diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1a7db3f23a..0b990bee24 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,11 +47,11 @@ jobs: # - name: Setup upterm session # uses: lhotari/action-upterm@v1 - - name: Check schema - run: | - GOPROXY=direct GOSUMDB=off GOBIN=/usr/local/bin go install go.bytebuilders.dev/uibuilder-tools@latest - uibuilder-tools check --wizard-dir=./charts \ - --skip-files=charts/corekubestashcom-backupconfiguration-editor-options/ui/create-ui.yaml + # - name: Check schema + # run: | + # GOPROXY=direct GOSUMDB=off GOBIN=/usr/local/bin go install go.bytebuilders.dev/uibuilder-tools@latest + # uibuilder-tools check --wizard-dir=./charts \ + # --skip-files=charts/corekubestashcom-backupconfiguration-editor-options/ui/create-ui.yaml - name: Run checks run: | diff --git a/charts/corekubestashcom-backupconfiguration-editor-options/templates/backupconfiguration.yaml b/charts/corekubestashcom-backupconfiguration-editor-options/templates/backupconfiguration.yaml index 7728def5d6..46ef4a8ed2 100644 --- a/charts/corekubestashcom-backupconfiguration-editor-options/templates/backupconfiguration.yaml +++ b/charts/corekubestashcom-backupconfiguration-editor-options/templates/backupconfiguration.yaml @@ -45,6 +45,6 @@ spec: jobTemplate: spec: securityContext: - runAsUser: {{ .addon.jobTemplate.securityContext }} + runAsUser: {{ .addon.jobTemplate.securityContext | int64 }} {{- end }} {{- end }} diff --git a/charts/corekubestashcom-backupconfiguration-editor-options/ui/create-ui.yaml b/charts/corekubestashcom-backupconfiguration-editor-options/ui/create-ui.yaml index a164d2978d..91db2819d9 100644 --- a/charts/corekubestashcom-backupconfiguration-editor-options/ui/create-ui.yaml +++ b/charts/corekubestashcom-backupconfiguration-editor-options/ui/create-ui.yaml @@ -1,237 +1,125 @@ -steps: -- form: - discriminator: - nameSpaceApi: - default: false - type: boolean +step: +- type: single-step-form + loader: initBundle + elements: + - loader: getNamespaces + label: Namespace + schema: schema/properties/metadata/properties/release/properties/namespace + type: select + - label: Name + schema: schema/properties/metadata/properties/release/properties/name + type: input + - loader: getData|storageRef + label: Storage Ref + schema: schema/properties/spec/properties/backend/properties/storageRef + type: select + - loader: getData|retentionPolicy + label: Retention Policy + schema: schema/properties/spec/properties/backend/properties/retentionPolicy + type: select + - elements: + - type: object-item + label: Labels + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + schema: schema/properties/spec/properties/annotations + label: Labels & Annotations + showLabels: true + hideBlock: true + type: block-layout + - label: Sessions elements: - - computed: init - if: returnFalse - type: label-element - - fetch: getNamespaces - label: - text: Namespace - schema: - $ref: schema#/properties/metadata/properties/release/properties/namespace + - type: input + label: Session Name + schema: sessionName + - type: input + label: Schedule + schema: schedule + - type: input + label: Security Context (runAsUser) + schema: addon/properties/jobTemplate/properties/securityContext + - type: select + label: Addon Name + loader: getAddon + schema: addon/properties/name + - type: array-object-form + label: Tasks + validation: + type: required + elements: + - type: select + label: Task Name + loader: + name: getTaskNames + watchPaths: + - schema/properties/spec/properties/sessions/dynamicIndex/properties/addon/properties/name + schema: name + validation: + type: required + - type: editor + label: Params + schema: params + schema: addon/properties/tasks + - type: select + customClass: mt-4 + label: Encryption Secret Namespace + loader: getNamespaces + schema: encryptionSecret/properties/namespace + - type: select + label: Encryption Secret Name + loader: + watchPaths: + - schema/properties/spec/properties/sessions/dynamicIndex/properties/encryptionSecret/properties/namespace + name: getEncryptionSecretNames + schema: encryptionSecret/properties/name + - type: input + label: Repo Name + schema: repoName + schema: schema/properties/spec/properties/sessions + type: array-object-form + - elements: + - loader: getApiGroup + label: Api Group + validation: + type: required + schema: schema/properties/spec/properties/target/properties/apiGroup type: select - - label: - text: Name - schema: - $ref: schema#/properties/metadata/properties/release/properties/name - type: input - - fetch: getData|storageRef - label: - text: Storage Ref - schema: - $ref: schema#/properties/spec/properties/backend/properties/storageRef + - loader: + name: getKinds + watchPaths: + - schema/properties/spec/properties/target/properties/apiGroup + label: Kind + watcher: + func: setVersion + paths: + - schema/properties/spec/properties/target/properties/kind + validation: + type: required + schema: schema/properties/spec/properties/target/properties/kind type: select - - fetch: getData|retentionPolicy - label: - text: Retention Policy - schema: - $ref: schema#/properties/spec/properties/backend/properties/retentionPolicy + - loader: getNamespaces + label: Namespace + validation: + type: required + schema: schema/properties/spec/properties/target/properties/namespace type: select - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties - type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties - type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - elements: - - addFormLabel: Session - element: - elements: - - label: - text: Session Name - required: true - schema: - $ref: schema#/items/properties/sessionName - type: input - - label: - text: Schedule - required: true - schema: - $ref: schema#/items/properties/schedule - type: input - - elements: - - inputType: number - label: - text: Security Context - schema: - $ref: schema#/properties/jobTemplate/properties/securityContext - type: input - - fetch: getAddon - label: - text: Name - onChange: clearTasks - required: true - schema: - $ref: schema#/items/properties/addon/properties/name - type: select - - addFormLabel: Task - element: - elements: - - fetch: getTaskNames - label: - text: Name - required: true - schema: - $ref: schema#/items/properties/name - type: select - - label: - text: Params - schema: - $ref: schema#/items/properties/params - type: editor - type: single-step-form - label: - text: Tasks - required: true - resetDependencyPath: /session/addon/name - resetOnChange: true - schema: - $ref: schema#/properties/tasks - tableContents: - - inTableColumn: true - label: - text: Name - path: name - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Params - path: params - type: value - typeOfValue: string - type: single-step-form-array - label: - text: Addon - schema: - $ref: schema#/items/properties/addon - show_label: true - type: single-step-form - - elements: - - fetch: getNamespaces - label: - text: Namespace - required: true - schema: - $ref: schema#/properties/namespace - type: select - - fetch: getEncryptionSecretNames - label: - text: Name - required: true - schema: - $ref: schema#/items/properties/encryptionSecret/properties/name - type: select - label: - text: Encryption Secret - schema: - $ref: schema#/items/properties/encryptionSecret - show_label: true - type: single-step-form - - label: - text: Repo Name - required: true - schema: - $ref: schema#/items/properties/repoName - type: input - type: single-step-form - label: - text: Session - schema: - $ref: schema#/properties/spec/properties/sessions - tableContents: - - inTableColumn: true - label: - text: Repo Name - path: repoName - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Schedule - path: schedule - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Session Name - path: sessionName - type: value - typeOfValue: string - temporaryPath: /session - type: single-step-form-array - type: single-step-form - - elements: - - fetch: getApiGroup - label: - text: Api Group - required: true - schema: - $ref: schema#/properties/spec/properties/target/properties/apiGroup - type: select - - fetch: getKinds - label: - text: Kind - onChange: setVersion - required: true - schema: - $ref: schema#/properties/spec/properties/target/properties/kind - type: select - - fetch: getNamespaces - label: - text: Namespace - required: true - schema: - $ref: schema#/properties/spec/properties/target/properties/namespace - type: select - - fetch: getTargetName - label: - text: Name - required: true - schema: - $ref: schema#/properties/spec/properties/target/properties/name - type: select - hideForm: true - if: showTarget - label: - text: Target - show_label: true - type: single-step-form - type: single-step-form + - loader: + name: getTargetName + watchPaths: + - schema/properties/spec/properties/target/properties/namespace + - schema/properties/spec/properties/target/properties/kind + label: Name + refresh: true + validation: + type: required + schema: schema/properties/spec/properties/target/properties/name + type: select + if: + type: function + name: showTarget + label: Target + showLabels: true + type: block-layout id: options - title: steps.0.label type: multi-step-form diff --git a/charts/corekubestashcom-backupconfiguration-editor-options/ui/functions.js b/charts/corekubestashcom-backupconfiguration-editor-options/ui/functions.js index 4e6f9975e8..e337e3782d 100644 --- a/charts/corekubestashcom-backupconfiguration-editor-options/ui/functions.js +++ b/charts/corekubestashcom-backupconfiguration-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + let namespaces = [] let appKind = [] let coreKind = [] @@ -6,314 +8,326 @@ let availableKinds = {} let kindToResourceMap = {} let version = '' -function init({ watchDependency, model, getValue, storeGet, axios, setDiscriminatorValue }) { - namespaces = getNamespacesApi({ axios, storeGet, setDiscriminatorValue }) - getKindsApi({ watchDependency, model, getValue, storeGet, axios }) - setDiscriminatorValue('/nameSpaceApi', true) -} +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) + + setDiscriminatorValue('/nameSpaceApi', false) -async function getNamespacesApi({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], + async function initBundle() { + namespaces = await getNamespacesApi() + await getKindsApi() + setDiscriminatorValue('/nameSpaceApi', true) + } + + async function getNamespacesApi() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, }, - }, - ) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] + ) + if (resp.data?.status?.projects) { + const projects = resp.data?.status?.projects + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } + } catch (e) { + console.log(e) } - } catch (e) { - console.log(e) + return [] } - return [] -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} - -function getNamespaces({ watchDependency }) { - watchDependency('discriminator#/nameSpaceApi') - return namespaces -} + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } -async function getAddon({ storeGet, axios }) { - const params = storeGet('/route/params') - const { user, cluster } = params - let url = `/clusters/${user}/${cluster}/proxy/addons.kubestash.com/v1alpha1/addons` - try { - const resp = await axios.get(url) - let addons = [] - resp.data?.items.forEach((item) => { - addons.push(item.metadata.name) - }) - return addons - } catch (e) { - console.log(e) + function getNamespaces() { + // watchDependency('discriminator#/nameSpaceApi') + return namespaces } - return [] -} -async function getTaskNames({ watchDependency, storeGet, axios }) { - watchDependency('temporaryModel#/session/addon/name') - const addon = storeGet('/wizard/temporaryModel/session/addon/name') - const params = storeGet('/route/params') - const { user, cluster } = params - let url = `/clusters/${user}/${cluster}/proxy/addons.kubestash.com/v1alpha1/addons/${addon}` - if (addon) { + async function getAddon() { + const params = storeGet('/route/params') + + const { user, cluster } = params + let url = `/clusters/${user}/${cluster}/proxy/addons.kubestash.com/v1alpha1/addons` try { const resp = await axios.get(url) - - const backupTasks = resp?.data?.spec?.backupTasks?.map((task) => task.name) || [] - return backupTasks + let addons = [] + resp.data?.items.forEach((item) => { + addons.push(item.metadata.name) + }) + return addons } catch (e) { console.log(e) } + return [] } - return [] -} -function clearTasks({ commit }) { - commit('wizard/temporaryModel$update', { - path: '/session/addon/tasks', - value: [], - force: true, - }) -} + async function getTaskNames(index) { + // watchDependency('temporaryModel#/session/addon/name') + const session = getValue(model, `/spec/sessions`) + const addon = session[index]?.addon?.name + + const params = storeGet('/route/params') + const { user, cluster } = params + let url = `/clusters/${user}/${cluster}/proxy/addons.kubestash.com/v1alpha1/addons/${addon}` + if (addon) { + try { + const resp = await axios.get(url) + + const backupTasks = resp?.data?.spec?.backupTasks?.map((task) => task.name) || [] + return backupTasks + } catch (e) { + console.log(e) + } + } + return [] + } + + function clearTasks() { + commit('wizard/temporaryModel$update', { + path: '/session/addon/tasks', + value: [], + force: true, + }) + } -async function getEncryptionSecretNames({ watchDependency, storeGet, axios }) { - watchDependency('temporaryModel#/session/encryptionSecret/namespace') - const namespace = storeGet('/wizard/temporaryModel/session/encryptionSecret/namespace') - const params = storeGet('/route/params') - const { user, cluster } = params - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - if (namespace) { + async function getEncryptionSecretNames(index) { + // watchDependency('temporaryModel#/session/encryptionSecret/namespace') + const session = getValue(model, `/spec/sessions`) + const namespace = session[index]?.encryptionSecret?.namespace + const params = storeGet('/route/params') + const { user, cluster } = params + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` + if (namespace) { + try { + const resp = await axios.get(url) + const name = resp?.data?.items?.map((item) => item.metadata?.name) || [] + return name + } catch (e) { + console.log(e) + } + } + return [] + } + + async function getKindsApi() { + const params = storeGet('/route/params') + const { user, cluster } = params + let url = `/clusters/${user}/${cluster}/available-types?groups=core,apps,kubedb.com` try { const resp = await axios.get(url) - const name = resp?.data?.items?.map((item) => item.metadata?.name) || [] - return name + + kindToResourceMap['kubedb.com'] = {} + kindToResourceMap['apps'] = {} + kindToResourceMap['core'] = {} + + availableKinds = resp.data + appKind = Object.values(availableKinds['apps']) + .flat() + .map((ele) => { + kindToResourceMap['apps'][ele.Kind] = ele.Resource + return ele.Kind + }) + kubedbKind = Object.values(availableKinds['kubedb.com']) + .flat() + .map((ele) => { + kindToResourceMap['kubedb.com'][ele.Kind] = ele.Resource + return ele.Kind + }) + coreKind = Object.values(availableKinds['']) + .flat() + .map((ele) => { + kindToResourceMap['core'][ele.Kind] = ele.Resource + return ele.Kind + }) } catch (e) { console.log(e) } + return [] } - return [] -} -async function getKindsApi({ storeGet, axios }) { - const params = storeGet('/route/params') - const { user, cluster } = params - let url = `/clusters/${user}/${cluster}/available-types?groups=core,apps,kubedb.com` - try { - const resp = await axios.get(url) - - kindToResourceMap['kubedb.com'] = {} - kindToResourceMap['apps'] = {} - kindToResourceMap['core'] = {} - - availableKinds = resp.data - appKind = Object.values(availableKinds['apps']) - .flat() - .map((ele) => { - kindToResourceMap['apps'][ele.Kind] = ele.Resource - return ele.Kind - }) - kubedbKind = Object.values(availableKinds['kubedb.com']) - .flat() - .map((ele) => { - kindToResourceMap['kubedb.com'][ele.Kind] = ele.Resource - return ele.Kind - }) - coreKind = Object.values(availableKinds['']) - .flat() - .map((ele) => { - kindToResourceMap['core'][ele.Kind] = ele.Resource - return ele.Kind + function getKinds() { + // watchDependency(`model#/spec/target/apiGroup`) + const apiGroup = getValue(model, `/spec/target/apiGroup`) + + if (apiGroup === 'core') return coreKind + else if (apiGroup === 'apps') return appKind + else return kubedbKind + } + + function setVersion() { + let apiGroup = getValue(model, `/spec/target/apiGroup`) + const kind = getValue(model, `/spec/target/kind`) + if (apiGroup === 'core') apiGroup = '' + Object.keys(availableKinds[apiGroup]).forEach((vs) => { + availableKinds[apiGroup][vs].forEach((ele) => { + if (ele.Kind === kind) { + version = vs + } }) - } catch (e) { - console.log(e) + }) } - return [] -} -function getKinds({ watchDependency, getValue, model }) { - watchDependency(`model#/spec/target/apiGroup`) - const apiGroup = getValue(model, `/spec/target/apiGroup`) + function getApiGroup() { + return ['core', 'apps', 'kubedb.com'] + } - if (apiGroup === 'core') return coreKind - else if (apiGroup === 'apps') return appKind - else return kubedbKind -} + async function getTargetName() { + // watchDependency('model#/spec/target/apiGroup') + // watchDependency('model#/spec/target/namespace') + // watchDependency('model#/spec/target/kind') + const apiGroup = getValue(model, `/spec/target/apiGroup`) + const namespace = getValue(model, `/spec/target/namespace`) + const resource = getResourceName() + const params = storeGet('/route/params') + const { user, cluster } = params -function setVersion({ getValue, model }) { - const apiGroup = getValue(model, `/spec/target/apiGroup`) - const kind = getValue(model, `/spec/target/kind`) - if (apiGroup === 'core') apiGroup = '' - Object.keys(availableKinds[apiGroup]).forEach((vs) => { - availableKinds[apiGroup][vs].forEach((ele) => { - if (ele.Kind === kind) { - version = vs + const url = `/clusters/${user}/${cluster}/proxy/${apiGroup}/${version}/namespaces/${namespace}/${resource}` + if (apiGroup && version && resource && namespace) { + try { + const resp = await axios.get(url) + const items = resp.data?.items + const options = items.map((ele) => { + return ele.metadata.name + }) + return options + } catch (e) { + console.log(e) } - }) - }) -} + } + return [] + } -function getApiGroup() { - return ['core', 'apps', 'kubedb.com'] -} + function getResourceName() { + const apiGroup = getValue(model, `/spec/target/apiGroup`) + const kind = getValue(model, `/spec/target/kind`) + if (!kind || !apiGroup) return '' + return kindToResourceMap[apiGroup][kind] + } + + async function fetchJsons() { + let ui = {} + let language = {} + let functions = {} + const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart -async function getTargetName({ watchDependency, getValue, model, axios, storeGet }) { - watchDependency('model#/spec/target/apiGroup') - watchDependency('model#/spec/target/namespace') - watchDependency('model#/spec/target/kind') - const apiGroup = getValue(model, `/spec/target/apiGroup`) - const namespace = getValue(model, `/spec/target/namespace`) - const resource = getResourceName({ getValue, model }) - const params = storeGet('/route/params') - const { user, cluster } = params - - const url = `/clusters/${user}/${cluster}/proxy/${apiGroup}/${version}/namespaces/${namespace}/${resource}` - if (apiGroup && version && resource && namespace) { try { - const resp = await axios.get(url) - const items = resp.data?.items - const options = items.map((ele) => { - return ele.metadata.name - }) - return options + 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 [] -} -function getResourceName({ getValue, model }) { - const apiGroup = getValue(model, `/spec/target/apiGroup`) - const kind = getValue(model, `/spec/target/kind`) - if (!kind || !apiGroup) return '' - return kindToResourceMap[apiGroup][kind] -} - -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, + } } - return { - ui: ui.data || {}, - language: language.data || {}, - functions, + async function getData(ctx, type) { + const user = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + let url = `/clusters/${user}/${cluster}/proxy/storage.kubestash.com/v1alpha1/${ + type === 'retentionPolicy' ? 'retentionpolicies' : 'backupstorages' + }` + try { + const data = await axios.get(url) + const items = data.data?.items || [] + const options = items.map((item) => { + return { + text: `${item.metadata.namespace}/${item.metadata.name}`, + value: { name: item.metadata.name, namespace: item.metadata.namespace }, + } + }) + return options || [] + } catch (e) { + console.log(e) + return [] + } } -} -async function getData({ axios, route }, type) { - const user = route.params.user - const cluster = route.params.cluster - url = `/clusters/${user}/${cluster}/proxy/storage.kubestash.com/v1alpha1/${ - type === 'retentionPolicy' ? 'retentionpolicies' : 'backupstorages' - }` - try { - const data = await axios.get(url) - const items = data.data?.items || [] - const options = items.map((item) => { - return { - text: `${item.metadata.namespace}/${item.metadata.name}`, - value: { name: item.metadata.name, namespace: item.metadata.namespace }, - } - }) - return options || [] - } catch (e) { - console.log(e) - return [] - } -} + function showTarget() { + const params = storeGet('/route/params') || {} + const { group, name } = params + const namespace = storeGet('/route/query/namespace') || '' + const kind = storeGet('/resource/layout/result/resource/kind') || '' -function showTarget({ route, commit, storeGet }) { - const params = route.params || {} - const { group, name } = params - const query = route.query || {} - const namespace = query.namespace || '' - const kind = storeGet('/resource/layout/result/resource/kind') || '' - - if (group === 'kubedb.com') { - const target = { - apiGroup: 'kubedb.com', - kind: kind, - namespace: namespace, - name: name, + if (group === 'kubedb.com') { + const target = { + apiGroup: 'kubedb.com', + kind: kind, + namespace: namespace, + name: name, + } + commit('wizard/model$update', { + path: '/spec/target', + value: target, + force: true, + }) } - commit('wizard/model$update', { - path: '/spec/target', - value: target, - force: true, - }) + return group !== 'kubedb.com' } - return group !== 'kubedb.com' -} -function returnFalse() { - return false -} + function returnFalse() { + return false + } -return { - isRancherManaged, - setVersion, - getTargetName, - getApiGroup, - getEncryptionSecretNames, - getKinds, - getTaskNames, - getAddon, - init, - returnFalse, - fetchJsons, - getNamespaces, - clearTasks, - showTarget, - getData, + return { + clearTasks, + fetchJsons, + getAddon, + getApiGroup, + getData, + getEncryptionSecretNames, + getKinds, + getNamespaces, + getTargetName, + getTaskNames, + initBundle, + isRancherManaged, + returnFalse, + setVersion, + showTarget, + } } diff --git a/charts/corekubestashcom-backupconfiguration-editor-options/values.yaml b/charts/corekubestashcom-backupconfiguration-editor-options/values.yaml index ca94a43d15..6d57521a15 100644 --- a/charts/corekubestashcom-backupconfiguration-editor-options/values.yaml +++ b/charts/corekubestashcom-backupconfiguration-editor-options/values.yaml @@ -30,6 +30,8 @@ spec: name: "" namespace: "" + sessions: [] + target: apiGroup: "kubedb.com" kind: "" diff --git a/charts/corekubestashcom-backupsession-editor-options/ui/create-ui.yaml b/charts/corekubestashcom-backupsession-editor-options/ui/create-ui.yaml index 59cb60832e..4327a0986d 100644 --- a/charts/corekubestashcom-backupsession-editor-options/ui/create-ui.yaml +++ b/charts/corekubestashcom-backupsession-editor-options/ui/create-ui.yaml @@ -1,88 +1,70 @@ -steps: -- form: +step: +- type: single-step-form + elements: + - loader: fetchNamespaces + hasGroup: isRancherManaged + label: Namespace + schema: schema/properties/metadata/properties/release/properties/namespace + type: select + - type: block-layout + label: Labels & Annotations + showLabels: true + hideBlock: true elements: - - fetch: fetchNamespaces - hasGroup: isRancherManaged - label: - text: labels.namespace - schema: - $ref: schema#/properties/metadata/properties/release/properties/namespace - type: select - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties - type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties - type: input - - label: - text: Invoker Kind - options: - - text: Backup Configurations - value: BackupConfiguration - - text: Backup Blueprints - value: BackupBlueprint - schema: - $ref: schema#/properties/spec/properties/invoker/properties/kind - type: select - - fetch: fetchInvokerName - label: - text: Invoker Name - onChange: initName - schema: - $ref: schema#/properties/spec/properties/invoker/properties/name - type: select - - fetch: fetchSessions - label: - text: Session - onChange: initName - schema: - $ref: schema#/properties/spec/properties/session - type: select - - label: - text: labels.timeout - options: - - text: 5 minutes - value: 5m - - text: 10 minutes - value: 10m - - text: 30 minutes - value: 30m - - text: 1 hour - value: 1h - - text: 2 hours - value: 2h - - text: 5 hours - value: 5h - - text: 10 hours - value: 10h - schema: - $ref: schema#/properties/spec/properties/backupTimeout - type: select - type: single-step-form + - type: object-item + label: Labels + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + schema: schema/properties/spec/properties/annotations + - label: Invoker Kind + options: + - text: Backup Configurations + value: BackupConfiguration + - text: Backup Blueprints + value: BackupBlueprint + schema: schema/properties/spec/properties/invoker/properties/kind + type: select + - loader: + name: fetchInvokerName + watchPaths: + - schema/properties/spec/properties/invoker/properties/kind + - schema/properties/metadata/properties/release/properties/namespace + label: Invoker Name + watcher: + func: initName + paths: + - schema/properties/spec/properties/invoker/properties/name + schema: schema/properties/spec/properties/invoker/properties/name + type: select + - loader: + name: fetchSessions + watchPaths: + - schema/properties/spec/properties/invoker/properties/name + label: Session + watcher: + func: initName + paths: + - schema/properties/spec/properties/session + schema: schema/properties/spec/properties/session + type: select + - label: Timeout + options: + - text: 5 minutes + value: 5m + - text: 10 minutes + value: 10m + - text: 30 minutes + value: 30m + - text: 1 hour + value: 1h + - text: 2 hours + value: 2h + - text: 5 hours + value: 5h + - text: 10 hours + value: 10h + schema: schema/properties/spec/properties/backupTimeout + type: select id: options - title: steps.0.label type: multi-step-form diff --git a/charts/corekubestashcom-backupsession-editor-options/ui/functions.js b/charts/corekubestashcom-backupsession-editor-options/ui/functions.js index 97487a939c..7ee27d1853 100644 --- a/charts/corekubestashcom-backupsession-editor-options/ui/functions.js +++ b/charts/corekubestashcom-backupsession-editor-options/ui/functions.js @@ -1,112 +1,127 @@ -let invokerData = [] +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} -function initName({ model, getValue, commit }) { - const invoker = getValue(model, '/spec/invoker/name') || '' - const session = getValue(model, '/spec/session') || '' - let name = '' - if (invoker && session) name = `${invoker}-${session}-${Date.now()}` - else name = '' - commit('wizard/model$update', { - path: '/metadata/release/name', - value: name, - force: true, - }) +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) - const found = invokerData.find((item) => item.metadata.name === invoker) - const uid = found ? found.metadata?.uid : '' - commit('wizard/model$update', { - path: '/spec/ownerUID', - value: uid, - force: true, - }) -} + let invokerData = [] + + function initName() { + const invoker = getValue(model, '/spec/invoker/name') || '' + const session = getValue(model, '/spec/session') || '' + let name = '' + if (invoker && session) name = `${invoker}-${session}-${Date.now()}` + else name = '' + commit('wizard/model$update', { + path: '/metadata/release/name', + value: name, + force: true, + }) + + const found = invokerData.find((item) => item.metadata.name === invoker) + const uid = found ? found.metadata?.uid : '' + commit('wizard/model$update', { + path: '/spec/ownerUID', + value: uid, + force: true, + }) + } -async function fetchNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], + async function fetchNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, }, - }, - ) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] + ) + if (resp.data?.status?.projects) { + const projects = resp.data?.status?.projects + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } + } catch (e) { + console.log(e) } - } catch (e) { - console.log(e) + return [] } - return [] -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } -async function fetchInvokerName({ getValue, model, watchDependency, axios, storeGet }) { - watchDependency('model#/spec/invoker/kind') - watchDependency('model#/metadata/release/namespace') - const namespace = getValue(model, '/metadata/release/namespace') || '' - const kind = getValue(model, '/spec/invoker/kind') || '' - const user = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - const core = 'core.kubestash.com' - const version = 'v1alpha1' - const suffix = kind === 'BackupConfiguration' ? 'backupconfigurations' : 'backupblueprints' - try { - if (namespace && kind) { - const url = `/clusters/${user}/${cluster}/proxy/${core}/${version}/namespaces/${namespace}/${suffix}` - const resp = await axios.get(url) - invokerData = resp.data.items - const names = resp.data.items.map((item) => { - const name = item.metadata?.name - return name - }) - return names + async function fetchInvokerName() { + // watchDependency('model#/spec/invoker/kind') + // watchDependency('model#/metadata/release/namespace') + const namespace = getValue(model, '/metadata/release/namespace') || '' + const kind = getValue(model, '/spec/invoker/kind') || '' + const user = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + const core = 'core.kubestash.com' + const version = 'v1alpha1' + const suffix = kind === 'BackupConfiguration' ? 'backupconfigurations' : 'backupblueprints' + try { + if (namespace && kind) { + const url = `/clusters/${user}/${cluster}/proxy/${core}/${version}/namespaces/${namespace}/${suffix}` + const resp = await axios.get(url) + invokerData = resp.data.items + + const dbKind = storeGet('/resource/layout/result/resource/kind') || '' + const group = storeGet('/resource/layout/result/resource/group') || '' + if (group === 'kubedb.com') + invokerData = invokerData.filter((item) => item.spec?.target?.kind === dbKind) + + const names = invokerData.map((item) => { + const name = item.metadata?.name + return name + }) + return names + } + } catch (e) { + console.log(e) } - } catch (e) { - console.log(e) + return [] } - return [] -} -function fetchSessions({ getValue, model, watchDependency }) { - watchDependency('model#/spec/invoker/name') - const invokerName = getValue(model, '/spec/invoker/name') || '' - const found = invokerData.find((item) => item.metadata.name === invokerName) - if (found) return found.spec?.sessions.map((item) => item.name) - return [] -} + function fetchSessions() { + // watchDependency('model#/spec/invoker/name') + const invokerName = getValue(model, '/spec/invoker/name') || '' + const found = invokerData.find((item) => item.metadata.name === invokerName) + if (found) return found.spec?.sessions.map((item) => item.name) + return [] + } -return { - isRancherManaged, - initName, - fetchNamespaces, - fetchInvokerName, - fetchSessions, + return { + isRancherManaged, + initName, + fetchNamespaces, + fetchInvokerName, + fetchSessions, + } } diff --git a/charts/corekubestashcom-backupsession-editor/ui/create-ui.yaml b/charts/corekubestashcom-backupsession-editor/ui/create-ui.yaml index 15217e6c70..59d5bdb05c 100644 --- a/charts/corekubestashcom-backupsession-editor/ui/create-ui.yaml +++ b/charts/corekubestashcom-backupsession-editor/ui/create-ui.yaml @@ -1,36 +1,40 @@ -steps: -- form: - discriminator: - backup: - type: string - initApi: - default: false - type: boolean - selectedSessions: - type: Array - elements: - - computed: init - if: returnFalse - type: label-element - - fetch: getOptions - if: isApiResolved - label: - text: Select Backup - onChange: clearModel - required: true - schema: - $ref: discriminator#/backup - type: select - - fetch: getSessionOptions - if: isBackupSelected - label: - text: Select Sessions - onChange: buildCommand - required: true - schema: - $ref: discriminator#/selectedSessions - type: multiselect - type: single-step-form - id: basic - title: steps.0.label type: multi-step-form +step: + - type: single-step-form + id: basic + # label: Basic Information + elements: + - type: label-element + label: '' + subtitle: Select a backup configuration and choose which backup sessions to view or manage + - type: select + label: Backup Configuration + subtitle: Select the backup configuration that contains the sessions you want to view + schema: temp/properties/backup + validation: + type: required + refresh: true + loader: getOptions + watcher: + func: clearModel + paths: + - temp/properties/backup + - type: select + multiple: true + label: Backup Sessions + subtitle: Select one or more backup sessions to view their details and status + schema: temp/properties/selectedSessions + refresh: true + validation: + type: required + if: + type: function + name: isBackupSelected + loader: + name: getSessionOptions + watchPaths: + - temp/properties/backup + watcher: + func: buildCommand + paths: + - temp/properties/selectedSessions diff --git a/charts/corekubestashcom-backupsession-editor/ui/functions.js b/charts/corekubestashcom-backupsession-editor/ui/functions.js index a65d7c4659..b34b3ebfa4 100644 --- a/charts/corekubestashcom-backupsession-editor/ui/functions.js +++ b/charts/corekubestashcom-backupsession-editor/ui/functions.js @@ -1,97 +1,107 @@ -let options = [] -let backups = [] -let backupName = '' -let backupNamespace = '' - -async function init({ storeGet, axios, setDiscriminatorValue, commit }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = storeGet('/route/query/namespace') - const name = storeGet('/route/params/name') - const url = `/clusters/${owner}/${cluster}/proxy/core.kubestash.com/v1alpha1/namespaces/${namespace}/backupconfigurations` - - try { - const resp = await axios.get(url) - const items = resp.data.items - - backups = items - items.forEach((ele) => { - if (ele.spec?.target?.name === name && ele.spec?.target?.namespace === namespace) { - const tx = `${ele.metadata.namespace}/${ele.metadata.name}` - options.push({ text: tx, value: ele.metadata.name }) +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) + + /********** Initialize Discriminator **************/ + + setDiscriminatorValue('backup', '') + setDiscriminatorValue('initApi', false) + setDiscriminatorValue('selectedSessions', []) + + let options = [] + let backups = [] + let backupName = '' + let backupNamespace = '' + + // **************** common functions **************** + + async function getOptions() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = storeGet('/route/query/namespace') + const name = storeGet('/route/params/name') + const url = `/clusters/${owner}/${cluster}/proxy/core.kubestash.com/v1alpha1/namespaces/${namespace}/backupconfigurations` + + try { + const resp = await axios.get(url) + const items = resp.data.items + + backups = items + items.forEach((ele) => { + if (ele.spec?.target?.name === name && ele.spec?.target?.namespace === namespace) { + const tx = `${ele.metadata.namespace}/${ele.metadata.name}` + options.push({ text: tx, value: ele.metadata.name }) + } + }) + return options + } catch (e) { + console.log(e) + } + setDiscriminatorValue('/initApi', true) + } + + function getSessionOptions() { + const backup = getValue(discriminator, '/backup') + let sessions = [] + backups?.forEach((ele) => { + if (ele.metadata.name === backup) { + backupName = ele.metadata.name + backupNamespace = ele.metadata.namespace + sessions = ele.spec.sessions } }) - } catch (e) { - console.log(e) + const optionsArray = sessions?.map((ele) => ele.name) + return optionsArray } - setDiscriminatorValue('/initApi', true) -} -function getOptions() { - return options -} - -function getSessionOptions({ getValue, discriminator, watchDependency }) { - watchDependency('discriminator#/backup') - const backup = getValue(discriminator, '/backup') - let sessions = [] - backups?.forEach((ele) => { - if (ele.metadata.name === backup) { - backupName = ele.metadata.name - backupNamespace = ele.metadata.namespace - sessions = ele.spec.sessions - } - }) - const optionsArray = sessions?.map((ele) => ele.name) - return optionsArray -} + function returnFalse() { + return false + } -function returnFalse() { - return false -} + function isApiResolved() { + const initApi = getValue(discriminator, '/initApi') + return initApi + } -function isApiResolved({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/initApi') - const initApi = getValue(discriminator, '/initApi') - return initApi -} + function isBackupSelected() { + const backup = getValue(discriminator, '/backup') + return backup + } -function isBackupSelected({ getValue, discriminator, watchDependency }) { - watchDependency('discriminator#/backup') - const backup = getValue(discriminator, '/backup') - return backup -} + function buildCommand() { + const sessions = getValue(discriminator, '/selectedSessions') + let generatedCommand = `trigger ${backupName} -n ${backupNamespace}` + sessions?.forEach((ele) => { + generatedCommand += ` --sessions ${ele}` + }) -function buildCommand({ getValue, discriminator, commit }) { - const sessions = getValue(discriminator, '/selectedSessions') - let generatedCommand = `kubectl-kubestash trigger ${backupName} -n ${backupNamespace}` - sessions?.forEach((ele) => { - generatedCommand += ` --sessions ${ele}` - }) - - commit('wizard/model$update', { - path: '/resources/coreKubestashComBackupSession/', - value: generatedCommand, - force: true, - }) -} + commit('wizard/model$update', { + path: '/resources/coreKubestashComBackupSession/', + value: generatedCommand, + force: true, + }) + } -function clearModel({ commit, setDiscriminatorValue }) { - commit('wizard/model$update', { - path: '/resources/coreKubestashComBackupSession/', - value: '', - force: true, - }) - setDiscriminatorValue('/selectedSessions', []) -} + function clearModel() { + commit('wizard/model$update', { + path: '/resources/coreKubestashComBackupSession/', + value: '', + force: true, + }) + setDiscriminatorValue('/selectedSessions', []) + } -return { - clearModel, - getSessionOptions, - isBackupSelected, - buildCommand, - isApiResolved, - getOptions, - init, - returnFalse, + return { + clearModel, + getSessionOptions, + isBackupSelected, + buildCommand, + isApiResolved, + getOptions, + returnFalse, + } } diff --git a/charts/corekubestashcom-restoresession-editor-options/ui/create-ui.yaml b/charts/corekubestashcom-restoresession-editor-options/ui/create-ui.yaml index 8daa59492d..a2b08d5b31 100644 --- a/charts/corekubestashcom-restoresession-editor-options/ui/create-ui.yaml +++ b/charts/corekubestashcom-restoresession-editor-options/ui/create-ui.yaml @@ -1,125 +1,137 @@ -steps: -- form: - elements: - - discriminator: - database: - default: {} - type: object - nameSpaceApi: - default: false - type: boolean +type: multi-step-form +step: +- type: single-step-form + id: options + loader: init + elements: + - type: select + label: Select Namespace + schema: schema/properties/metadata/properties/release/properties/namespace + hasGroup: isRancherManaged + if: + type: function + name: isConsole + loader: + name: fetchNamespaces + watchPaths: + - temp/properties/nameSpaceApi + - type: input + label: Name + schema: schema/properties/metadata/properties/release/properties/name + if: + type: function + name: isConsole + - type: block-layout + showLabels: true + fixedBlock: true + label: Restore Configuration + loader: initMetadata + elements: + - type: label-element + label: '' + subtitle: Configure the backup repository and snapshot to restore your data from + - type: select + label: Repository + subtitle: Select the repository where your backup snapshots are stored + disableUnselect: true + schema: temp/properties/repository + refresh: true + validation: + type: required + loader: getRepositories + watcher: + func: onRepoChange + paths: + - temp/properties/repository + - type: select + disableUnselect: true + label: Snapshot + subtitle: Choose a point-in-time backup snapshot to restore from + refresh: true + schema: schema/properties/spec/properties/dataSource/properties/snapshot + loader: + name: getSnapshots + watchPaths: + - temp/properties/repository + watcher: + func: onSnapChange + paths: + - schema/properties/spec/properties/dataSource/properties/snapshot + - type: select + label: Addon Name + subtitle: Select the restore addon to use + refresh: true + schema: schema/properties/spec/properties/addon/properties/name + if: + type: function + name: isConsole + loader: + name: getAddons + watchPaths: + - schema/properties/spec/properties/dataSource/properties/snapshot + watcher: + func: clearAddon + paths: + - schema/properties/spec/properties/dataSource/properties/snapshot + - type: textarea + label: Additional Parameters + schema: temp/properties/params + watcher: + func: onParameterChange + paths: + - temp/properties/params + - type: block-layout + showLabels: true + label: Restore Target + if: + type: function + name: isConsole elements: - - fetch: fetchNamespaces + - type: label-element + label: Target Resource Configuration + subtitle: Specify the Kubernetes resource where you want to restore the data + - type: select + label: Api Group + subtitle: Select the API group of the target resource (e.g., apps, kubedb.com) + schema: schema/properties/spec/properties/target/properties/apiGroup + loader: getApiGroup + if: + name: showGroupKind + type: function + - type: select + label: Kind + subtitle: Select the resource type (e.g., Deployment, StatefulSet, MongoDB, PostgreSQL) + schema: schema/properties/spec/properties/target/properties/kind + loader: + name: getKinds + watchPaths: + - schema/properties/spec/properties/target/properties/apiGroup + - schema/properties/spec/properties/dataSource/properties/snapshot + watcher: + func: setVersion + paths: + - schema/properties/spec/properties/target/properties/kind + - schema/properties/spec/properties/target/properties/apiGroup + if: + name: showGroupKind + type: function + - type: select + label: Namespace + subtitle: Select the namespace where the target resource exists + schema: schema/properties/spec/properties/target/properties/namespace + loader: fetchNamespaces hasGroup: isRancherManaged - if: isConsole - label: - text: Select Namespace - schema: - $ref: schema#/properties/metadata/properties/release/properties/namespace - type: select - - computed: init - if: returnFalse - type: input - - if: isConsole - label: - text: labels.name - schema: - $ref: schema#/properties/metadata/properties/release/properties/name - type: input - - elements: - - computed: initMetadata - if: returnFalse - type: input - - discriminator: - repository: - type: object - elements: - - disableUnselect: true - fetch: getRepositories - label: - text: Repository - onChange: onRepoChange - refresh: true - required: true - schema: - $ref: discriminator#/properties/repository - type: select - - disableUnselect: true - fetch: getSnapshots - label: - text: labels.dataSource.snapshot - refresh: true - schema: - $ref: schema#/properties/spec/properties/dataSource/properties/snapshot - type: select - schema: - $ref: schema#/properties/spec/properties/dataSource - type: single-step-form - - discriminator: - params: - default: "" - type: string - elements: - - fetch: getAddons - if: isConsole - label: - text: labels.name - refresh: true - schema: - $ref: schema#/properties/spec/properties/addon/properties/name - type: select - - label: - text: Additional Parameters - onChange: onParameterChange - schema: - $ref: discriminator#/properties/params - type: textarea - - computed: setSecurityContext - if: returnFalse - type: input - schema: - $ref: schema#/properties/spec/properties/addon - type: single-step-form - - elements: - - fetch: getApiGroup - label: - text: Api Group - schema: - $ref: schema#/properties/spec/properties/target/properties/apiGroup - type: select - - fetch: getKinds - label: - text: Kind - onChange: setVersion - schema: - $ref: schema#/properties/spec/properties/target/properties/kind - type: select - - fetch: fetchNamespaces - hasGroup: isRancherManaged - label: - text: Namespace - schema: - $ref: schema#/properties/spec/properties/target/properties/namespace - type: select - - fetch: getTargetName - label: - text: Name - schema: - $ref: schema#/properties/spec/properties/target/properties/name - type: select - hideForm: true - if: isConsole - label: - text: Target - schema: - $ref: schema#/properties/spec/properties/target - show_label: true - type: single-step-form - schema: - $ref: schema#/properties/spec - type: single-step-form - type: single-step-form - type: single-step-form - id: options - title: steps.0.label -type: multi-step-form + watcher: + func: fetchNamespaces + paths: + - temp/properties/nameSpaceApi + - type: select + label: Resource Name + subtitle: Select the specific resource to restore to + schema: schema/properties/spec/properties/target/properties/name + loader: + name: getTargetName + watchPaths: + - schema/properties/spec/properties/target/properties/apiGroup + - schema/properties/spec/properties/target/properties/namespace + - schema/properties/spec/properties/target/properties/kind diff --git a/charts/corekubestashcom-restoresession-editor-options/ui/functions.js b/charts/corekubestashcom-restoresession-editor-options/ui/functions.js index d668e31ed6..52850fce75 100644 --- a/charts/corekubestashcom-restoresession-editor-options/ui/functions.js +++ b/charts/corekubestashcom-restoresession-editor-options/ui/functions.js @@ -1,530 +1,597 @@ -let addonList = [] -function isConsole({ storeGet }) { - const group = storeGet('/route/params/group') || '' - return group !== 'kubedb.com' -} +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} -async function initMetadata({ storeGet, commit, axios }) { - const resource = storeGet('/resource') || {} - const { group, kind } = resource?.layout?.result?.resource - const name = storeGet('/route/params/name') || '' - const namespace = storeGet('route/query/namespace') || '' - if (!isConsole({ storeGet })) { - // set metadata name namespace - commit('wizard/model$update', { - path: '/metadata/release/name', - value: `${name}-${Math.floor(Date.now() / 1000)}-restore`, - force: true, - }) - commit('wizard/model$update', { - path: '/metadata/release/namespace', - value: namespace, - force: true, - }) +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) - const target = { - apiGroup: group, - kind: kind, - name: name, - namespace: namespace, - } - commit('wizard/model$update', { - path: '/spec/target', - value: target, - force: true, - }) + /********** Initialize Discriminator **************/ - // set addon name - commit('wizard/model$update', { - path: '/spec/addon/name', - value: `${kind.toLowerCase()}-addon`, - }) + setDiscriminatorValue('database', {}) + setDiscriminatorValue('nameSpaceApi', false) + setDiscriminatorValue('repository', '') + setDiscriminatorValue('params', '') + + let addonList = [] + function isConsole() { + const group = storeGet('/route/params/group') || '' + return group !== 'kubedb.com' } - // get encryptionSecret from stash-preset - await getPreset({ axios, storeGet, commit }) -} + async function initMetadata() { + const resource = storeGet('/resource') || {} + const { group, kind } = resource?.layout?.result?.resource + const name = storeGet('/route/params/name') || '' + const namespace = storeGet('route/query/namespace') || '' + if (!isConsole()) { + // set metadata name namespace + commit('wizard/model$update', { + path: '/metadata/release/name', + value: `${name}-${Math.floor(Date.now() / 1000)}-restore`, + force: true, + }) + commit('wizard/model$update', { + path: '/metadata/release/namespace', + value: namespace, + force: true, + }) -async function getPreset({ axios, storeGet, commit }) { - const user = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - const url = `/clusters/${user}/${cluster}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/stash-presets` - try { - const resp = await axios.get(url) - const encryptionSecret = resp?.data?.spec?.values?.spec?.backup?.kubestash?.encryptionSecret - commit('wizard/model$update', { - path: '/spec/dataSource/encryptionSecret', - value: encryptionSecret, - force: true, - }) - } catch (e) { - console.log(e) + const target = { + apiGroup: group, + kind: kind, + name: name, + namespace: namespace, + } + commit('wizard/model$update', { + path: '/spec/target', + value: target, + force: true, + }) + + // set addon name + commit('wizard/model$update', { + path: '/spec/addon/name', + value: `${kind.toLowerCase()}-addon`, + }) + } + + // get encryptionSecret from stash-preset + await getPreset() + setSecurityContext() } -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + async function getPreset() { + const user = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + const url = `/clusters/${user}/${cluster}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/stash-presets` + try { + const resp = await axios.get(url) + const encryptionSecret = resp?.data?.spec?.values?.spec?.backup?.kubestash?.encryptionSecret + commit('wizard/model$update', { + path: '/spec/dataSource/encryptionSecret', + value: encryptionSecret, + force: true, + }) + } catch (e) { + console.log(e) + } + } -async function fetchNamespacesApi({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } + + async function fetchNamespacesApi() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, }, - }, - ) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] + ) + if (resp.data?.status?.projects) { + const projects = resp.data?.status?.projects + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } + } catch (e) { + console.log(e) } - } catch (e) { - console.log(e) + return [] } - return [] -} -function setNamespace({ storeGet, model, getValue }) { - const namespaceFromModel = getValue(model, '/metadata/release/namespace') - const namespace = storeGet('/route/query/namespace') || namespaceFromModel || '' - return namespace -} - -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - watchDependency('model#/metadata/release/namespace') - const namespace = getValue(model, '/metadata/release/namespace') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/core.k8s.appscode.com/v1alpha1/namespaces/${namespace}/genericresources`, - { - params: { - convertToTable: true, - labelSelector: 'k8s.io/group=kubedb.com', - }, - }, - ) + function setNamespace() { + const namespaceFromModel = getValue(model, '/metadata/release/namespace') + const namespace = storeGet('/route/query/namespace') || namespaceFromModel || '' + return namespace + } - const resources = (resp && resp.data && resp.data.rows) || [] + async function getDbs() { + // watchDependency('model#/metadata/release/namespace') + const namespace = getValue(model, '/metadata/release/namespace') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - return resources.map((item) => { - const name = (item.cells?.length > 0 && item.cells[0].data) || '' - const kind = (item.cells?.length > 2 && item.cells[2].data) || '' - const dbObject = { - apiGroup: 'kubedb.com', - kind: kind, - name: name, - namespace: namespace, - } - return { - text: name, - value: dbObject, - } - }) -} + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core.k8s.appscode.com/v1alpha1/namespaces/${namespace}/genericresources`, + { + params: { + convertToTable: true, + labelSelector: 'k8s.io/group=kubedb.com', + }, + }, + ) -function initTarget({ getValue, discriminator, commit }) { - const target = getValue(discriminator, '/database') || {} - commit('wizard/model$update', { - path: '/metadata/release/name', - value: `${target.name}-${Math.floor(Date.now() / 1000)}-restore` || '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/target', - value: target, - force: true, - }) -} + const resources = (resp && resp.data && resp.data.rows) || [] -async function getRepositories({ getValue, model, storeGet, axios }) { - const user = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - const namespace = storeGet('/route/query/namespace') || '' - const activeOrg = storeGet('/activeOrganization') || '' - const orgList = storeGet('/organizations') || [] - const activeOrgObj = orgList.find((item) => item.username === activeOrg) - const orgType = activeOrgObj?.orgType - - let url = `/clusters/${user}/${cluster}/proxy/storage.kubestash.com/v1alpha1/repositories` - if (orgType === 3) { - url = `/clusters/${user}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${namespace}/repositories` + return resources.map((item) => { + const name = (item.cells?.length > 0 && item.cells[0].data) || '' + const kind = (item.cells?.length > 2 && item.cells[2].data) || '' + const dbObject = { + apiGroup: 'kubedb.com', + kind: kind, + name: name, + namespace: namespace, + } + return { + text: name, + value: dbObject, + } + }) } - try { - const resp = await axios.get(url) - let names = resp?.data?.items - names.map((item) => { - item.value = { name: item?.metadata?.name, namespace: item?.metadata?.namespace } || {} - item.text = `${item?.metadata?.namespace}/${item?.metadata?.name}` || '' - return true + function initTarget() { + const target = getValue(discriminator, '/database') || {} + commit('wizard/model$update', { + path: '/metadata/release/name', + value: `${target.name}-${Math.floor(Date.now() / 1000)}-restore` || '', + force: true, + }) + commit('wizard/model$update', { + path: '/spec/target', + value: target, + force: true, }) - - const resource = storeGet('/resource/layout/result/resource') || {} - let group = resource?.group || '' - let kind = resource?.kind || '' - - if (isConsole({ storeGet })) { - group = getValue(model, '/spec/target/apiGroup') || '' - kind = getValue(model, '/spec/target/kind') || '' - } - if (kind && group) { - const filteredRepo = names.filter((item) => { - const appRef = item?.spec?.appRef || {} - return appRef?.apiGroup === group && appRef?.kind === kind - }) - return filteredRepo - } else { - return names - } - } catch (e) { - console.log(e) } - return [] -} - -function onRepoChange({ getValue, discriminator, commit }) { - const repo = getValue(discriminator, '/repository') - commit('wizard/model$update', { - path: '/spec/dataSource/repository', - value: repo, - force: true, - }) -} -async function getSnapshots({ watchDependency, discriminator, storeGet, getValue, axios }) { - watchDependency('discriminator#/repository') - const user = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - const core = 'storage.kubestash.com' - const version = 'v1alpha1' - const repo = getValue(discriminator, '/repository') || {} - const namespace = repo.namespace || '' - const repository = repo.name || '' - - const url = `/clusters/${user}/${cluster}/proxy/${core}/${version}/namespaces/${namespace}/snapshots` + async function getRepositories() { + const user = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + const namespace = storeGet('/route/query/namespace') || '' + const activeOrg = storeGet('/activeOrganization') || '' + const orgList = storeGet('/organizations') || [] + const activeOrgObj = orgList.find((item) => item.username === activeOrg) + const orgType = activeOrgObj?.orgType + + let url = `/clusters/${user}/${cluster}/proxy/storage.kubestash.com/v1alpha1/repositories` + if (orgType === 3) { + url = `/clusters/${user}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${namespace}/repositories` + } - try { - if (namespace) { + try { const resp = await axios.get(url) - let snapshots = resp?.data?.items - snapshots.map((item) => { - const name = item?.metadata?.name - item.value = name - item.text = name + let names = resp?.data?.items + names.map((item) => { + item.value = { name: item?.metadata?.name, namespace: item?.metadata?.namespace } || {} + item.text = `${item?.metadata?.namespace}/${item?.metadata?.name}` || '' return true }) - const filteredSnapshots = - snapshots.filter((item) => { - const owners = item?.metadata?.ownerReferences || [] - if (owners.length) return owners[0].name === repository && owners[0].kind === 'Repository' - }) || [] - - filteredSnapshots.forEach((item) => { - const time = item.status?.snapshotTime || '' - // get the time difference and add it to subtext - item.subText = getTimeDiffs(time) - }) - if (filteredSnapshots.length) - filteredSnapshots[0].subText = '(Latest) ' + filteredSnapshots[0].subText - return filteredSnapshots + const resource = storeGet('/resource/layout/result/resource') || {} + let group = resource?.group || '' + let kind = resource?.kind || '' + + if (isConsole()) { + group = getValue(model, '/spec/target/apiGroup') || '' + kind = getValue(model, '/spec/target/kind') || '' + } + if (kind && group) { + const filteredRepo = names.filter((item) => { + const appRef = item?.spec?.appRef || {} + return appRef?.apiGroup === group && appRef?.kind === kind + }) + return filteredRepo + } else { + return names + } + } catch (e) { + console.log(e) } - } catch (e) { - console.log(e) + return [] } - return [] -} -function getTimeDiffs(time) { - if (time === '') return '' + function onRepoChange() { + const repo = getValue(discriminator, '/repository') + commit('wizard/model$update', { + path: '/spec/dataSource/repository', + value: repo, + force: true, + }) + } + + let snapshotObj = {} + let snapshotList = [] + let snapshotGroup = '' + let snapshotKind = '' - const now = new Date() - const timeConvert = new Date(time) - diffInMs = now - timeConvert + function onSnapChange() { + const snapshot = getValue(model, '/spec/dataSource/snapshot') || '' + snapshotObj = snapshotList.find((item) => item.metadata?.name === snapshot) || {} + snapshotKind = snapshotObj?.spec?.appRef?.kind || '' + snapshotGroup = snapshotObj?.spec?.appRef?.apiGroup || '' + } - // const diffInSeconds = Math.floor(diffInMs / 1000) % 60 - const diffInMinutes = Math.floor(diffInMs / (1000 * 60)) % 60 - const diffInHours = Math.floor(diffInMs / (1000 * 60 * 60)) % 24 - const diffInDays = Math.floor(diffInMs / (1000 * 60 * 60 * 24)) + async function getSnapshots() { + // watchDependency('discriminator#/repository') + const user = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + const core = 'storage.kubestash.com' + const version = 'v1alpha1' + const repo = getValue(discriminator, '/repository') || {} + const namespace = repo.namespace || '' + const repository = repo.name || '' - let timeDiff = '' - if (diffInDays) timeDiff += `${diffInDays} ${diffInDays > 1 ? 'days' : 'day'} ` - if (diffInHours) timeDiff += `${diffInHours} ${diffInHours > 1 ? 'hours' : 'hour'} ` - if (diffInMinutes) timeDiff += `${diffInMinutes} ${diffInMinutes > 1 ? 'minutes' : 'minute'}` - if (!diffInMinutes) return 'Just now' - return ` ${timeDiff} ago` -} + const url = `/clusters/${user}/${cluster}/proxy/${core}/${version}/namespaces/${namespace}/snapshots` -async function getAddons({ storeGet, axios, commit }) { - const user = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - const url = `/clusters/${user}/${cluster}/proxy/addons.kubestash.com/v1alpha1/addons` - if (isConsole({ storeGet })) { try { - const resp = await axios.get(url) - let addons = resp?.data?.items - addonList = addons - - addons = addons.map((item) => item?.metadata?.name) - - const kind = storeGet('/resource/layout/result/resource/kind') - if (kind) { - const found = addons.find((item) => item.startsWith(kind.toLowerCase())) - commit('wizard/model$update', { - path: '/spec/addon/name', - value: found, - force: true, + if (namespace) { + const resp = await axios.get(url) + let snapshots = resp?.data?.items + snapshotList = snapshots + snapshots.map((item) => { + const name = item?.metadata?.name + item.value = name + item.text = name + return true }) + const filteredSnapshots = + snapshots.filter((item) => { + const owners = item?.metadata?.ownerReferences || [] + if (owners.length) + return owners[0].name === repository && owners[0].kind === 'Repository' + }) || [] + + filteredSnapshots.forEach((item) => { + const time = item.status?.snapshotTime || '' + // get the time difference and add it to subtext + item.subText = getTimeDiffs(time) + }) + if (filteredSnapshots.length) + filteredSnapshots[0].subText = '(Latest) ' + filteredSnapshots[0].subText + + return filteredSnapshots } - return addons } catch (e) { console.log(e) } + return [] } - return [] -} -function getTasks({ watchDependency, model, getValue }) { - watchDependency('model#/spec/addon/name') - const addon = getValue(model, '/spec/addon/name') - const addonDetails = addonList?.find((item) => item?.metadata?.name === addon) - let tasks = addonDetails?.spec?.restoreTasks - tasks = tasks?.map((item) => item?.name) - return tasks -} + function getTimeDiffs(time) { + if (time === '') return '' -function databaseSelected({ storeGet, watchDependency, getValue, discriminator }) { - isKube = storeGet('/route/params/actions') - if (isKube) return true - watchDependency('discriminator#/database') - const target = getValue(discriminator, '/database') || {} - return !!target.name -} + const now = new Date() + const timeConvert = new Date(time) + const diffInMs = now - timeConvert -const securityContextMap = { - MongoDB: 999, - Postgres: 70, - Elasticsearch: 1000, - MSSQLServer: 10001, - MySQL: 999, - MariaDB: 999, - Redis: 999, - Singlestore: 999, - ZooKeeper: 999, -} + // const diffInSeconds = Math.floor(diffInMs / 1000) % 60 + const diffInMinutes = Math.floor(diffInMs / (1000 * 60)) % 60 + const diffInHours = Math.floor(diffInMs / (1000 * 60 * 60)) % 24 + const diffInDays = Math.floor(diffInMs / (1000 * 60 * 60 * 24)) -async function setSecurityContext({ storeGet, commit, axios }) { - const namespace = storeGet('/route/query/namespace') || '' - const user = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - if (namespace) { - const url = `clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}` - try { - const resp = await axios.get(url) - const annotations = resp.data?.metadata?.annotations || {} - const uidRange = annotations['openshift.io/sa.scc.uid-range'] - if (uidRange) { - const val = uidRange.split('/')[0] - commit('wizard/model$update', { - path: '/spec/addon/jobTemplate/securityContext', - value: val, - force: true, - }) - } else { - const kind = storeGet('/resource/layout/result/resource/kind') || '' - const context = securityContextMap[kind] + let timeDiff = '' + if (diffInDays) timeDiff += `${diffInDays} ${diffInDays > 1 ? 'days' : 'day'} ` + if (diffInHours) timeDiff += `${diffInHours} ${diffInHours > 1 ? 'hours' : 'hour'} ` + if (diffInMinutes) timeDiff += `${diffInMinutes} ${diffInMinutes > 1 ? 'minutes' : 'minute'}` + if (!diffInMinutes) return 'Just now' + return ` ${timeDiff} ago` + } - commit('wizard/model$update', { - path: '/spec/addon/jobTemplate/securityContext', - value: context, - force: true, - }) + function showGroupKind() { + const snapshot = getValue(model, '/spec/dataSource/snapshot') || '' + snapshotObj = snapshotList.find((item) => item.metadata?.name === snapshot) || {} + snapshotGroup = snapshotObj?.spec?.appRef?.apiGroup || '' + snapshotKind = snapshotObj?.spec?.appRef?.kind || '' + return !(snapshotGroup === 'kubedb.com') + } + + async function getAddons() { + const user = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + const url = `/clusters/${user}/${cluster}/proxy/addons.kubestash.com/v1alpha1/addons` + if (isConsole()) { + try { + const resp = await axios.get(url) + let addons = resp?.data?.items + addonList = addons + + addons = addons.map((item) => item?.metadata?.name) + + const kind = storeGet('/resource/layout/result/resource/kind') + if (kind) { + const found = addons.find((item) => item.startsWith(kind.toLowerCase())) + commit('wizard/model$update', { + path: '/spec/addon/name', + value: found, + force: true, + }) + } + if (Object.keys(snapshotObj).length) { + const filteredAddon = addons.find((item) => { + return item.includes(snapshotKind.toLowerCase()) + }) + + if (snapshotGroup === 'kubedb.com') { + commit('wizard/model$update', { + path: '/spec/target/kind', + value: snapshotKind, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/target/apiGroup', + value: snapshotGroup, + force: true, + }) + setVersion() + } + + if (filteredAddon) return [filteredAddon] + } + + return addons + } catch (e) { + console.log(e) } - } catch (e) { - console.log(e) } + return [] } -} -function returnFalse() { - return false -} + function getTasks() { + // watchDependency('model#/spec/addon/name') + const addon = getValue(model, '/spec/addon/name') + const addonDetails = addonList?.find((item) => item?.metadata?.name === addon) + let tasks = addonDetails?.spec?.restoreTasks + tasks = tasks?.map((item) => item?.name) + return tasks + } -let appKind = [] -let coreKind = [] -let kubedbKind = [] -let availableKinds = {} -let kindToResourceMap = {} -let namespaces = [] -let version = '' - -function init({ watchDependency, model, getValue, storeGet, axios }) { - getKindsApi({ watchDependency, model, getValue, storeGet, axios }) - namespaces = fetchNamespacesApi({ axios, storeGet }) -} + function databaseSelected() { + isKube = storeGet('/route/params/actions') + if (isKube) return true + // watchDependency('discriminator#/database') + const target = getValue(discriminator, '/database') || {} + return !!target.name + } -function fetchNamespaces({ watchDependency }) { - watchDependency('discriminator#/nameSpaceApi') - return namespaces -} + const securityContextMap = { + MongoDB: 999, + Postgres: 70, + Elasticsearch: 1000, + MSSQLServer: 10001, + MySQL: 999, + MariaDB: 999, + Redis: 999, + Singlestore: 999, + ZooKeeper: 999, + } -function setVersion({ getValue, model, watchDependency }) { - watchDependency('model#/spec/target/apiGroup') - watchDependency('model#/spec/target/kind') - const apiGroup = getValue(model, `/spec/target/apiGroup`) - const kind = getValue(model, `/spec/target/kind`) - if (apiGroup === 'core') apiGroup = '' - Object.keys(availableKinds[apiGroup]).forEach((vs) => { - availableKinds[apiGroup][vs].forEach((ele) => { - if (ele.Kind === kind) { - version = vs + async function setSecurityContext() { + const namespace = storeGet('/route/query/namespace') || '' + const user = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + if (namespace) { + const url = `clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}` + try { + const resp = await axios.get(url) + const annotations = resp.data?.metadata?.annotations || {} + const uidRange = annotations['openshift.io/sa.scc.uid-range'] + if (uidRange) { + const val = uidRange.split('/')[0] + commit('wizard/model$update', { + path: '/spec/addon/jobTemplate/securityContext', + value: val, + force: true, + }) + } else { + const kind = storeGet('/resource/layout/result/resource/kind') || '' + const context = securityContextMap[kind] + + commit('wizard/model$update', { + path: '/spec/addon/jobTemplate/securityContext', + value: context, + force: true, + }) + } + } catch (e) { + console.log(e) } - }) - }) -} + } + } -async function getKindsApi({ storeGet, axios }) { - const params = storeGet('/route/params') - const { user, cluster } = params - let url = `/clusters/${user}/${cluster}/available-types?groups=core,apps,kubedb.com` - try { - const resp = await axios.get(url) + function returnFalse() { + return false + } - kindToResourceMap['kubedb.com'] = {} - kindToResourceMap['apps'] = {} - kindToResourceMap['core'] = {} + let appKind = [] + let coreKind = [] + let kubedbKind = [] + let availableKinds = {} + let kindToResourceMap = {} + let namespaces = [] + let version = '' + + async function init() { + await getKindsApi() + namespaces = await fetchNamespacesApi() + } - availableKinds = resp.data + function fetchNamespaces() { + // watchDependency('discriminator#/nameSpaceApi') + return namespaces + } - appKind = Object.values(availableKinds['apps']) - .flat() - .map((ele) => { - kindToResourceMap['apps'][ele.Kind] = ele.Resource - return ele.Kind - }) - kubedbKind = Object.values(availableKinds['kubedb.com']) - .flat() - .map((ele) => { - kindToResourceMap['kubedb.com'][ele.Kind] = ele.Resource - return ele.Kind + function setVersion() { + // watchDependency('model#/spec/target/apiGroup') + // watchDependency('model#/spec/target/kind') + const apiGroup = getValue(model, `/spec/target/apiGroup`) + const kind = getValue(model, `/spec/target/kind`) + if (apiGroup === 'core') apiGroup = '' + Object.keys(availableKinds[apiGroup]).forEach((vs) => { + availableKinds[apiGroup][vs].forEach((ele) => { + if (ele.Kind === kind) { + version = vs + } }) - coreKind = Object.values(availableKinds['']) - .flat() - .map((ele) => { - kindToResourceMap['core'][ele.Kind] = ele.Resource - return ele.Kind - }) - } catch (e) { - console.log(e) + }) } - return [] -} -function getKinds({ watchDependency, getValue, model }) { - watchDependency(`model#/spec/target/apiGroup`) - const apiGroup = getValue(model, `/spec/target/apiGroup`) + async function getKindsApi() { + const params = storeGet('/route/params') + const { user, cluster } = params + let url = `/clusters/${user}/${cluster}/available-types?groups=core,apps,kubedb.com` + try { + const resp = await axios.get(url) - if (apiGroup === 'core') return coreKind - else if (apiGroup === 'apps') return appKind - else return kubedbKind -} + kindToResourceMap['kubedb.com'] = {} + kindToResourceMap['apps'] = {} + kindToResourceMap['core'] = {} -function getApiGroup() { - return ['core', 'apps', 'kubedb.com'] -} + availableKinds = resp.data -async function getTargetName({ watchDependency, getValue, model, axios, storeGet }) { - watchDependency('model#/spec/target/apiGroup') - watchDependency('model#/spec/target/namespace') - watchDependency('model#/spec/target/kind') - const apiGroup = getValue(model, `/spec/target/apiGroup`) - const namespace = getValue(model, `/spec/target/namespace`) - const resource = getResourceName({ getValue, model }) - const params = storeGet('/route/params') - const { user, cluster } = params - - const url = `/clusters/${user}/${cluster}/proxy/${apiGroup}/${version}/namespaces/${namespace}/${resource}` - if (apiGroup && version && resource && namespace) { - try { - const resp = await axios.get(url) - const items = resp.data?.items - const options = items.map((ele) => { - return ele.metadata.name - }) - return options + appKind = Object.values(availableKinds['apps']) + .flat() + .map((ele) => { + kindToResourceMap['apps'][ele.Kind] = ele.Resource + return ele.Kind + }) + kubedbKind = Object.values(availableKinds['kubedb.com']) + .flat() + .map((ele) => { + kindToResourceMap['kubedb.com'][ele.Kind] = ele.Resource + return ele.Kind + }) + coreKind = Object.values(availableKinds['']) + .flat() + .map((ele) => { + kindToResourceMap['core'][ele.Kind] = ele.Resource + return ele.Kind + }) } catch (e) { console.log(e) } + return [] } -} -function getResourceName({ getValue, model }) { - const apiGroup = getValue(model, `/spec/target/apiGroup`) - const kind = getValue(model, `/spec/target/kind`) - if (!kind || !apiGroup) return '' - return kindToResourceMap[apiGroup][kind] -} + function getKinds() { + // watchDependency(`model#/spec/target/apiGroup`) + const apiGroup = getValue(model, `/spec/target/apiGroup`) + if (apiGroup === 'core') return coreKind + else if (apiGroup === 'apps') return appKind + else return kubedbKind + } -function onParameterChange({ getValue, model, discriminator, commit }) { - const tasks = getValue(model, '/spec/addon/tasks') || [] - const params = getValue(discriminator, '/params') - tasks[0]['params'] = params - commit('wizard/model$update', { - path: '/spec/addon/tasks', - value: tasks, - force: true, - }) -} + function getApiGroup() { + return ['core', 'apps', 'kubedb.com'] + } + + async function getTargetName() { + // watchDependency('model#/spec/target/apiGroup') + // watchDependency('model#/spec/target/namespace') + // watchDependency('model#/spec/target/kind') + const apiGroup = getValue(model, `/spec/target/apiGroup`) + const namespace = getValue(model, `/spec/target/namespace`) + const resource = getResourceName() + const params = storeGet('/route/params') + const { user, cluster } = params + + const url = `/clusters/${user}/${cluster}/proxy/${apiGroup}/${version}/namespaces/${namespace}/${resource}` + if (apiGroup && version && resource && namespace) { + try { + const resp = await axios.get(url) + const items = resp.data?.items + const options = items.map((ele) => { + return ele.metadata.name + }) + return options + } catch (e) { + console.log(e) + } + } + } -return { - isRancherManaged, - fetchNamespaces, - setVersion, - init, - getTargetName, - getKinds, - getApiGroup, - isConsole, - initMetadata, - getPreset, - fetchNamespacesApi, - setNamespace, - getDbs, - initTarget, - getRepositories, - onRepoChange, - getSnapshots, - getAddons, - getTasks, - databaseSelected, - returnFalse, - onParameterChange, - setSecurityContext, + function getResourceName() { + const apiGroup = getValue(model, `/spec/target/apiGroup`) + const kind = getValue(model, `/spec/target/kind`) + if (!kind || !apiGroup) return '' + return kindToResourceMap[apiGroup][kind] + } + + function onParameterChange() { + const tasks = getValue(model, '/spec/addon/tasks') || [] + const params = getValue(discriminator, '/params') + tasks[0]['params'] = params + commit('wizard/model$update', { + path: '/spec/addon/tasks', + value: tasks, + force: true, + }) + } + + function clearAddon() { + return '' + } + + return { + isRancherManaged, + fetchNamespaces, + setVersion, + init, + getTargetName, + getKinds, + getApiGroup, + isConsole, + initMetadata, + getPreset, + fetchNamespacesApi, + setNamespace, + getDbs, + initTarget, + getRepositories, + onRepoChange, + getSnapshots, + onSnapChange, + getAddons, + getTasks, + databaseSelected, + returnFalse, + onParameterChange, + setSecurityContext, + showGroupKind, + clearAddon, + } } diff --git a/charts/enginekubevaultcom-mongodbrole-editor/ui/create-ui.yaml b/charts/enginekubevaultcom-mongodbrole-editor/ui/create-ui.yaml index b8d5b06082..de85e353b4 100644 --- a/charts/enginekubevaultcom-mongodbrole-editor/ui/create-ui.yaml +++ b/charts/enginekubevaultcom-mongodbrole-editor/ui/create-ui.yaml @@ -1,73 +1,62 @@ -steps: -- form: - elements: - - fetch: getDatabases|core.k8s.appscode.com|v1alpha1|genericresources - if: isConsole - label: - text: labels.selectDb - refresh: true - required: true - schema: - $ref: discriminator#/properties/database - sortable: true - type: select - - computed: setRoleName - label: - text: metadata.name - required: true - schema: - $ref: schema#/properties/metadata/properties/name +step: +- type: single-step-form + elements: + - loader: getDatabases|core.k8s.appscode.com|v1alpha1|genericresources + if: + name: isConsole + type: function + label: Select Database + refresh: true + validation: + type: required + schema: temp/properties/database + sortable: true + type: select + - watcher: + func: setRoleName + paths: + - schema/properties/spec/properties/secretEngineRef/properties/name + label: Name + validation: + type: required + schema: schema/properties/metadata/properties/name + type: input + - init: + value: getDbNamespace + type: func + disable: true + if: + name: isDbSelected + type: function + label: Namespace + schema: schema/properties/metadata/properties/namespace + type: input + - loader: getEngines|engine.kubevault.com|v1alpha1|secretengines + if: + name: isDbSelected + type: function + label: Select SecretEngine + refresh: true + validation: + type: required + schema: schema/properties/spec/properties/secretEngineRef/properties/name + type: select + - label: Default TTL + schema: schema/properties/spec/properties/defaultTTL + type: input + - label: Max TTL + schema: schema/properties/spec/properties/maxTTL + type: input + - type: array-item-form + element: + label: Statement type: input - - computed: getDbNamespace - disabled: true - if: isDbSelected - label: - text: metadata.namespace - schema: - $ref: schema#/properties/metadata/properties/namespace + label: Creation Statement + schema: schema/properties/spec/properties/creationStatements + - type: array-item-form + element: + label: Statement type: input - - fetch: getEngines|engine.kubevault.com|v1alpha1|secretengines - if: isDbSelected - label: - text: labels.selectEngine - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/secretEngineRef/properties/name - type: select - - label: - text: spec.defaultTTL - schema: - $ref: schema#/properties/spec/properties/defaultTTL - type: input - - label: - text: spec.maxTTL - schema: - $ref: schema#/properties/spec/properties/maxTTL - type: input - - element: - label: - text: labels.statement - schema: - $ref: schema#/properties/spec/properties/creationStatements/items - type: input - label: - text: spec.creation - schema: - $ref: schema#/properties/spec/properties/creationStatements - type: list-input-form - - element: - label: - text: labels.statement - schema: - $ref: schema#/properties/spec/properties/revocationStatements/items - type: input - label: - text: spec.revocation - schema: - $ref: schema#/properties/spec/properties/revocationStatements - type: list-input-form - type: single-step-form - id: basic - title: Create MongoDBRole + label: Revocation Statement + schema: schema/properties/spec/properties/revocationStatements type: multi-step-form diff --git a/charts/enginekubevaultcom-mongodbrole-editor/ui/functions.js b/charts/enginekubevaultcom-mongodbrole-editor/ui/functions.js index 3ba617c84a..bdd5020b2a 100644 --- a/charts/enginekubevaultcom-mongodbrole-editor/ui/functions.js +++ b/charts/enginekubevaultcom-mongodbrole-editor/ui/functions.js @@ -1,113 +1,123 @@ -function isConsole({ storeGet }) { - const owner = storeGet('/route/params/user') - const path = storeGet('/route/path') - const prefix = `/${owner}/kubernetes` - if (path.startsWith(prefix)) return true - return false -} +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} -async function getDatabases({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - if (isConsole({ storeGet })) { - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: { - convertToTable: true, - labelSelector: 'k8s.io/group=kubedb.com', - }, - }, - ) +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) - const resources = (resp && resp.data && resp.data.rows) || [] + function isConsole() { + const owner = storeGet('/route/params/user') + const path = storeGet('/route/path') + const prefix = `/${owner}/kubernetes` + if (path.startsWith(prefix)) return true + return false + } - resources.map((item) => { - const name = (item.cells && item.cells[0].data) || '' - const namespace = (item.cells?.length > 0 && item.cells[1].data) || '' - const resource = (item.cells?.length > 1 && item.cells[2].data) || '' - item.text = name - item.value = { - name: name, - namespace: namespace, - resource: resource, - } - return true - }) - const filteredResources = resources.filter( - (item) => item.value.resource.toLowerCase() === 'mongodb', - ) - return filteredResources - } catch (e) { - console.log(e) - return [] - } - } else return [] -} + async function getDatabases(group, version, resource) { + const owner = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + if (isConsole()) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: { + convertToTable: true, + labelSelector: 'k8s.io/group=kubedb.com', + }, + }, + ) -function isDbSelected({ getValue, storeGet, discriminator, watchDependency }) { - if (!isConsole({ storeGet })) return true - watchDependency('discriminator#/database') - const val = getValue(discriminator, '/database') || {} - return val && val.name ? true : false -} + const resources = (resp && resp.data && resp.data.rows) || [] -function setRoleName({ watchDependency, getValue, model }) { - watchDependency('model#/spec/secretEngineRef/name') - const engineName = getValue(model, '/spec/secretEngineRef/name') || '' - const timestamp = `${Math.floor(Date.now() / 1000)}` - return engineName ? `${engineName}-role-${timestamp}` : engineName -} + resources.map((item) => { + const name = (item.cells && item.cells[0].data) || '' + const namespace = (item.cells?.length > 0 && item.cells[1].data) || '' + const resource = (item.cells?.length > 1 && item.cells[2].data) || '' + item.text = name + item.value = { + name: name, + namespace: namespace, + resource: resource, + } + return true + }) + const filteredResources = resources.filter( + (item) => item.value.resource.toLowerCase() === 'mongodb', + ) + return filteredResources + } catch (e) { + console.log(e) + return [] + } + } else return [] + } -function getDbNamespace({ getValue, storeGet, discriminator, watchDependency }) { - if (isConsole({ storeGet })) { - watchDependency('discriminator#/database') - const data = getValue(discriminator, '/database') || {} - return (data && data.namespace) || '' - } else { - const namespace = storeGet('/route/query/namespace') || '' - return namespace + function isDbSelected() { + if (!isConsole()) return true + // watchDependency('discriminator#/database') + const val = getValue(discriminator, '/database') || {} + return val && val.name ? true : false } -} -async function getEngines({ axios, storeGet, getValue, discriminator }, group, version, resource) { - const owner = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - const dbValue = getValue(discriminator, '/database') || {} - const dbName = storeGet('/route/params/name') || dbValue.name || '' - const dbNamespace = storeGet('/route/query/namespace') || dbValue.namespace || '' - if (dbName) { - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - ) + function setRoleName() { + // watchDependency('model#/spec/secretEngineRef/name') + const engineName = getValue(model, '/spec/secretEngineRef/name') || '' + const timestamp = `${Math.floor(Date.now() / 1000)}` + + return engineName ? `${engineName}-role-${timestamp}` : engineName + } - const resources = (resp && resp.data && resp.data.items) || [] - const filteredResources = resources.filter( - (item) => - item.spec?.mongodb?.databaseRef?.name === dbName && - item.spec?.mongodb?.databaseRef?.namespace === dbNamespace, - ) - filteredResources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return filteredResources - } catch (e) { - console.log(e) - return [] + function getDbNamespace() { + if (isConsole()) { + // watchDependency('discriminator#/database') + const data = getValue(discriminator, '/database') || {} + return (data && data.namespace) || '' + } else { + const namespace = storeGet('/route/query/namespace') || '' + return namespace } - } else return [] -} + } -return { - isConsole, - getDatabases, - isDbSelected, - setRoleName, - getDbNamespace, - getEngines, + async function getEngines(group, version, resource) { + const owner = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + const dbValue = getValue(discriminator, '/database') || {} + const dbName = storeGet('/route/params/name') || dbValue.name || '' + const dbNamespace = storeGet('/route/query/namespace') || dbValue.namespace || '' + if (dbName) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + ) + + const resources = (resp && resp.data && resp.data.items) || [] + const filteredResources = resources.filter( + (item) => + item.spec?.mongodb?.databaseRef?.name === dbName && + item.spec?.mongodb?.databaseRef?.namespace === dbNamespace, + ) + filteredResources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true + }) + return filteredResources + } catch (e) { + console.log(e) + return [] + } + } else return [] + } + + return { + isConsole, + getDatabases, + isDbSelected, + setRoleName, + getDbNamespace, + getEngines, + } } diff --git a/charts/enginekubevaultcom-secretaccessrequest-editor/ui/create-ui.yaml b/charts/enginekubevaultcom-secretaccessrequest-editor/ui/create-ui.yaml index b1278b30c9..1d6d431cee 100644 --- a/charts/enginekubevaultcom-secretaccessrequest-editor/ui/create-ui.yaml +++ b/charts/enginekubevaultcom-secretaccessrequest-editor/ui/create-ui.yaml @@ -1,102 +1,69 @@ -steps: -- form: - elements: - - fetch: getDatabases|core.k8s.appscode.com|v1alpha1|genericresources - if: isConsole - label: - text: labels.selectDb - refresh: true - required: true - schema: - $ref: discriminator#/properties/database - sortable: true - type: select - - computed: setRequestName - label: - text: metadata.name - required: true - schema: - $ref: schema#/properties/metadata/properties/name +step: +- type: single-step-form + elements: + - loader: getDatabases|core.k8s.appscode.com|v1alpha1|genericresources + if: + name: isConsole + type: function + label: Select Database + refresh: true + validation: + type: required + schema: temp/properties/database + sortable: true + type: select + - watcher: + func: setRequestName + paths: + - schema/properties/spec/properties/roleRef + label: Name + validation: + type: required + schema: schema/properties/metadata/properties/name + type: input + - init: + type: func + value: getDbNamespace + disable: true + if: + name: isDbSelected + type: function + label: Namespace + schema: schema/properties/metadata/properties/namespace + type: input + - loader: getDbRoles|engine.kubevault.com|v1alpha1 + if: + name: isDbSelected + type: function + label: Select Role + refresh: true + validation: + type: required + schema: schema/properties/spec/properties/roleRef + type: select + - elements: + - label: Name + validation: + type: required + schema: name type: input - - computed: getDbNamespace - disabled: true - if: isDbSelected - label: - text: metadata.namespace - schema: - $ref: schema#/properties/metadata/properties/namespace + - label: Kind + validation: + type: required + schema: kind type: input - - fetch: getDbRoles|engine.kubevault.com|v1alpha1 - if: isDbSelected - label: - text: labels.select - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/roleRef + - loader: getNamespaces|core|v1|namespaces + hasGroup: isRancherManaged + label: Namespace + schema: namespace type: select - - addFormLabel: Subject - element: - elements: - - label: - text: spec.subjects.name - schema: - $ref: schema#/properties/spec/properties/subjects/items/properties/name - type: input - - label: - text: spec.subjects.kind - schema: - $ref: schema#/properties/spec/properties/subjects/items/properties/kind - type: input - - fetch: getNamespaces|core|v1|namespaces - hasGroup: isRancherManaged - label: - text: spec.subjects.namespace - schema: - $ref: schema#/properties/spec/properties/subjects/items/properties/namespace - type: select - - label: - text: spec.subjects.group - schema: - $ref: schema#/properties/spec/properties/subjects/items/properties/apiGroup - type: input - type: single-step-form - label: - text: spec.subjects.title - schema: - $ref: schema#/properties/spec/properties/subjects - tableContents: - - inTableColumn: true - label: - text: spec.subjects.name - path: name - type: value - typeOfValue: string - - inTableColumn: true - label: - text: spec.subjects.kind - path: kind - type: value - typeOfValue: string - - inTableColumn: true - label: - text: spec.subjects.namespace - path: namespace - type: value - typeOfValue: string - - inTableColumn: true - label: - text: spec.subjects.group - path: apigroup - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: labels.ttl - schema: - $ref: schema#/properties/spec/properties/ttl + - label: APIGroup + schema: apiGroup type: input - type: single-step-form - id: basic - title: Create SecretAccessRequest + label: Subjects + schema: schema/properties/spec/properties/subjects + type: array-object-form + - label: TTL + schema: schema/properties/spec/properties/ttl + type: input type: multi-step-form diff --git a/charts/enginekubevaultcom-secretaccessrequest-editor/ui/functions.js b/charts/enginekubevaultcom-secretaccessrequest-editor/ui/functions.js index 2be4e7cc8e..7f08162de8 100644 --- a/charts/enginekubevaultcom-secretaccessrequest-editor/ui/functions.js +++ b/charts/enginekubevaultcom-secretaccessrequest-editor/ui/functions.js @@ -1,267 +1,262 @@ -let secretEngineList = [] -let filteredEngineList = [] +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} -function isConsole({ storeGet }) { - const owner = storeGet('/route/params/user') - const path = storeGet('/route/path') - const prefix = `/${owner}/kubernetes` - if (path.startsWith(prefix)) return true - return false -} +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) -async function getEngines({ axios, storeGet }) { - const owner = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - try { - const group = 'engine.kubevault.com' - const version = 'v1alpha1' - const resource = 'secretengines' - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - ) + let secretEngineList = [] + let filteredEngineList = [] - const resources = (resp && resp.data && resp.data.items) || [] - const engines = resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const spec = item.spec || {} - return { - text: name, - value: { - name: name, - spec: spec, - }, - } - }) - secretEngineList = engines - return resources - } catch (e) { - console.log(e) - return [] + function isConsole() { + const owner = storeGet('/route/params/user') + const path = storeGet('/route/path') + const prefix = `/${owner}/kubernetes` + if (path.startsWith(prefix)) return true + return false } -} - -function getSingularResource(resource) { - if (resource === 'elasticsearches') return 'elasticsearch' - else if (resource === 'mariadbs') return 'mariadb' - else if (resource === 'mongodbs') return 'mongodb' - else if (resource === 'mysqls') return 'mysql' - else if (resource === 'postgreses') return 'postgres' - else if (resource === 'redises') return 'redis' - else return '' -} - -function filterSecretEngineList({ getValue, storeGet, discriminator }) { - const dbValue = getValue(discriminator, '/database') || {} - const dbName = dbValue?.name ? dbValue.name : storeGet('/route/params/name') || '' - const dbNamespace = dbValue?.namespace - ? dbValue.namespace - : storeGet('route/query/namespace') || '' - let resource = isConsole({ storeGet }) - ? dbValue?.resource || '' - : getSingularResource(storeGet('/route/params/resource') || '') - resource = resource.toLowerCase() - const filteredList = secretEngineList.filter((engine) => { - return ( - engine.value.spec && - engine.value.spec[resource] && - engine.value.spec[resource].databaseRef && - engine.value.spec[resource].databaseRef.name === dbName && - engine.value.spec[resource].databaseRef.namespace === dbNamespace - ) - }) - const result = filteredList.map((engine) => engine.value?.name) - filteredEngineList = result -} - -async function getDatabases( - { axios, storeGet, getValue, discriminator }, - group, - version, - resource, -) { - const owner = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - if (isConsole({ storeGet })) { - await getEngines({ axios, storeGet, getValue, discriminator }) + async function getEngines() { + const owner = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' try { + const group = 'engine.kubevault.com' + const version = 'v1alpha1' + const resource = 'secretengines' const resp = await axios.get( `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: { - convertToTable: true, - labelSelector: 'k8s.io/group=kubedb.com', - }, - }, ) - const resources = (resp && resp.data && resp.data.rows) || [] - const databases = resources.map((item) => { - const name = (item.cells && item.cells[0].data) || '' - const namespace = (item.cells?.length > 0 && item.cells[1].data) || '' - const resource = (item.cells?.length > 1 && item.cells[2].data) || '' + const resources = (resp && resp.data && resp.data.items) || [] + const engines = resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + const spec = item.spec || {} return { text: name, value: { name: name, - namespace: namespace, - resource: resource, + spec: spec, }, } }) - return databases + secretEngineList = engines + return resources } catch (e) { console.log(e) return [] } } -} -function isDbSelected({ getValue, storeGet, discriminator, watchDependency }) { - if (!isConsole({ storeGet })) return true - watchDependency('discriminator#/database') - const val = getValue(discriminator, '/database') || {} - return val && val.name ? true : false -} + function getSingularResource(resource) { + if (resource === 'elasticsearches') return 'elasticsearch' + else if (resource === 'mariadbs') return 'mariadb' + else if (resource === 'mongodbs') return 'mongodb' + else if (resource === 'mysqls') return 'mysql' + else if (resource === 'postgreses') return 'postgres' + else if (resource === 'redises') return 'redis' + else return '' + } -function setRequestName({ watchDependency, getValue, model }) { - watchDependency('model#/spec/roleRef/name') - const roleName = getValue(model, '/spec/roleRef/name') || '' + function filterSecretEngineList() { + const dbValue = getValue(discriminator, '/database') || {} + const dbName = dbValue?.name ? dbValue.name : storeGet('/route/params/name') || '' + const dbNamespace = dbValue?.namespace + ? dbValue.namespace + : storeGet('route/query/namespace') || '' + let resource = isConsole() + ? dbValue?.resource || '' + : getSingularResource(storeGet('/route/params/resource') || '') + resource = resource.toLowerCase() - let refinedRoleName = roleName - const lastDash = roleName.lastIndexOf('-') - if (lastDash !== -1 && !isNaN(roleName.slice(lastDash + 1))) - refinedRoleName = roleName.slice(0, lastDash) + const filteredList = secretEngineList.filter((engine) => { + return ( + engine.value.spec && + engine.value.spec[resource] && + engine.value.spec[resource].databaseRef && + engine.value.spec[resource].databaseRef.name === dbName && + engine.value.spec[resource].databaseRef.namespace === dbNamespace + ) + }) + const result = filteredList.map((engine) => engine.value?.name) + filteredEngineList = result + } - const timestamp = `${Math.floor(Date.now() / 1000)}` - return refinedRoleName ? `${refinedRoleName}-request-${timestamp}` : refinedRoleName -} + async function getDatabases(group, version, resource) { + const owner = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + if (isConsole({ storeGet })) { + await getEngines({ axios, storeGet, getValue, discriminator }) + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: { + convertToTable: true, + labelSelector: 'k8s.io/group=kubedb.com', + }, + }, + ) + const resources = (resp && resp.data && resp.data.rows) || [] -function getDbNamespace({ getValue, storeGet, discriminator, watchDependency }) { - if (isConsole({ storeGet })) { - watchDependency('discriminator#/database') - const data = getValue(discriminator, '/database') || {} - return (data && data.namespace) || '' - } else { - const namespace = storeGet('/route/query/namespace') || '' - return namespace + const databases = resources.map((item) => { + const name = (item.cells && item.cells[0].data) || '' + const namespace = (item.cells?.length > 0 && item.cells[1].data) || '' + const resource = (item.cells?.length > 1 && item.cells[2].data) || '' + return { + text: name, + value: { + name: name, + namespace: namespace, + resource: resource, + }, + } + }) + return databases + } catch (e) { + console.log(e) + return [] + } + } } -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function isDbSelected() { + if (!isConsole({ storeGet })) return true + // watchDependency('discriminator#/database') + const val = getValue(discriminator, '/database') || {} + return val && val.name ? true : false + } -async function getNamespaces({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' + function setRequestName() { + // watchDependency('model#/spec/roleRef/name') + const roleName = getValue(model, '/spec/roleRef/name') || '' - 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) || [] + let refinedRoleName = roleName + const lastDash = roleName.lastIndexOf('-') + if (lastDash !== -1 && !isNaN(roleName.slice(lastDash + 1))) + refinedRoleName = roleName.slice(0, lastDash) - const namespaces = resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { text: name, value: name } - }) - return namespaces - } catch (e) { - console.log(e) - return [] + const timestamp = `${Math.floor(Date.now() / 1000)}` + return refinedRoleName ? `${refinedRoleName}-request-${timestamp}` : refinedRoleName } -} - -function getResourceRoleNameForConsole(resource) { - return `${resource.toLowerCase()}roles` -} -function getResourceRoleName(resource) { - if (resource === 'elasticsearches') return 'elasticsearchroles' - else if (resource === 'mariadbs') return 'mariadbroles' - else if (resource === 'mongodbs') return 'mongodbroles' - else if (resource === 'mysqls') return 'mysqlroles' - else if (resource === 'postgreses') return 'postgresroles' - else if (resource === 'redises') return 'redisroles' - else return '' -} - -async function getDbRoles( - { axios, storeGet, discriminator, getValue, watchDependency }, - group, - version, -) { - if (!isConsole({ storeGet })) await getEngines({ axios, storeGet }) - filterSecretEngineList({ - getValue, - storeGet, - discriminator, - watchDependency, - }) + function getDbNamespace() { + if (isConsole({ storeGet })) { + // watchDependency('discriminator#/database') + const data = getValue(discriminator, '/database') || {} + return (data && data.namespace) || '' + } else { + const namespace = storeGet('/route/query/namespace') || '' + return namespace + } + } - const dbValue = getValue(discriminator, '/database') || {} - const owner = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - let resource = '' - let pluralRole = '' - if (isConsole({ storeGet })) { - resource = dbValue?.resource || '' - pluralRole = getResourceRoleNameForConsole(resource) - } else { - resource = storeGet('/route/params/resource') || '' - pluralRole = getResourceRoleName(resource) + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found } - if (resource) { + async function getNamespaces(group, version, resource) { + const owner = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + try { - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${pluralRole}` - const resp = await axios.get(url) - const response = (resp && resp.data && resp.data.items) || [] + 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) || [] - roles = response.map((item) => { + const namespaces = resources.map((item) => { const name = (item.metadata && item.metadata.name) || '' - const kind = (item && item.kind) || '' - const namespace = (item.metadata && item.metadata.namespace) || '' - const engine = (item.spec && item.spec.secretEngineRef?.name) || '' - return { - text: name, - value: { - name: name, - kind: kind, - namespace: namespace, - engineRef: engine, - }, - } - }) - return roles.filter((role) => { - const target = role.value.engineRef - return filteredEngineList.find((item) => item === target) + return { text: name, value: name } }) + return namespaces } catch (e) { console.log(e) return [] } } -} -return { - isRancherManaged, - isConsole, - getDatabases, - isDbSelected, - setRequestName, - getDbNamespace, - getNamespaces, - getResourceRoleName, - getResourceRoleNameForConsole, - getDbRoles, - getEngines, - filterSecretEngineList, - getSingularResource, + function getResourceRoleNameForConsole(resource) { + return `${resource.toLowerCase()}roles` + } + + function getResourceRoleName(resource) { + if (resource === 'elasticsearches') return 'elasticsearchroles' + else if (resource === 'mariadbs') return 'mariadbroles' + else if (resource === 'mongodbs') return 'mongodbroles' + else if (resource === 'mysqls') return 'mysqlroles' + else if (resource === 'postgreses') return 'postgresroles' + else if (resource === 'redises') return 'redisroles' + else return '' + } + + async function getDbRoles(group, version) { + if (!isConsole()) await getEngines() + filterSecretEngineList() + + const dbValue = getValue(discriminator, '/database') || {} + const owner = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + let resource = '' + let pluralRole = '' + if (isConsole()) { + resource = dbValue?.resource || '' + pluralRole = getResourceRoleNameForConsole(resource) + } else { + resource = storeGet('/route/params/resource') || '' + pluralRole = getResourceRoleName(resource) + } + + if (resource) { + try { + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${pluralRole}` + const resp = await axios.get(url) + const response = (resp && resp.data && resp.data.items) || [] + + let roles = response.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + const kind = (item && item.kind) || '' + const namespace = (item.metadata && item.metadata.namespace) || '' + const engine = (item.spec && item.spec.secretEngineRef?.name) || '' + return { + text: name, + value: { + name: name, + kind: kind, + namespace: namespace, + engineRef: engine, + }, + } + }) + return roles?.filter((role) => { + const target = role.value.engineRef + return filteredEngineList.find((item) => item === target) + }) + } catch (e) { + console.log(e) + return [] + } + } + } + + return { + isRancherManaged, + isConsole, + getDatabases, + isDbSelected, + setRequestName, + getDbNamespace, + getNamespaces, + getResourceRoleName, + getResourceRoleNameForConsole, + getDbRoles, + getEngines, + filterSecretEngineList, + getSingularResource, + } } diff --git a/charts/enginekubevaultcom-secretengine-editor/ui/create-ui.yaml b/charts/enginekubevaultcom-secretengine-editor/ui/create-ui.yaml index fd55a401b0..588622af73 100644 --- a/charts/enginekubevaultcom-secretengine-editor/ui/create-ui.yaml +++ b/charts/enginekubevaultcom-secretengine-editor/ui/create-ui.yaml @@ -1,66 +1,80 @@ -steps: -- form: - elements: - - fetch: getDatabases|core.k8s.appscode.com|v1alpha1|genericresources - if: isConsole - label: - text: labels.selectDb - onChange: getSpecRef - refresh: true - required: true - schema: - $ref: discriminator#/properties/database - sortable: true - type: select - - computed: getEngineName - label: - text: metadata.name - required: true - schema: - $ref: schema#/properties/metadata/properties/name - type: input - - computed: getDbNamespace - disabled: true - if: isDbSelected - label: - text: metadata.namespace - schema: - $ref: schema#/properties/metadata/properties/namespace - type: input - - fetch: getVaultservers|kubevault.com|v1alpha2|vaultservers - label: - text: labels.selectVault - refresh: true - required: true - schema: - $ref: discriminator#/properties/vaultserver - type: select - - computed: vaultRefName - disabled: true - if: isVaultSelected - label: - text: spec.vaultRef.name - onChange: getSpecRef - schema: - $ref: schema#/properties/spec/properties/vaultRef/properties/name - type: input - - computed: vaultRefNamespace - disabled: true - if: isVaultSelected - label: - text: spec.vaultRef.namespace - schema: - $ref: schema#/properties/spec/properties/vaultRef/properties/namespace - type: input - - computed: getPluginName - disabled: true - if: isDbSelected - label: - text: labels.plugin - schema: - $ref: discriminator#/properties/plugin-name - type: input - type: single-step-form - id: basic - title: Create SecretEngine +step: +- type: single-step-form + elements: + - loader: getDatabases|core.k8s.appscode.com|v1alpha1|genericresources + if: + name: isConsole + type: function + label: Select Database + watcher: + func: getSpecRef + paths: + - schema/properties/spec/properties/database + refresh: true + validation: + type: required + schema: temp/properties/database + sortable: true + type: select + - init: + type: func + value: getEngineName + label: Name + validation: + type: required + schema: schema/properties/metadata/properties/name + type: input + - init: + type: func + value: getDbNamespace + disable: true + if: + name: isDbSelected + type: function + label: Namespace + schema: schema/properties/metadata/properties/namespace + type: input + - loader: getVaultservers|kubevault.com|v1alpha2|vaultservers + label: Select VaultServer + refresh: true + validation: + type: required + schema: temp/properties/vaultserver + watcher: + func: getSpecRef + paths: + - temp/properties/vaultserver + type: select + - init: + value: vaultRefName + type: func + disable: true + if: + name: isVaultSelected + type: function + label: Vaultref Name + + schema: schema/properties/spec/properties/vaultRef/properties/name + type: input + - init: + value: vaultRefNamespace + type: func + disable: true + if: + name: isVaultSelected + type: function + label: Vaultref Namespace + schema: schema/properties/spec/properties/vaultRef/properties/namespace + type: input + - watcher: + func: getPluginName + paths: + - schema/properties/spec/properties/database + disable: true + if: + name: isDbSelected + type: function + label: Plugin Name + schema: discriminator/properties/plugin-name + type: input type: multi-step-form diff --git a/charts/enginekubevaultcom-secretengine-editor/ui/functions.js b/charts/enginekubevaultcom-secretengine-editor/ui/functions.js index 0410166b3d..0e4a999a66 100644 --- a/charts/enginekubevaultcom-secretengine-editor/ui/functions.js +++ b/charts/enginekubevaultcom-secretengine-editor/ui/functions.js @@ -1,37 +1,119 @@ -function isConsole({ storeGet }) { - const owner = storeGet('/route/params/user') - const path = storeGet('/route/path') - const prefix = `/${owner}/kubernetes` - if (path.startsWith(prefix)) return true - return false -} +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) + + function isConsole() { + const owner = storeGet('/route/params/user') + const path = storeGet('/route/path') + const prefix = `/${owner}/kubernetes` + if (path.startsWith(prefix)) return true + return false + } + + async function getDatabases(group, version, resource) { + const owner = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + if (isConsole()) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: { + convertToTable: true, + labelSelector: 'k8s.io/group=kubedb.com', + }, + }, + ) + + const resources = (resp && resp.data && resp.data.rows) || [] + + resources.map((item) => { + const name = (item.cells && item.cells[0].data) || '' + const namespace = (item.cells?.length > 0 && item.cells[1].data) || '' + const resource = (item.cells?.length > 1 && item.cells[2].data) || '' + item.text = name + item.value = { + name: name, + namespace: namespace, + resource: resource, + } + return true + }) + return resources + } catch (e) { + console.log(e) + return [] + } + } + } + + function isDbSelected() { + if (!isConsole()) return true + // watchDependency('discriminator#/database') + const val = getValue(discriminator, '/database') || {} + return val && val.name ? true : false + } + + function getDbName() { + if (isConsole()) { + // watchDependency('discriminator#/database') + const data = getValue(discriminator, '/database') || {} + return (data && data.name) || '' + } else { + const name = storeGet('/route/params/name') || '' + return name + } + } + + function getEngineName() { + // watchDependency('model#/spec/vaultRef/name') + const val = getValue(model, '/spec/vaultRef/name') || '' + const dbName = getDbName() + return val && dbName ? `${dbName}-${val}` : dbName + } + + function getDbNamespace() { + if (isConsole()) { + // watchDependency('discriminator#/database') + const data = getValue(discriminator, '/database') || {} + return (data && data.namespace) || '' + } else { + const namespace = storeGet('/route/query/namespace') || '' + return namespace + } + } -async function getDatabases({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - if (isConsole({ storeGet })) { + function isVaultSelected() { + // watchDependency('discriminator#/vaultserver') + const vault = getValue(discriminator, '/vaultserver') || {} + return vault && vault.name ? true : false + } + + async function getVaultservers(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: { - convertToTable: true, - labelSelector: 'k8s.io/group=kubedb.com', + filter: { items: { metadata: { name: null, namespace: null } } }, }, }, ) - const resources = (resp && resp.data && resp.data.rows) || [] - + const resources = (resp && resp.data && resp.data.items) || [] resources.map((item) => { - const name = (item.cells && item.cells[0].data) || '' - const namespace = (item.cells?.length > 0 && item.cells[1].data) || '' - const resource = (item.cells?.length > 1 && item.cells[2].data) || '' - item.text = name + const name = (item.metadata && item.metadata.name) || '' + const namespace = (item.metadata && item.metadata.namespace) || '' + item.text = `${namespace}/${name}` item.value = { name: name, namespace: namespace, - resource: resource, } return true }) @@ -41,183 +123,101 @@ async function getDatabases({ axios, storeGet }, group, version, resource) { return [] } } -} - -function isDbSelected({ getValue, storeGet, discriminator, watchDependency }) { - if (!isConsole({ storeGet })) return true - watchDependency('discriminator#/database') - const val = getValue(discriminator, '/database') || {} - return val && val.name ? true : false -} -function getDbName({ getValue, storeGet, discriminator, watchDependency }) { - if (isConsole({ storeGet })) { - watchDependency('discriminator#/database') - const data = getValue(discriminator, '/database') || {} - return (data && data.name) || '' - } else { - const name = storeGet('/route/params/name') || '' - return name - } -} + function vaultRefName() { + const vault = getValue(discriminator, '/vaultserver') || {} -function getEngineName({ storeGet, getValue, watchDependency, model, discriminator }) { - watchDependency('model#/spec/vaultRef/name') - const val = getValue(model, '/spec/vaultRef/name') || '' - const dbName = getDbName({ - getValue, - storeGet, - discriminator, - watchDependency, - }) - return val && dbName ? `${dbName}-${val}` : dbName -} - -function getDbNamespace({ getValue, storeGet, discriminator, watchDependency }) { - if (isConsole({ storeGet })) { - watchDependency('discriminator#/database') - const data = getValue(discriminator, '/database') || {} - return (data && data.namespace) || '' - } else { - const namespace = storeGet('/route/query/namespace') || '' - return namespace + let refName = '' + if (vault && vault.name) { + refName = vault.name + } + return refName } -} -function isVaultSelected({ getValue, watchDependency, discriminator }) { - watchDependency('discriminator#/vaultserver') - const vault = getValue(discriminator, '/vaultserver') || {} - return vault && vault.name ? true : false -} - -async function getVaultservers({ axios, storeGet }, 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, namespace: null } } }, - }, - }, - ) - - const resources = (resp && resp.data && resp.data.items) || [] - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const namespace = (item.metadata && item.metadata.namespace) || '' - item.text = `${namespace}/${name}` - item.value = { - name: name, - namespace: namespace, - } - return true - }) - return resources - } catch (e) { - console.log(e) - return [] + function vaultRefNamespace() { + const vault = getValue(discriminator, '/vaultserver') || {} + let refNamespace = '' + if (vault && vault.namespace) { + refNamespace = vault.namespace + } + return refNamespace } -} -function vaultRefName({ getValue, discriminator }) { - const vault = getValue(discriminator, '/vaultserver') || {} - let refName = '' - if (vault && vault.name) { - refName = vault.name + function getSingularResource(resource) { + if (resource === 'elasticsearches') return 'elasticsearch' + else if (resource === 'mariadbs') return 'mariadb' + else if (resource === 'mongodbs') return 'mongodb' + else if (resource === 'mysqls') return 'mysql' + else if (resource === 'postgreses') return 'postgres' + else if (resource === 'redises') return 'redis' } - return refName -} -function vaultRefNamespace({ getValue, discriminator }) { - const vault = getValue(discriminator, '/vaultserver') || {} - let refNamespace = '' - if (vault && vault.namespace) { - refNamespace = vault.namespace + function getPluginName() { + // watchDependency('discriminator#/database') + const database = getValue(discriminator, '/database') || {} + const resource = storeGet('/route/params/resource') || '' + let singularResource = getSingularResource(resource) || '' + if (singularResource === 'postgres') singularResource = 'postgresql' + if (database && database.resource) { + const databaseResource = database.resource + singularResource = databaseResource.toLowerCase() + } + let plugin = '' + if (singularResource) plugin = `${singularResource}-database-plugin` + return plugin } - return refNamespace -} - -function getSingularResource(resource) { - if (resource === 'elasticsearches') return 'elasticsearch' - else if (resource === 'mariadbs') return 'mariadb' - else if (resource === 'mongodbs') return 'mongodb' - else if (resource === 'mysqls') return 'mysql' - else if (resource === 'postgreses') return 'postgres' - else if (resource === 'redises') return 'redis' -} -function getPluginName({ storeGet, getValue, watchDependency, discriminator }) { - watchDependency('discriminator#/database') - const database = getValue(discriminator, '/database') || {} - const resource = storeGet('/route/params/resource') || '' - let singularResource = getSingularResource(resource) || '' - if (singularResource === 'postgres') singularResource = 'postgresql' - if (database && database.resource) { - const databaseResource = database.resource - singularResource = databaseResource.toLowerCase() - } - let plugin = '' - if (singularResource) plugin = `${singularResource}-database-plugin` - return plugin -} + function getSpecRef() { + // watchDependency('discriminator#/database') + const database = getValue(discriminator, '/database') || {} + const paramResource = storeGet('/route/params/resource') || '' + let databaseRefName = getSingularResource(paramResource) || '' + if (database && database.resource) databaseRefName = database.resource.toLowerCase() + + const dbValue = getValue(discriminator, '/database') || {} + const dbName = storeGet('/route/params/name') || dbValue?.name || '' + const dbNamespace = storeGet('/route/query/namespace') || dbValue?.namespace || '' + + const val = { + databaseRef: { + name: dbName, + namespace: dbNamespace, + }, + pluginName: getPluginName(), + } -function getSpecRef({ model, getValue, storeGet, commit, watchDependency, discriminator }) { - watchDependency('discriminator#/database') - const database = getValue(discriminator, '/database') || {} - const paramResource = storeGet('/route/params/resource') || '' - let databaseRefName = getSingularResource(paramResource) || '' - if (database && database.resource) databaseRefName = database.resource.toLowerCase() - - const dbValue = getValue(discriminator, '/database') || {} - const dbName = storeGet('/route/params/name') || dbValue?.name || '' - const dbNamespace = storeGet('/route/query/namespace') || dbValue?.namespace || '' - - const val = { - databaseRef: { - name: dbName, - namespace: dbNamespace, - }, - pluginName: getPluginName({ - storeGet, - getValue, - watchDependency, - discriminator, - }), - } + let spec = getValue(model, '/spec') || {} - let spec = getValue(model, '/spec') || {} - - const temp = Object.keys(spec).filter((key) => key === 'vaultRef') - const tempSpec = {} - temp.forEach((key) => { - tempSpec[key] = spec[key] - }) - spec = tempSpec - - spec[databaseRefName] = val - if (spec && databaseRefName) { - commit('wizard/model$update', { - path: `/spec`, - value: spec, - force: true, + const temp = Object.keys(spec).filter((key) => key === 'vaultRef') + const tempSpec = {} + temp.forEach((key) => { + tempSpec[key] = spec[key] }) + spec = tempSpec + + spec[databaseRefName] = val + if (spec && databaseRefName) { + commit('wizard/model$update', { + path: `/spec`, + value: spec, + force: true, + }) + } } -} -return { - isConsole, - getDatabases, - isDbSelected, - getDbName, - getEngineName, - getDbNamespace, - isVaultSelected, - getVaultservers, - vaultRefName, - vaultRefNamespace, - getSingularResource, - getPluginName, - getSpecRef, + return { + isConsole, + getDatabases, + isDbSelected, + getDbName, + getEngineName, + getDbNamespace, + isVaultSelected, + getVaultservers, + vaultRefName, + vaultRefNamespace, + getSingularResource, + getPluginName, + getSpecRef, + } } diff --git a/charts/kubedbcom-cassandra-editor-options/ui/create-ui.yaml b/charts/kubedbcom-cassandra-editor-options/ui/create-ui.yaml index 64f1927be8..bf299f900e 100644 --- a/charts/kubedbcom-cassandra-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-cassandra-editor-options/ui/create-ui.yaml @@ -1,341 +1,332 @@ -steps: -- form: - discriminator: - bundleApiLoaded: - default: false - type: boolean - elements: - - computed: initBundle - if: returnFalse - type: label-element - - disableUnselect: true - fetch: getAdminOptions|databases/Cassandra/versions - if: isToggleOn|databases/Cassandra/versions - label: - text: labels.database.version - schema: - $ref: schema#/properties/spec/properties/admin/properties/databases/properties/Cassandra/properties/versions/properties/default - type: select - - computed: getDefault|databases/Cassandra/mode - fetch: getAdminOptions|databases/Cassandra/mode - hasDescription: true - if: isToggleOn|databases/Cassandra/mode - label: - text: labels.database.mode - onChange: toggleTls - schema: - $ref: schema#/properties/spec/properties/mode - type: radio - - if: isEqualToModelPathValue|Topology|/spec/mode - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/replicas - type: input - - elements: - - computed: setMachineToCustom - customClass: mt-10 - fetch: getMachineListForOptions - label: - text: labels.machine - schema: - $ref: schema#/properties/spec/properties/podResources/properties/machine +step: +- type: single-step-form + loader: initBundle + elements: + - type: label-element + label: '' + subtitle: Select the Cassandra version you want to deploy on Kubernetes. The chosen version determines the Cassandra engine features, compatibility, and runtime behavior of your distributed database cluster. + - disableUnselect: true + loader: getAdminOptions|databases/Cassandra/versions + if: + type: function + name: isToggleOn|databases/Cassandra/versions + label: Database version + schema: schema/properties/spec/properties/admin/properties/databases/properties/Cassandra/properties/versions/properties/default + type: select + - init: + type: func + value: getDefault|databases/Cassandra/mode + loader: getAdminOptions|databases/Cassandra/mode + if: + type: function + name: isToggleOn|databases/Cassandra/mode + label: Database mode + isHorizontal: true + watcher: + func: toggleTls + paths: + - schema/properties/spec/properties/mode + schema: schema/properties/spec/properties/mode + type: radio + - if: + type: function + name: isEqualToModelPathValue|Topology|/spec/mode + label: Replicaset number + schema: schema/properties/spec/properties/replicas + type: input + - elements: + - type: label-element + label: '' + subtitle: Select a machine profile to allocate CPU and memory resources for your database. Choose 'custom' to manually specify resource requirements or select a predefined profile. + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/podResources/properties/machine type: select - - computed: setLimits|cpu - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.cpu - onChange: setRequests|cpu - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - init: + type: func + value: setLimits|cpu + if: + type: function + name: isMachineCustom + label: cpu + watcher: + func: setRequests|cpu + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu type: input - - computed: setLimits|memory - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.memory - onChange: setRequests|memory - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + - init: + type: func + value: setLimits|memory + if: + type: function + name: isMachineCustom + label: memory + watcher: + func: setRequests|memory + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory type: input - label: - text: labels.machine_profile - show_label: true - type: single-step-form + label: Machine profile + showLabels: true + type: block-layout + - elements: + - type: label-element + label: '' + subtitle: Define rack names to organize your Cassandra nodes into racks for improved fault tolerance and data distribution. Each rack represents a group of nodes that share similar characteristics, such as physical location or network topology. + - type: array-item-form + element: + label: Rack names + type: input + validation: + type: custom + name: validateRackName + label: Rack name + schema: schema/properties/spec/properties/topology/properties/racks + if: + type: function + name: isEqualToModelPathValue|Topology|/spec/mode + label: Topology + showLabels: true + type: block-layout + - type: horizontal-layout + showLabels: true + elements: + - loader: getAdminOptions|storageClasses + if: + type: function + name: isToggleOn|storageClasses + label: Storage class + schema: schema/properties/spec/properties/admin/properties/storageClasses/properties/default + type: select + - label: Storage size + schema: schema/properties/spec/properties/persistence/properties/size + type: input + - description: Configure Credentials, Deployment Mode etc. + elements: - elements: - - element: - label: - isSubsection: true - text: Rack names - schema: - $ref: schema#/properties/spec/properties/topology/properties/racks/items - type: input - validationRuleObject: - errorText: The value must start with a letter, can include letters, numbers, - hyphens (-), and underscores (_). - regex: ^[A-Za-z][A-Za-z0-9_-]*[A-Za-z0-9]$ - label: - text: Rack name - required: true - schema: - $ref: schema#/properties/spec/properties/topology/properties/racks - type: list-input-form - if: isEqualToModelPathValue|Topology|/spec/mode - label: - text: Topology - show_label: true - type: single-step-form - - fetch: getAdminOptions|storageClasses - if: isToggleOn|storageClasses - label: - text: labels.storage.class - schema: - $ref: schema#/properties/spec/properties/admin/properties/storageClasses/properties/default + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/annotations + label: Labels & Annotations + showLabels: true + hideBlock: true + type: block-layout + - init: + type: func + value: getDefault|deletionPolicy + customClass: mt-20 + if: + type: function + name: isToggleOn|deletionPolicy + label: Deletion Policy + watcher: + func: setStorageClass + paths: + - schema/properties/spec/properties/deletionPolicy + options: + - description: options.deletionPolicy.delete.description + text: Delete + value: Delete + - description: options.deletionPolicy.halt.description + text: Halt + value: Halt + - description: options.deletionPolicy.wipeOut.description + text: WipeOut + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: DoNotTerminate + value: DoNotTerminate + schema: schema/properties/spec/properties/deletionPolicy + type: select + - if: + type: function + name: getDefaultValue|spec/admin/authCredential/customize + label: Provide Authentication Credentials? + watcher: + func: onAuthChange + paths: + - temp/createAuthSecret + schema: temp/createAuthSecret + type: switch + - if: + type: function + name: showReferSecretSwitch + label: Refer existing Secret? + watcher: + func: onReferSecretChange + paths: + - temp/referSecret + schema: temp/referSecret + type: switch + - loader: getReferSecrets + if: + type: function + name: showSecretDropdown + label: Secret + schema: schema/properties/spec/properties/authSecret/properties/name type: select - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/persistence/properties/size + - if: + type: function + name: showReferSecret + label: password + schema: schema/properties/spec/properties/authSecret/properties/password type: input - - accordion: true - description: - text: Configure Credentials, Deployment Mode etc. - discriminator: - configDatabase: - default: false - type: boolean - createAuthSecret: - default: false - type: boolean - referSecret: - default: false - type: boolean - elements: - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties - type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties - type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - computed: getDefault|deletionPolicy - customClass: mt-20 - if: isToggleOn|deletionPolicy - 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/spec/properties/deletionPolicy - type: select - - if: getDefaultValue|spec/admin/authCredential/customize - label: - text: Provide Authentication Credentials? - onChange: onAuthChange - schema: - $ref: discriminator#/createAuthSecret - type: switch - - if: showReferSecretSwitch - label: - text: Refer existing Secret? - onChange: onReferSecretChange - schema: - $ref: discriminator#/referSecret - type: switch - - fetch: getReferSecrets - if: showSecretDropdown - label: - text: Secret - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/name - type: select - - if: showReferSecret - label: - text: labels.password - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/password - type: input - - computed: isConfigAvailable - if: getDefaultValue|spec/admin/customConfiguration - label: - text: Configure Database? - onChange: clearConfiguration - schema: - $ref: discriminator#/configDatabase + - if: + type: function + name: getDefaultValue|spec/admin/customConfiguration + label: Configure Database? + watcher: + func: clearConfiguration + paths: + - temp/configDatabase + schema: temp/configDatabase + type: switch + - if: + type: function + name: isConfigDatabaseOn + label: Configuration + # hasCopy: true + schema: schema/properties/spec/properties/configuration + type: textarea + - if: + type: function + name: isToggleOn|deployment + label: Deployment name + options: + - description: labels.deployment.shared + text: Shared + value: Shared + - description: labels.deployment.dedicated + text: Dedicated + value: Dedicated + schema: schema/properties/spec/properties/admin/properties/deployment/properties/default + type: radio + - if: + type: function + name: isToggleOn|clusterTier + isHorizontal: true + label: Cluster Tier + options: + - text: General Purpose + value: GeneralPurpose + - text: Memory Optimized + value: MemoryOptimized + - text: CPU Optimized + value: CPUOptimized + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/default + type: radio + - disableUnselect: true + loader: getAdminOptions|clusterTier/placement + if: + type: function + name: isToggleOn|clusterTier/placement + label: Placement + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + type: select + - disableUnselect: true + loader: getNodeTopology + if: + type: function + name: isToggleOn|clusterTier/nodeTopology + label: Node Topology + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + type: select + label: Advanced Configuration + showLabels: true + type: block-layout + - description: Enable Backup, Monitoring, TLS etc. + elements: + - elements: + - init: + type: func + value: setMonitoring + label: Enable Monitoring? + watcher: + func: updateAlertValue + paths: + - temp/monitoring + schema: temp/monitoring type: switch - - if: isConfigDatabaseOn - label: - text: Configuration - schema: - $ref: schema#/properties/spec/properties/configuration - type: editor - - hasDescription: true - if: isToggleOn|deployment - label: - text: labels.deployment.name + - customClass: mt-10 + if: + type: function + name: showAlerts + label: Alert Options options: - - description: labels.deployment.shared - text: Shared - value: Shared - - description: labels.deployment.dedicated - text: Dedicated - value: Dedicated - schema: - $ref: schema#/properties/spec/properties/admin/properties/deployment/properties/default - type: radio - - if: isToggleOn|clusterTier - isHorizontal: true - label: - text: labels.clusterTier - options: - - text: General Purpose - value: GeneralPurpose - - text: Memory Optimized - value: MemoryOptimized - - text: CPU Optimized - value: CPUOptimized - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/default - type: radio - - disableUnselect: true - fetch: getAdminOptions|clusterTier/placement - if: isToggleOn|clusterTier/placement - label: - text: labels.placement - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default - type: select - - disableUnselect: true - fetch: getNodeTopology - if: isToggleOn|clusterTier/nodeTopology - label: - text: labels.nodeTopology - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + - text: None + value: none + - text: Critical + value: critical + - text: Warning + value: warning + - text: Info + value: info + schema: schema/properties/form/properties/alert/properties/enabled type: select - hideForm: true - label: - text: Advanced Configuration - show_label: true - type: single-step-form - - accordion: true - description: - text: Enable Backup, Monitoring, TLS etc. - discriminator: - backup: - default: false - type: boolean - elements: - - discriminator: - monitoring: - default: false - type: boolean - elements: - - computed: setMonitoring - label: - text: labels.enable_monitoring - onChange: updateAlertValue - schema: - $ref: discriminator#/monitoring - type: switch - - customClass: mt-10 - if: showAlerts - label: - text: labels.alert.options - options: - - text: None - value: none - - text: Critical - value: critical - - text: Warning - value: warning - - text: Info - value: info - schema: - $ref: schema#/properties/form/properties/alert/properties/enabled - sortable: true - type: select - if: isToggleOn|monitoring - type: single-step-form - - computed: setBackup - if: isToggleOn|backup - label: - text: Enable Backup? - onChange: onBackupSwitch - schema: - $ref: discriminator#/backup - type: switch - - elements: - - computed: toggleTls - label: - text: Enable TLS? - schema: - $ref: schema#/properties/spec/properties/admin/properties/tls/properties/default - type: switch - - fetch: getAdminOptions|clusterIssuers - if: showIssuer - label: - text: labels.clusterIssuers - required: true - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterIssuers/properties/default - type: select - if: isEqualToModelPathValue|Topology|/spec/mode - type: single-step-form - - if: isToggleOn|expose - label: - text: Expose via Gateway? - schema: - $ref: schema#/properties/spec/properties/admin/properties/expose/properties/default + if: + type: function + name: isToggleOn|monitoring + type: block-layout + - init: + type: func + value: setBackup + if: + type: function + name: isToggleOn|backup + label: Enable Backup? + watcher: + func: onBackupSwitch + paths: + - temp/backup + schema: temp/backup + type: switch + - elements: + - init: + type: func + value: toggleTls|true + label: Enable TLS? + schema: schema/properties/spec/properties/admin/properties/tls/properties/default type: switch - if: showAdditionalSettings - label: - text: Additional Options - show_label: true - type: single-step-form - type: single-step-form + - loader: getAdminOptions|clusterIssuers + if: + type: function + name: showIssuer + label: Cluster Issuers + validation: + type: required + schema: schema/properties/spec/properties/admin/properties/clusterIssuers/properties/default + type: select + if: + type: function + name: isEqualToModelPathValue|Topology|/spec/mode + type: block-layout + - if: + type: function + name: isToggleOn|expose + label: Expose via Gateway? + schema: schema/properties/spec/properties/admin/properties/expose/properties/default + type: switch + if: + type: function + name: showAdditionalSettings + label: Additional Options + showLabels: true + type: block-layout id: options - title: steps.0.label + # title: steps.0.label type: multi-step-form diff --git a/charts/kubedbcom-cassandra-editor-options/ui/functions.js b/charts/kubedbcom-cassandra-editor-options/ui/functions.js index e9111a3411..2c5ffe3146 100644 --- a/charts/kubedbcom-cassandra-editor-options/ui/functions.js +++ b/charts/kubedbcom-cassandra-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -315,1063 +317,892 @@ const modeDetails = { }, } -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} - -function showAuthSecretField({ discriminator, getValue, watchDependency }) { - return !showAuthPasswordField({ - discriminator, - getValue, - watchDependency, - }) -} +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) -async function getResources({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + setDiscriminatorValue('bundleApiLoaded', false) + setDiscriminatorValue('configDatabase', false) + setDiscriminatorValue('createAuthSecret', false) + setDiscriminatorValue('referSecret', false) + setDiscriminatorValue('backup', false) + setDiscriminatorValue('monitoring', false) + + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + async function getReferSecrets() { + const referSecret = getValue(discriminator, '/referSecret') + if (!referSecret) { + return [] + } - const resources = (resp && resp.data && resp.data.items) || [] + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/metadata/release/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return resources -} + const options = [] + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + return options + } -async function getMySqlVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function showReferSecret() { + const modelPathValue = getValue(discriminator, '/createAuthSecret') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue + } - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, - }, - }, + function showSecretDropdown() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !!modelPathValue && showReferSecret() } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) + function showReferSecretSwitch() { + const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue && showReferSecret() + } - const resources = (resp && resp.data && resp.data.items) || [] + function onReferSecretChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + } - // keep only non deprecated versions - const filteredMySqlVersions = resources.filter((item) => item.spec && !item.spec.deprecated) + let array = [] + function getMachineListForOptions() { + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') - filteredMySqlVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredMySqlVersions -} + if (available.length) { + array = available.map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + else { + let subText = '', + text = '' + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + text = machineData.name ? machineData.name : machineData.id + } + return { text, subText, value: machine } + } + }) + } else { + array = machineList + .map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { text, subText, value: machine } + }) + .filter((val) => !!val) + } + return array + } -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/spec/authSecret/name') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/spec/authSecret/password') + function setMachineToCustom() { + const machine = getValue(model, '/spec/admin/machineProfiles/default') + return machine || 'custom' } -} -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') + function isMachineCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue === 'custom' + } - if (owner && cluster && namespace) { - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { - items: { - data: { username: null, password: null }, - metadata: { name: null }, - type: null, - }, - }, - }, - }, - ) + function isMachineNotCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue !== 'custom' && !!modelPathValue + } - const secrets = (resp && resp.data && resp.data.items) || [] + function setLimits(resource, type) { + const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' + // watchDependency(`model#${path}`) + const selectedMachine = getValue(model, path) || 'custom' + const reqCommitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + const comparePath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + + const resourceValue = getValue(model, comparePath) + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + let cpu = '', + memory = '' + if (available.length && selectedMachine !== 'custom') { + const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) + if (machineData) { + cpu = machineData.limits.cpu + memory = machineData.limits.memory + } + } else { + if (selectedMachine === 'custom') { + cpu = resourceValue + memory = resourceValue + } else { + cpu = machines[selectedMachine].resources.limits.cpu + memory = machines[selectedMachine].resources.limits.memory + } + } - const filteredSecrets = secrets.filter((item) => { - const validType = [ - 'kubernetes.io/service-account-token', - 'Opaque', - 'kubernetes.io/basic-auth', - ] - return validType.includes(item.type) + if (resource === 'memory') { + commit('wizard/model$update', { + path: reqCommitPath, + value: memory, + force: true, }) - - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + commit('wizard/model$update', { + path: comparePath, + value: memory, + force: true, }) - return filteredSecrets - } catch (e) { - console.log(e) + return memory + } else { + commit('wizard/model$update', { + path: reqCommitPath, + value: cpu, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: cpu, + force: true, + }) + return cpu } } - return [] -} -function getMachineListForOptions({ model, getValue }) { - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - let array = [] + function setRequests(resource, type) { + const modelPath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + + const fullpath = `/spec/podResources/machine` + const modelPathValue = getValue(model, fullpath) - if (available.length) { - array = available.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - else { - let subText = '', - text = '' - const machineData = machinesFromPreset.find((val) => val.id === machine) - if (machineData) { - subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` - text = machineData.name ? machineData.name : machineData.id + commit('wizard/model$update', { + path: commitPath, + value: val, + force: true, + }) + + if (modelPathValue === 'custom') { + return + } + let commitCpuMemory, ModelPathValue + if (resource && type) { + const fullPath = `/spec/${type}/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/${type}/podResources/resources/requests/${resource}` + } else { + const fullPath = `/spec/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/podResources/resources/requests/${resource}` + } + let cpuMemoryValue + array.forEach((item) => { + if (item.value === ModelPathValue) { + // Parse subText like "CPU: 2, Memory: 2Gi" + const subText = item.subText || '' + if (resource === 'cpu') { + // Extract CPU value + const cpuMatch = subText.match(/CPU:\s*([^,]+)/) + cpuMemoryValue = cpuMatch ? cpuMatch[1].trim() : '' + } else if (resource === 'memory') { + // Extract Memory value + const memoryMatch = subText.match(/Memory:\s*(.+)/) + cpuMemoryValue = memoryMatch ? memoryMatch[1].trim() : '' } - return { text, subText, value: machine } } }) - } else { - array = machineList - .map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } - }) - .filter((val) => !!val) + commit('wizard/model$update', { + path: commitCpuMemory, + value: cpuMemoryValue, + force: true, + }) + return cpuMemoryValue } - return array -} - -function setMachineToCustom({ getValue, model }) { - const machine = getValue(model, '/spec/admin/machineProfiles/default') - return machine || 'custom' -} -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) + function validateRackName() { + // watchDependency('model#/spec/topology/racks') + const regex = /^[A-Za-z][A-Za-z0-9_-]*[A-Za-z0-9]$/ + const racks = getValue(model, '/spec/topology/racks') || [] + for (let rack of racks) { + if (!regex.test(rack)) { + return 'The value must start with a letter, can include letters, numbers, hyphens (-), and underscores (_).' + } + } + return true } - return { - ui: ui.data || {}, - language: language.data || {}, - functions, + function updateAlertValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const alert = isMonitorEnabled ? 'warning' : 'none' + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: alert, + force: true, + }) + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: agent, + force: true, + }) } -} -function updateAgentValue({ commit }, val) { - commit('wizard/model$update', { - path: '/spec/monitoring/agent', - value: val ? 'prometheus.io/operator' : '', - force: true, - }) - - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: val ? 'warning' : 'none', - force: true, - }) -} - -function setReplicaNumber({ model, getValue }) { - const modelPathValue = getValue(model, '/spec/mode') - if (modelPathValue === 'Topology') { - return 2 - } else return 1 -} -function setRouterNumber({ model, getValue }) { - const modelPathValue = getValue(model, '/spec/mode') - if (modelPathValue === 'Topology') { - return 3 - } else return 1 -} - -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function getCreateNameSpaceUrl() { + 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + const domain = storeGet('/domain') || '' + if (domain.includes('bb.test')) { + return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } } -} -const ifCapiProviderIsNotEmpty = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/provider') - const val = getValue(model, '/form/capi/provider') - if (val) return true -} - -const showMultiselectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') + const ifCapiProviderIsNotEmpty = () => { + // watchDependency('model#/form/capi/provider') + const val = getValue(model, '/form/capi/provider') + if (val) return true + } - if (val === 'capz' && ifDedicated({ model, getValue })) return true -} + const showMultiselectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') -const showSelectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') - if (val !== 'capz' && ifDedicated({ model, getValue })) return true -} + if (val === 'capz' && ifDedicated()) return true + } -const ifDedicated = ({ model, getValue }) => { - const val = getValue(model, 'form/capi/dedicated') - if (val) return true -} + const showSelectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') + if (val !== 'capz' && ifDedicated()) return true + } -const dedicatedOnChange = ({ model, getValue, commit }) => { - const val = getValue(model, 'form/capi/dedicated') - if (!val) { - commit('wizard/model$delete', 'form/capi/zones') - commit('wizard/model$delete', 'form/capi/sku') + const ifDedicated = () => { + const val = getValue(model, 'form/capi/dedicated') + if (val) return true } -} -const ifZones = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/zones') - watchDependency('model#/form/capi/dedicated') - const zones = getValue(model, 'form/capi/zones') || [] - const isDedicated = getValue(model, 'form/capi/dedicated') - if (zones.length && isDedicated) return true -} + const dedicatedOnChange = () => { + const val = getValue(model, 'form/capi/dedicated') + if (!val) { + commit('wizard/model$delete', 'form/capi/zones') + commit('wizard/model$delete', 'form/capi/sku') + } + } -const zonesOnChange = ({ model, getValue, commit }) => { - const zones = getValue(model, 'form/capi/zones') || [] - if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') -} + const ifZones = () => { + // watchDependency('model#/form/capi/zones') + // watchDependency('model#/form/capi/dedicated') + const zones = getValue(model, 'form/capi/zones') || [] + const isDedicated = getValue(model, 'form/capi/dedicated') + if (zones.length && isDedicated) return true + } -async function getZones({ storeGet, axios, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const isDedicated = getValue(model, 'form/capi/dedicated') - if (isDedicated) { - try { - const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) - const val = resp.data.map((item) => { - return { value: item, text: item } - }) - return val - } catch (e) { - console.log(e) - return [] - } + const zonesOnChange = () => { + const zones = getValue(model, 'form/capi/zones') || [] + if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') } -} -async function getSKU({ storeGet, axios, model, getValue, watchDependency }) { - watchDependency('model#/form/capi/zones') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const zones = getValue(model, 'form/capi/zones') || [] - if (zones.length) { - try { - let url = `clustersv2/${owner}/${cluster}/vms?` - if (typeof zones === 'string') { - url += `zones=${encodeURIComponent(zones)}` - } else { - zones.forEach((item) => { - url += `zones=${encodeURIComponent(item)}&` + async function getZones() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const isDedicated = getValue(model, 'form/capi/dedicated') + if (isDedicated) { + try { + const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) + const val = resp.data.map((item) => { + return { value: item, text: item } }) - url = url.slice(0, -1) + return val + } catch (e) { + console.log(e) + return [] } - const resp = await axios.get(url) - const val = resp.data.map((item) => { - return { - value: item.name, - text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, - } - }) - return val - } catch (e) { - console.log(e) - return [] } } -} -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} - -function setStorageClass({ model, getValue, commit, discriminator, watchDependency }) { - const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' - let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' - const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] - const suffix = '-retain' - - const simpleClassList = storageClassList.filter((item) => { - return !item.endsWith(suffix) - }) - const retainClassList = storageClassList.filter((item) => { - return item.endsWith(suffix) - }) - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] - } else { - storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + async function getSKU() { + // watchDependency('model#/form/capi/zones') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const zones = getValue(model, 'form/capi/zones') || [] + if (zones.length) { + try { + let url = `clustersv2/${owner}/${cluster}/vms?` + if (typeof zones === 'string') { + url += `zones=${encodeURIComponent(zones)}` + } else { + zones.forEach((item) => { + url += `zones=${encodeURIComponent(item)}&` + }) + url = url.slice(0, -1) + } + const resp = await axios.get(url) + const val = resp.data.map((item) => { + return { + value: item.name, + text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb]`, + } + }) + return val + } catch (e) { + console.log(e) + return [] + } + } } - const isChangeable = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'storageClasses', - ) - if (isChangeable && storageClass) { - commit('wizard/model$update', { - path: '/spec/admin/storageClasses/default', - value: storageClass, - force: true, - }) + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false } -} -function showAlerts({ watchDependency, model, getValue, discriminator }) { - watchDependency('discriminator#/monitoring') - const isMonitorEnabled = getValue(discriminator, '/monitoring') - return ( - isMonitorEnabled && isToggleOn({ getValue, model, discriminator, watchDependency }, 'alert') - ) -} + function setStorageClass() { + const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' + let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' + const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] + const suffix = '-retain' -function onBackupSwitch({ discriminator, getValue, commit }) { - const isBackupOn = getValue(discriminator, '/backup') - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: isBackupOn ? 'KubeStash' : '', - force: true, - }) -} + const simpleClassList = storageClassList.filter((item) => { + return !item.endsWith(suffix) + }) + const retainClassList = storageClassList.filter((item) => { + return item.endsWith(suffix) + }) -function clearArbiterHidden({ commit }) { - commit('wizard/model$update', { - path: `/spec/arbiter/enabled`, - value: false, - force: true, - }) - - commit('wizard/model$update', { - path: `/spec/hidden/enabled`, - value: false, - force: true, - }) -} + if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { + storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] + } else { + storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + } -let placement = [] -let versions = [] -let storageClass = [] -let clusterIssuers = [] -let nodetopologiesShared = [] -let nodetopologiesDedicated = [] -let features = [] -async function initBundle({ commit, model, getValue, axios, storeGet, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - - let db = getValue(model, '/metadata/resource/kind') - db = db.toLowerCase() - let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` - const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - - try { - const resp = await axios.get(url) - features = resp.data.features || [] - placement = resp.data.placementpolicies || [] - versions = resp.data.versions || [] - storageClass = resp.data.storageclasses || [] - clusterIssuers = resp.data.clusterissuers || [] - nodetopologiesDedicated = resp.data.dedicated || [] - nodetopologiesShared = resp.data.shared || [] - - const response = await axios.get(annotationUrl) - const annotations = response.data?.metadata?.annotations || {} - const uidRange = annotations['openshift.io/sa.scc.uid-range'] - if (uidRange) { - const val = uidRange.split('/')[0] + const isChangeable = isToggleOn('storageClasses') + if (isChangeable && storageClass) { commit('wizard/model$update', { - path: '/spec/openshift/securityContext/runAsUser', - value: val, + path: '/spec/admin/storageClasses/default', + value: storageClass, force: true, }) } - } catch (e) { - console.log(e) } - commit('wizard/model$update', { - path: '/spec/deletionPolicy', - value: getDefault({ getValue, model }, 'deletionPolicy'), - force: true, - }) - - if (!getValue(model, `/spec/admin/databases/Cassandra/mode/toggle`)) { - let defMode = getDefault({ getValue, model }, 'databases/Cassandra/mode') || '' - if (defMode === '') { - const arr = getValue(model, '/spec/databases/Cassandra/mode/available') || [] - if (arr.length) defMode = arr[0] - } - commit('wizard/model$update', { - path: '/spec/mode', - value: defMode, - force: true, - }) + function isConfigDatabaseOn() { + // watchDependency('discriminator#/configDatabase') + return getValue(discriminator, '/configDatabase') } - if (!features.includes('tls')) { - commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: false, - force: true, - }) - } - if (!features.includes('binding')) { - commit('wizard/model$update', { - path: '/spec/admin/expose/default', - value: false, - force: true, - }) - } - if (!features.includes('monitoring')) { - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: 'none', - force: true, - }) + function clearConfiguration() { + const configOn = getValue(discriminator, '/configDatabase') + + if (!configOn) { + commit('wizard/model$delete', '/spec/configuration') + } } - if (!features.includes('backup')) { - commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, - force: true, - }) - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: '', - force: true, - }) + + function returnFalse() { + return false } - setDiscriminatorValue('/bundleApiLoaded', true) -} + let placement = [] + let versions = [] + let storageClass = [] + let clusterIssuers = [] + let nodetopologiesShared = [] + let nodetopologiesDedicated = [] + let features = [] + let namespaces = [] + async function initBundle() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + let db = getValue(model, '/metadata/resource/kind') + db = db.toLowerCase() + let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` + const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` -function fetchOptions({ model, getValue, commit }, type) { - let kind = getValue(model, '/metadata/resource/kind') - - let returnArray = [] - if (type === 'clusterTier/placement') { - returnArray = placement - } else if (type === `databases/${kind}/versions`) { - returnArray = versions - } else if (type === 'storageClasses') { - returnArray = storageClass - } else if (type === 'clusterIssuers') { - returnArray = clusterIssuers - } + try { + const resp = await axios.get(url) + features = resp.data.features || [] + placement = resp.data.placementpolicies || [] + versions = resp.data.versions || [] + storageClass = resp.data.storageclasses || [] + clusterIssuers = resp.data.clusterissuers || [] + nodetopologiesDedicated = resp.data.dedicated || [] + nodetopologiesShared = resp.data.shared || [] + + const response = await axios.get(annotationUrl) + const annotations = response.data?.metadata?.annotations || {} + const uidRange = annotations['openshift.io/sa.scc.uid-range'] + if (uidRange) { + const val = uidRange.split('/')[0] + commit('wizard/model$update', { + path: '/spec/openshift/securityContext/runAsUser', + value: val, + force: true, + }) + } + } catch (e) { + console.log(e) + } - if (returnArray.length === 1) { - const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: path, - value: returnArray[0], + path: '/spec/deletionPolicy', + value: getDefault('deletionPolicy'), force: true, }) - } - - return returnArray -} -function getAdminOptions({ getValue, model, watchDependency, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') + if (!getValue(model, `/spec/admin/databases/Cassandra/mode/toggle`)) { + let defMode = getDefault('databases/Cassandra/mode') || '' + if (defMode === '') { + const arr = getValue(model, '/spec/databases/Cassandra/mode/available') || [] + if (arr.length) defMode = arr[0] + } + commit('wizard/model$update', { + path: '/spec/mode', + value: defMode, + force: true, + }) + } - const options = getValue(model, `/spec/admin/${type}/available`) || [] + if (!features.includes('tls')) { + commit('wizard/model$update', { + path: '/spec/admin/tls/default', + value: false, + force: true, + }) + } + if (!features.includes('binding')) { + commit('wizard/model$update', { + path: '/spec/admin/expose/default', + value: false, + force: true, + }) + } + if (!features.includes('monitoring')) { + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: 'none', + force: true, + }) + } + if (!features.includes('backup')) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: '', + force: true, + }) + } - if (options.length === 0) { - return fetchOptions({ model, getValue, commit }, type) - } - if (type.endsWith('/mode')) { - return ( - options?.map((item) => ({ - description: modeDetails[item]?.description || '', - text: modeDetails[item]?.text || '', - value: item, - })) || [] - ) + namespaces = getNamespaces() + setDiscriminatorValue('/bundleApiLoaded', true) } - return options -} -function checkIfFeatureOn({ getValue, model }, type) { - let val = getValue(model, `/spec/admin/${type}/toggle`) - if (type === 'backup' || type === 'archiver') { - val = getValue(model, `/spec/admin/${type}/enable/toggle`) - } - const backupVal = getValue(model, '/spec/backup/tool') - - if (type === 'backup') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } else if (type === 'tls') { - return features.includes('tls') && val - } else if (type === 'expose') { - return features.includes('binding') && val - } else if (type === 'monitoring') { - return features.includes('monitoring') && val - } else if (type === 'archiver') { - return features.includes('backup') && backupVal === 'KubeStash' && val + function fetchNamespaces() { + // watchDependency('discriminator#/bundleApiLoaded') + return namespaces } -} -function isToggleOn({ getValue, model, discriminator, watchDependency }, type) { - watchDependency('discriminator#/bundleApiLoaded') - watchDependency('model#/spec/admin/deployment/default') - const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') - let deploymentType = getValue(model, `/spec/admin/deployment/default`) - if ( - type === 'tls' || - type === 'backup' || - type === 'expose' || - type === 'monitoring' || - type === 'archiver' - ) { - return checkIfFeatureOn({ getValue, model }, type) - } else if ( - type === 'clusterTier' || - type === 'clusterTier/placement' || - type === 'clusterTier/nodeTopology' - ) { - if (deploymentType === 'Dedicated' && bundleApiLoaded) return true - else return false - } else if (type === 'deployment') { - const deploymentType = getValue(model, '/spec/admin/deployment/default') - if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + function fetchOptions(type) { + let kind = getValue(model, '/metadata/resource/kind') + + let returnArray = [] + if (type === 'clusterTier/placement') { + returnArray = placement + } else if (type === `databases/${kind}/versions`) { + returnArray = versions + } else if (type === 'storageClasses') { + returnArray = storageClass + } else if (type === 'clusterIssuers') { + returnArray = clusterIssuers + } + + if (returnArray.length === 1) { + const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: '/spec/admin/deployment/default', - value: 'Shared', + path: path, + value: returnArray[0], force: true, }) } - return ( - getValue(model, `/spec/admin/${type}/toggle`) && - nodetopologiesDedicated.length && - bundleApiLoaded - ) - } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded -} -async function getNodeTopology({ model, getValue, axios, storeGet, watchDependency }) { - watchDependency('model#/spec/admin/deployment/default') - watchDependency('model#/spec/admin/clusterTier/default') - const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' - const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' - let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + return returnArray + } - const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + function getAdminOptions(type) { + // watchDependency('discriminator#/bundleApiLoaded') - if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared - else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + const options = getValue(model, `/spec/admin/${type}/available`) || [] - const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) - return filteredList -} + if (options.length === 0) { + return fetchOptions(type) + } + if (type.endsWith('/mode')) { + return ( + options?.map((item) => ({ + description: modeDetails[item]?.description || '', + text: modeDetails[item]?.text || '', + value: item, + })) || [] + ) + } + return options + } + + let backupToolInitialValue = '' + function checkIfFeatureOn(type) { + let val = getValue(model, `/spec/admin/${type}/toggle`) + if (type === 'backup' || type === 'archiver') { + val = getValue(model, `/spec/admin/${type}/enable/toggle`) + } + const backupVal = getValue(model, '/spec/backup/tool') + if (type === 'backup') { + if (backupToolInitialValue === '') { + backupToolInitialValue = + features.includes('backup') && backupVal === 'KubeStash' && val ? 'on' : 'off' + return features.includes('backup') && backupVal === 'KubeStash' && val + } else { + if (backupToolInitialValue === 'on') { + return true + } else { + return false + } + } + } else if (type === 'tls') { + return features.includes('tls') && val + } else if (type === 'expose') { + return features.includes('binding') && val + } else if (type === 'monitoring') { + return features.includes('monitoring') && val + } else if (type === 'archiver') { + return features.includes('backup') && val + } + } + + function isToggleOn(type) { + // watchDependency('discriminator#/bundleApiLoaded') + // watchDependency('model#/spec/admin/deployment/default') + const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') + let deploymentType = getValue(model, `/spec/admin/deployment/default`) + if (type === 'tls' || type === 'backup' || type === 'expose' || type === 'monitoring') { + return checkIfFeatureOn(type) + } else if ( + type === 'clusterTier' || + type === 'clusterTier/placement' || + type === 'clusterTier/nodeTopology' + ) { + if (deploymentType === 'Dedicated' && bundleApiLoaded) return true + else return false + } else if (type === 'deployment') { + const deploymentType = getValue(model, '/spec/admin/deployment/default') + if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + commit('wizard/model$update', { + path: '/spec/admin/deployment/default', + value: 'Shared', + force: true, + }) + } + return ( + getValue(model, `/spec/admin/${type}/toggle`) && + nodetopologiesDedicated.length && + bundleApiLoaded + ) + } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded + } -function filterNodeTopology(list, tier, provider) { - // first filter the list from value that exists from the filtered list got from API - const filteredlist = list + function showAlerts() { + // watchDependency('discriminator#/monitoring') + const isMonitorEnabled = getValue(discriminator, '/monitoring') + return isMonitorEnabled && isToggleOn('alert') + } - // filter the list based on clusterTier - if (provider === 'EKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('c') - else if (tier === 'MemoryOptimized') return item.startsWith('r') - else return !item.startsWith('c') && !item.startsWith('r') + function onBackupSwitch() { + const isBackupOn = getValue(discriminator, '/backup') + setDiscriminatorValue('/isBackupToggleOn', true) + console.log('Backup toggle is changed to ON/OFF. Updating backup tool to KubeStash/empty.') + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: isBackupOn ? 'KubeStash' : '', + force: true, }) - } else if (provider === 'AKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - else - return ( - !(item.startsWith('f') || item.startsWith('fx')) && - !( + } + + async function getNodeTopology() { + // watchDependency('model#/spec/admin/deployment/default') + // watchDependency('model#/spec/admin/clusterTier/default') + const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' + const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' + let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + + const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + + if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared + else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + + const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) + return filteredList + } + + function filterNodeTopology(list, tier, provider) { + // first filter the list from value that exists from the filtered list got from API + const filteredlist = list + + // filter the list based on clusterTier + if (provider === 'EKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('c') + else if (tier === 'MemoryOptimized') return item.startsWith('r') + else return !item.startsWith('c') && !item.startsWith('r') + }) + } else if (provider === 'AKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('e') || item.startsWith('eb') || item.startsWith('ec') || item.startsWith('m') || item.startsWith('d') ) - ) - }) - } else if (provider === 'GKE') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') - return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - else - return ( - !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && - !( + else + return ( + !(item.startsWith('f') || item.startsWith('fx')) && + !( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + ) + }) + } else if (provider === 'GKE') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') + return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('x4') || item.startsWith('m1') || item.startsWith('m2') || item.startsWith('m3') ) - ) - }) - } else return filteredlist -} - -function returnFalse() { - return false -} - -function isConfigDatabaseOn({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configDatabase') - return getValue(discriminator, '/configDatabase') -} -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} -function showStorageSizeField({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - const validType = [] - return !validType.includes(modelPathValue) -} -function showHidden({ watchDependency, model, getValue }) { - watchDependency('model#/spec/hidden/enabled') - const isHiddenOn = getValue(model, '/spec/hidden/enabled') || '' - const notStandalone = notEqualToDatabaseMode({ model, getValue, watchDependency }, 'Standalone') - return isHiddenOn && notStandalone -} -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} -function showArbiter({ watchDependency, model, getValue }) { - watchDependency('model#/spec/arbiter/enabled') - const isArbiterOn = getValue(model, '/spec/arbiter/enabled') || '' - const notStandalone = notEqualToDatabaseMode({ model, getValue, watchDependency }, 'Standalone') - return isArbiterOn && notStandalone -} -function clearConfiguration({ discriminator, getValue, commit }) { - const configOn = getValue(discriminator, '/configDatabase') - - if (!configOn) { - commit('wizard/model$delete', '/spec/configuration') + else + return ( + !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && + !( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + ) + }) + } else return filteredlist } -} - -function showIssuer({ model, getValue, watchDependency, discriminator }) { - watchDependency('model#/spec/admin/tls/default') - const isTlsEnabled = getValue(model, '/spec/admin/tls/default') - const isIssuerToggleEnabled = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'clusterIssuers', - ) - return isTlsEnabled && isIssuerToggleEnabled -} -function onAuthChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/authSecret/password', - value: '', - force: true, - }) -} -function setMonitoring({ getValue, model }) { - const agent = getValue(model, '/spec/admin/monitoring/agent') || '' - return !!agent -} -function setBackup({ model, getValue }) { - const backup = getValue(model, '/spec/backup/tool') - const val = getValue(model, '/spec/admin/backup/enable/default') - return backup === 'KubeStash' && features.includes('backup') && val -} - -function isMachineCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue === 'custom' -} - -function isMachineNotCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue !== 'custom' && !!modelPathValue -} -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], - }, - }, - ) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] - } - } catch (e) { - console.log(e) + function showIssuer() { + // watchDependency('model#/spec/admin/tls/default') + const isTlsEnabled = getValue(model, '/spec/admin/tls/default') + const isIssuerToggleEnabled = isToggleOn('clusterIssuers') + return isTlsEnabled && isIssuerToggleEnabled } - return [] -} - -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} -function updateAlertValue({ commit, model, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const alert = isMonitorEnabled ? 'warning' : 'none' - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: alert, - force: true, - }) - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} + function setMonitoring() { + const agent = getValue(model, '/spec/admin/monitoring/agent') || '' + return !!agent + } -function setLimits({ model, getValue, commit, watchDependency }, resource, type) { - const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' - watchDependency(`model#${path}`) - const selectedMachine = getValue(model, path) || 'custom' - const reqCommitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - const comparePath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - - const resourceValue = getValue(model, comparePath) - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - - let cpu = '', - memory = '' - if (available.length && selectedMachine !== 'custom') { - const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) - if (machineData) { - cpu = machineData.limits.cpu - memory = machineData.limits.memory - } - } else { - if (selectedMachine === 'custom') { - cpu = resourceValue - memory = resourceValue - } else { - cpu = machines[selectedMachine].resources.limits.cpu - memory = machines[selectedMachine].resources.limits.memory - } + function setBackup() { + const backup = getValue(model, '/spec/backup/tool') + const val = getValue(model, '/spec/admin/backup/enable/default') + return backup === 'KubeStash' && features.includes('backup') && val } - if (resource === 'memory') { + function onAuthChange() { commit('wizard/model$update', { - path: reqCommitPath, - value: memory, + path: '/spec/authSecret/name', + value: '', force: true, }) commit('wizard/model$update', { - path: comparePath, - value: memory, + path: '/spec/authSecret/password', + value: '', force: true, }) - return memory - } else { + } + + function showAdditionalSettings() { + // watchDependency('discriminator#/bundleApiLoaded') + return features.length + } + + function toggleTls(isTlsInit) { + let modelPathValue = getValue(model, '/spec/mode') commit('wizard/model$update', { - path: reqCommitPath, - value: cpu, + path: '/spec/admin/tls/default', + value: modelPathValue !== 'Standalone', force: true, }) commit('wizard/model$update', { - path: comparePath, - value: cpu, + path: '/spec/admin/tls/toggle', + value: modelPathValue !== 'Standalone', force: true, }) - return cpu + if (isTlsInit) return isTlsInit } -} - -function setRequests({ getValue, model, commit }, resource, type) { - const modelPath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - const val = getValue(model, modelPath) - commitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - commit('wizard/model$update', { - path: commitPath, - value: val, - force: true, - }) -} - -function toggleTls({ commit, model, getValue }) { - let modelPathValue = getValue(model, '/spec/mode') - commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: modelPathValue !== 'Standalone', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/admin/tls/toggle', - value: modelPathValue !== 'Standalone', - force: true, - }) -} - -function showAdditionalSettings({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return features.length -} - -function getDefault({ getValue, model }, type) { - const val = getValue(model, `/spec/admin/${type}/default`) || '' - return val -} -function isConfigAvailable({ getValue, model }) { - const val = getValue(model, '/spec/configuration') - return val !== '' -} - -async function getReferSecrets({ getValue, model, storeGet, axios, discriminator }) { - const referSecret = getValue(discriminator, '/referSecret') - if (!referSecret) { - return [] + function getDefault(type) { + const val = getValue(model, `/spec/admin/${type}/default`) || '' + return val } - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/metadata/release/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - - const options = [] - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) - } catch (e) { - console.log(e) + function getDefaultValue(path) { + const val = getValue(model, `/${path}`) || '' + return val } - return options -} - -function showAuthPasswordField({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} - -function showSecretDropdown({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} -function showReferSecret({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/createAuthSecret') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue -} - -function getDefaultValue({ getValue, model }, path) { - const val = getValue(model, `/${path}`) || '' - return val -} - -function showReferSecretSwitch({ model, getValue, watchDependency, discriminator }) { - const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, + }, + ) + const projects = resp?.data?.status?.projects + if (projects) { + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + namespaces = projectsNamespace + } else { + namespaces = resp?.data?.status?.namespaces || [] + } + return namespaces + } catch (e) { + console.log(e) + return [] + } + } -function onReferSecretChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) -} + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } -return { - showReferSecretSwitch, - onReferSecretChange, - getDefaultValue, - isRancherManaged, - showSecretDropdown, - showReferSecret, - getReferSecrets, - isConfigAvailable, - initBundle, - returnFalse, - setLimits, - setRequests, - toggleTls, - getNamespaces, - updateAlertValue, - getAdminOptions, - isToggleOn, - showAlerts, - getNodeTopology, - clearArbiterHidden, - returnFalse, - showHidden, - isConfigDatabaseOn, - notEqualToDatabaseMode, - filterNodeTopology, - onAuthChange, - setMonitoring, - isMachineNotCustom, - isMachineCustom, - showIssuer, - showArbiter, - clearConfiguration, - showStorageSizeField, - onBackupSwitch, - isVariantAvailable, - fetchJsons, - showAuthPasswordField, - isEqualToModelPathValue, - showAuthSecretField, - getResources, - getMySqlVersions, - onCreateAuthSecretChange, - getSecrets, - getMachineListForOptions, - setMachineToCustom, - updateAgentValue, - getCreateNameSpaceUrl, - ifCapiProviderIsNotEmpty, - ifDedicated, - dedicatedOnChange, - ifZones, - zonesOnChange, - getZones, - getSKU, - showMultiselectZone, - showSelectZone, - setStorageClass, - setReplicaNumber, - setRouterNumber, - setBackup, - showAdditionalSettings, - getDefault, + return { + onReferSecretChange, + showReferSecretSwitch, + getDefaultValue, + showSecretDropdown, + showReferSecret, + getReferSecrets, + toggleTls, + isRancherManaged, + fetchNamespaces, + showAdditionalSettings, + returnFalse, + initBundle, + isVariantAvailable, + isEqualToModelPathValue, + getNamespaces, + isMachineNotCustom, + isMachineCustom, + getMachineListForOptions, + setLimits, + setRequests, + setMachineToCustom, + updateAlertValue, + getCreateNameSpaceUrl, + ifCapiProviderIsNotEmpty, + ifDedicated, + dedicatedOnChange, + ifZones, + zonesOnChange, + getZones, + getSKU, + showMultiselectZone, + showSelectZone, + setStorageClass, + isConfigDatabaseOn, + clearConfiguration, + isToggleOn, + getAdminOptions, + onBackupSwitch, + showAlerts, + showIssuer, + setMonitoring, + getNodeTopology, + filterNodeTopology, + onAuthChange, + setBackup, + getDefault, + validateRackName, + } } diff --git a/charts/kubedbcom-clickhouse-editor-options/ui/create-ui.yaml b/charts/kubedbcom-clickhouse-editor-options/ui/create-ui.yaml index c946b1d696..537ddcc90c 100644 --- a/charts/kubedbcom-clickhouse-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-clickhouse-editor-options/ui/create-ui.yaml @@ -1,353 +1,361 @@ -steps: -- form: - discriminator: - bundleApiLoaded: - default: false - type: boolean - elements: - - computed: initBundle - if: returnFalse - type: label-element - - disableUnselect: true - fetch: getAdminOptions|databases/ClickHouse/versions - if: isToggleOn|databases/ClickHouse/versions - label: - text: labels.database.version - schema: - $ref: schema#/properties/spec/properties/admin/properties/databases/properties/ClickHouse/properties/versions/properties/default - type: select - - computed: getDefault|databases/ClickHouse/mode - fetch: getAdminOptions|databases/ClickHouse/mode - hasDescription: true - if: isToggleOn|databases/ClickHouse/mode - label: - text: labels.database.mode - onChange: clearArbiterHidden - schema: - $ref: schema#/properties/spec/properties/mode - type: radio +step: +- type: single-step-form + loader: initBundle + elements: + - type: label-element + label: '' + subtitle: Select the ClickHouse version you want to deploy on Kubernetes. The chosen version determines the ClickHouse engine features, compatibility, and runtime behavior of your analytical database. + - disableUnselect: true + loader: getAdminOptions|databases/ClickHouse/versions + if: + type: function + name: isToggleOn|databases/ClickHouse/versions + label: Database Version + schema: schema/properties/spec/properties/admin/properties/databases/properties/ClickHouse/properties/versions/properties/default + type: select + - init: + type: func + value: getDefault|databases/ClickHouse/mode + loader: getAdminOptions|databases/ClickHouse/mode + if: + type: function + name: isToggleOn|databases/ClickHouse/mode + label: Database Mode + isHorizontal: true + watcher: + func: clearArbiterHidden + paths: + - schema/properties/spec/properties/mode + schema: schema/properties/spec/properties/mode + type: radio + - elements: - elements: - - elements: - - label: - text: labels.cluster.replicas - schema: - $ref: schema#/properties/spec/properties/topology/properties/cluster/properties/replicas + - type: label-element + label: '' + subtitle: Configure cluster topology for distributed ClickHouse deployment. Specify the number of replicas for high availability and shards for data partitioning and parallel query processing. + - type: horizontal-layout + showLabels: true + elements: + - label: Cluster Replicas + schema: schema/properties/spec/properties/topology/properties/cluster/properties/replicas + type: input + - label: Cluster Shards + schema: schema/properties/spec/properties/topology/properties/cluster/properties/shards + type: input + label: Cluster + showLabels: true + type: block-layout + if: + type: function + name: isEqualToModelPathValue|Topology|/spec/mode + type: block-layout + - elements: + - type: label-element + label: '' + subtitle: Select a machine profile to allocate CPU and memory resources for your analytical database. Choose 'custom' to manually specify resource requirements or select a predefined profile. + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: CPU + loader: setLimits|cpu + watcher: + func: setRequests|cpu + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: Memory + loader: setLimits|memory + watcher: + func: setRequests|memory + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + label: Machine Profile + showLabels: true + type: block-layout + - elements: + - type: horizontal-layout + showLabels: true + elements: + - loader: getAdminOptions|storageClasses + if: + type: function + name: isToggleOn|storageClasses + label: Storage Class + schema: schema/properties/spec/properties/admin/properties/storageClasses/properties/default + type: select + - if: + type: function + name: showStorageSizeField + label: Storage Size + schema: schema/properties/spec/properties/persistence/properties/size + type: input + type: block-layout + - label: Externally Managed? + schema: schema/properties/spec/properties/topology/properties/clickHouseKeeper/properties/externallyManaged + type: switch + - elements: + - type: label-element + label: '' + subtitle: Configure external ClickHouse Keeper node connection details. Specify the host address and port number for the externally managed keeper service. + - type: horizontal-layout + showLabels: true + elements: + - label: Host + schema: schema/properties/spec/properties/topology/properties/clickHouseKeeper/properties/node/properties/host + type: input + - label: Port + schema: schema/properties/spec/properties/topology/properties/clickHouseKeeper/properties/node/properties/port + type: input + if: + type: function + name: isExternallyManaged|true + label: Node + showLabels: true + type: block-layout + - elements: + - type: label-element + label: '' + subtitle: Configure managed ClickHouse Keeper instance for cluster coordination. Specify storage size, replica count, and resource allocation for the keeper nodes. + - type: horizontal-layout + showLabels: true + elements: + - label: Storage Size + schema: schema/properties/spec/properties/topology/properties/clickHouseKeeper/properties/spec/properties/persistence/properties/size + type: input + - label: Replicas + schema: schema/properties/spec/properties/topology/properties/clickHouseKeeper/properties/spec/properties/replicas + type: input + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/topology/properties/clickHouseKeeper/properties/spec/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu|topology/clickHouseKeeper/spec + disable: isMachineNotCustom|topology/clickHouseKeeper/spec + label: CPU + loader: setLimits|cpu|topology/clickHouseKeeper/spec + watcher: + func: setRequests|cpu|topology/clickHouseKeeper/spec + paths: + - schema/properties/spec/properties/topology/properties/clickHouseKeeper/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/topology/properties/clickHouseKeeper/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/clickHouseKeeper/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu type: input - - label: - text: labels.cluster.shards - schema: - $ref: schema#/properties/spec/properties/topology/properties/cluster/properties/shards + - init: + type: func + value: setLimits|memory|topology/clickHouseKeeper/spec + disable: isMachineNotCustom|topology/clickHouseKeeper/spec + label: Memory + loader: setLimits|memory|topology/clickHouseKeeper/spec + watcher: + func: setRequests|memory|topology/clickHouseKeeper/spec + paths: + - schema/properties/spec/properties/topology/properties/clickHouseKeeper/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/topology/properties/clickHouseKeeper/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/clickHouseKeeper/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory type: input - label: - text: labels.cluster.cluster - show_label: true - type: single-step-form - if: isEqualToModelPathValue|Topology|/spec/mode - type: single-step-form + if: + type: function + name: isExternallyManaged|false + label: Spec + showLabels: true + type: block-layout + - description: Configure Credentials, Deployment Mode etc. + elements: - elements: - - computed: setMachineToCustom - customClass: mt-10 - fetch: getMachineListForOptions - label: - text: labels.machine - schema: - $ref: schema#/properties/spec/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.cpu - onChange: setRequests|cpu - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.memory - onChange: setRequests|memory - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - label: - text: labels.machine_profile - show_label: true - type: single-step-form - - fetch: getAdminOptions|storageClasses - if: isToggleOn|storageClasses - label: - text: labels.storage.select - schema: - $ref: schema#/properties/spec/properties/admin/properties/storageClasses/properties/default + - type: label-element + label: '' + subtitle: Add custom labels and annotations to your database resources for organization, monitoring, and integration with other Kubernetes tools and services. + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/annotations + label: Labels & Annotations + showLabels: true + hideBlock: true + type: block-layout + - init: + type: func + value: getDefault|deletionPolicy + customClass: mt-20 + if: + type: function + name: isToggleOn|deletionPolicy + label: Deletion Policy + watcher: + func: setStorageClass + paths: + - schema/properties/spec/properties/deletionPolicy + options: + - description: options.deletionPolicy.delete.description + text: Delete + value: Delete + - description: options.deletionPolicy.halt.description + text: Halt + value: Halt + - description: options.deletionPolicy.wipeOut.description + text: WipeOut + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: DoNotTerminate + value: DoNotTerminate + schema: schema/properties/spec/properties/deletionPolicy + type: select + - if: + type: function + name: getDefaultValue|spec/admin/authCredential/customize + label: Provide Authentication Credentials? + watcher: + func: onAuthChange + paths: + - temp/createAuthSecret + schema: temp/createAuthSecret + type: switch + - if: + type: function + name: showReferSecretSwitch + label: Refer existing Secret? + watcher: + func: onReferSecretChange + paths: + - temp/referSecret + schema: temp/referSecret + type: switch + - loader: getReferSecrets + if: + type: function + name: showSecretDropdown + label: Secret + schema: schema/properties/spec/properties/authSecret/properties/name type: select - - if: showStorageSizeField - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/persistence/properties/size + - if: + type: function + name: showReferSecret + label: password + schema: schema/properties/spec/properties/authSecret/properties/password type: input - - label: - text: Externally Managed? - schema: - $ref: schema#/properties/spec/properties/topology/properties/clickHouseKeeper/properties/externallyManaged + - if: + type: function + name: getDefaultValue|spec/admin/customConfiguration + label: Configure Database? + watcher: + func: clearConfiguration + paths: + - temp/configDatabase + schema: temp/configDatabase type: switch + - if: + type: function + name: isConfigDatabaseOn + label: Configuration + # hasCopy: true + schema: schema/properties/spec/properties/configuration + type: textarea + - if: + type: function + name: isToggleOn|deployment + label: Deployment name + options: + - description: labels.deployment.shared + text: Shared + value: Shared + - description: labels.deployment.dedicated + text: Dedicated + value: Dedicated + schema: schema/properties/spec/properties/admin/properties/deployment/properties/default + type: radio + - if: + type: function + name: isToggleOn|clusterTier + isHorizontal: true + label: Cluster Tier + options: + - text: General Purpose + value: GeneralPurpose + - text: Memory Optimized + value: MemoryOptimized + - text: CPU Optimized + value: CPUOptimized + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/default + type: radio + - disableUnselect: true + loader: getAdminOptions|clusterTier/placement + if: + type: function + name: isToggleOn|clusterTier/placement + label: Placement + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + type: select + - disableUnselect: true + loader: getNodeTopology + if: + type: function + name: isToggleOn|clusterTier/nodeTopology + label: Node Topology + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + type: select + label: Advanced Configuration + showLabels: true + type: block-layout + - description: Enable Backup, Monitoring, TLS etc. + elements: - elements: - - customClass: mt-10 - label: - text: labels.host - schema: - $ref: schema#/properties/spec/properties/topology/properties/clickHouseKeeper/properties/node/properties/host - type: input - - label: - text: labels.port - schema: - $ref: schema#/properties/spec/properties/topology/properties/clickHouseKeeper/properties/node/properties/port - type: input - if: isExternallyManaged|true - label: - text: Node - show_label: true - type: single-step-form - - elements: - - customClass: mt-10 - label: - text: Size - schema: - $ref: schema#/properties/spec/properties/topology/properties/clickHouseKeeper/properties/spec/properties/persistence/properties/size - type: input - - label: - text: Replicas - schema: - $ref: schema#/properties/spec/properties/topology/properties/clickHouseKeeper/properties/spec/properties/replicas - type: input - - elements: - - computed: setMachineToCustom - customClass: mt-10 - fetch: getMachineListForOptions - label: - text: labels.machine - schema: - $ref: schema#/properties/spec/properties/topology/properties/clickHouseKeeper/properties/spec/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu|topology/clickHouseKeeper/spec - disabled: isMachineNotCustom|topology/clickHouseKeeper/spec - if: isMachineCustom|topology/clickHouseKeeper/spec - label: - text: labels.cpu - onChange: setRequests|cpu - schema: - $ref: schema#/properties/spec/properties/topology/properties/clickHouseKeeper/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory|topology/clickHouseKeeper/spec - disabled: isMachineNotCustom|topology/clickHouseKeeper/spec - if: isMachineCustom|topology/clickHouseKeeper/spec - label: - text: labels.memory - onChange: setRequests|memory - schema: - $ref: schema#/properties/spec/properties/topology/properties/clickHouseKeeper/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - label: - text: labels.machine_profile - show_label: true - type: single-step-form - if: isExternallyManaged|false - label: - text: Spec - show_label: true - type: single-step-form - - accordion: true - description: - text: Configure Credentials, Deployment Mode etc. - discriminator: - configDatabase: - default: false - type: boolean - createAuthSecret: - default: false - type: boolean - referSecret: - default: false - type: boolean - elements: - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties - type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties - type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - computed: getDefault|deletionPolicy - customClass: mt-20 - if: isToggleOn|deletionPolicy - 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/spec/properties/deletionPolicy - type: select - - if: getDefaultValue|spec/admin/authCredential/customize - label: - text: Provide Authentication Credentials? - onChange: onAuthChange - schema: - $ref: discriminator#/createAuthSecret - type: switch - - if: showReferSecretSwitch - label: - text: Refer existing Secret? - onChange: onReferSecretChange - schema: - $ref: discriminator#/referSecret - type: switch - - fetch: getReferSecrets - if: showSecretDropdown - label: - text: Secret - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/name - type: select - - if: showReferSecret - label: - text: labels.password - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/password - type: input - - computed: isConfigAvailable - if: getDefaultValue|spec/admin/customConfiguration - label: - text: Configure Database? - onChange: clearConfiguration - schema: - $ref: discriminator#/configDatabase + - init: + type: func + value: setMonitoring + label: Enable Monitoring? + watcher: + func: updateAlertValue + paths: + - temp/monitoring + schema: temp/monitoring type: switch - - if: isConfigDatabaseOn - label: - text: Configuration - schema: - $ref: schema#/properties/spec/properties/configuration - type: editor - - hasDescription: true - if: isToggleOn|deployment - label: - text: labels.deployment.name - options: - - description: labels.deployment.shared - text: Shared - value: Shared - - description: labels.deployment.dedicated - text: Dedicated - value: Dedicated - schema: - $ref: schema#/properties/spec/properties/admin/properties/deployment/properties/default - type: radio - - if: isToggleOn|clusterTier - isHorizontal: true - label: - text: labels.clusterTier - options: - - text: General Purpose - value: GeneralPurpose - - text: Memory Optimized - value: MemoryOptimized - - text: CPU Optimized - value: CPUOptimized - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/default - type: radio - - disableUnselect: true - fetch: getAdminOptions|clusterTier/placement - if: isToggleOn|clusterTier/placement - label: - text: labels.placement - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default - type: select - - disableUnselect: true - fetch: getNodeTopology - if: isToggleOn|clusterTier/nodeTopology - label: - text: labels.nodeTopology - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default - type: select - hideForm: true - label: - text: Advanced Configuration - show_label: true - type: single-step-form - - accordion: true - description: - text: Enable Backup, Monitoring, TLS etc. - discriminator: - backup: - default: false - type: boolean - elements: - - discriminator: - monitoring: - default: false - type: boolean - elements: - - computed: setMonitoring - label: - text: labels.enable_monitoring - onChange: updateAlertValue - schema: - $ref: discriminator#/monitoring - type: switch - if: isToggleOn|monitoring - type: single-step-form - if: showAdditionalSettings - label: - text: Additional Options - show_label: true - type: single-step-form - type: single-step-form + if: + type: function + name: isToggleOn|monitoring + type: block-layout + if: + type: function + name: showAdditionalSettings + label: Additional Options + showLabels: true + type: block-layout id: options - title: steps.0.label type: multi-step-form diff --git a/charts/kubedbcom-clickhouse-editor-options/ui/functions.js b/charts/kubedbcom-clickhouse-editor-options/ui/functions.js index e6db92df11..ec85c9985d 100644 --- a/charts/kubedbcom-clickhouse-editor-options/ui/functions.js +++ b/charts/kubedbcom-clickhouse-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -315,1011 +317,1058 @@ const modeDetails = { }, } -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} - -function showStorageSizeField({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - const validType = ['Standalone', 'Cluster'] - return validType.includes(modelPathValue) -} +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) -function showReplicaField({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - const validType = ['Replicaset'] - return validType.includes(modelPathValue) -} + setDiscriminatorValue('bundleApiLoaded', false) + setDiscriminatorValue('configDatabase', false) + setDiscriminatorValue('createAuthSecret', false) + setDiscriminatorValue('referSecret', false) + setDiscriminatorValue('backup', false) + setDiscriminatorValue('monitoring', false) + + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } -function onModeChange({ model, getValue, watchDependency, commit }) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - if (modelPathValue === 'Replicaset') { - commit('wizard/model$update', { - path: '/spec/replicas', - value: 3, - force: true, - }) - } else { - commit('wizard/model$update', { - path: '/spec/replicas', - value: 1, - force: true, - }) + function showStorageSizeField() { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + const validType = [] + return !validType.includes(modelPathValue) } -} -async function getResources({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function showReplicaField() { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + const validType = ['Replicaset'] + return validType.includes(modelPathValue) + } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + function onModeChange() { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + if (modelPathValue === 'Replicaset') { + commit('wizard/model$update', { + path: '/spec/replicas', + value: 3, + force: true, + }) + } else { + commit('wizard/model$update', { + path: '/spec/replicas', + value: 1, + force: true, + }) + } + } - const resources = (resp && resp.data && resp.data.items) || [] + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return resources -} + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) -async function getMongoDbVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + const resources = (resp && resp.data && resp.data.items) || [] - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, - }, - }, + resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true + }) + return resources } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) + async function getMongoDbVersions(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + + const queryParams = { + filter: { + items: { + metadata: { name: null }, + spec: { version: null, deprecated: null }, + }, + }, + } - const resources = (resp && resp.data && resp.data.items) || [] + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: queryParams, + }, + ) - // keep only non deprecated versions - const filteredMongoDbVersions = resources.filter((item) => item.spec && !item.spec.deprecated) + const resources = (resp && resp.data && resp.data.items) || [] - filteredMongoDbVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredMongoDbVersions -} + // keep only non deprecated versions + const filteredMongoDbVersions = resources.filter((item) => item.spec && !item.spec.deprecated) -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/spec/authSecret/name') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/spec/authSecret/password') + filteredMongoDbVersions.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + const specVersion = (item.spec && item.spec.version) || '' + item.text = `${name} (${specVersion})` + item.value = name + return true + }) + return filteredMongoDbVersions } -} -function getMachineListForOptions({ model, getValue }) { - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') + function onCreateAuthSecretChange() { + const createAuthSecret = getValue(discriminator, '/createAuthSecret') + if (createAuthSecret) { + commit('wizard/model$delete', '/spec/authSecret/name') + } else if (createAuthSecret === false) { + commit('wizard/model$delete', '/spec/authSecret/password') + } + } let array = [] + function getMachineListForOptions() { + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') - if (available.length) { - array = available.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - else { - let subText = '', - text = '' - const machineData = machinesFromPreset.find((val) => val.id === machine) - if (machineData) { - subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` - text = machineData.name ? machineData.name : machineData.id - } - return { text, subText, value: machine } - } - }) - } else { - array = machineList - .map((machine) => { + if (available.length) { + array = available.map((machine) => { if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + else { + let subText = '', + text = '' + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + text = machineData.name ? machineData.name : machineData.id + } + return { text, subText, value: machine } + } }) - .filter((val) => !!val) + } else { + array = machineList + .map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { text, subText, value: machine } + }) + .filter((val) => !!val) + } + return array } - return array -} -function setLimits({ model, getValue, commit, watchDependency }, resource, type) { - const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' - watchDependency(`model#${path}`) - const selectedMachine = getValue(model, path) || 'custom' - const reqCommitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - const comparePath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - - const resourceValue = getValue(model, comparePath) - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - - let cpu = '', - memory = '' - if (available.length && selectedMachine !== 'custom') { - const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) - if (machineData) { - cpu = machineData.limits.cpu - memory = machineData.limits.memory + function setLimits(resource, type) { + const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' + // watchDependency(`model#${path}`) + const selectedMachine = getValue(model, path) || 'custom' + const reqCommitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + const comparePath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + + const resourceValue = getValue(model, comparePath) + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + let cpu = '', + memory = '' + if (available.length && selectedMachine !== 'custom') { + const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) + if (machineData) { + cpu = machineData.limits.cpu + memory = machineData.limits.memory + } + } else { + if (selectedMachine === 'custom') { + cpu = resourceValue + memory = resourceValue + } else { + cpu = machines[selectedMachine].resources.limits.cpu + memory = machines[selectedMachine].resources.limits.memory + } } - } else { - if (selectedMachine === 'custom') { - cpu = resourceValue - memory = resourceValue + + if (resource === 'memory') { + commit('wizard/model$update', { + path: reqCommitPath, + value: memory, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: memory, + force: true, + }) + return memory } else { - cpu = machines[selectedMachine].resources.limits.cpu - memory = machines[selectedMachine].resources.limits.memory + commit('wizard/model$update', { + path: reqCommitPath, + value: cpu, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: cpu, + force: true, + }) + return cpu } } - if (resource === 'memory') { + function setRequests(resource, type) { + const modelPath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + + const fullpath = `/spec/podResources/machine` + const modelPathValue = getValue(model, fullpath) + commit('wizard/model$update', { - path: reqCommitPath, - value: memory, + path: commitPath, + value: val, force: true, }) + + if (modelPathValue === 'custom') { + return + } + let commitCpuMemory, ModelPathValue + if (resource && type) { + const fullPath = `/spec/${type}/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/${type}/podResources/resources/requests/${resource}` + } else { + const fullPath = `/spec/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/podResources/resources/requests/${resource}` + } + let cpuMemoryValue + array.forEach((item) => { + if (item.value === ModelPathValue) { + // Parse subText like "CPU: 2, Memory: 2Gi" + const subText = item.subText || '' + if (resource === 'cpu') { + // Extract CPU value + const cpuMatch = subText.match(/CPU:\s*([^,]+)/) + cpuMemoryValue = cpuMatch ? cpuMatch[1].trim() : '' + } else if (resource === 'memory') { + // Extract Memory value + const memoryMatch = subText.match(/Memory:\s*(.+)/) + cpuMemoryValue = memoryMatch ? memoryMatch[1].trim() : '' + } + } + }) commit('wizard/model$update', { - path: comparePath, - value: memory, + path: commitCpuMemory, + value: cpuMemoryValue, force: true, }) - return memory - } else { + return cpuMemoryValue + } + + function setMachineToCustom(type) { + const machine = getValue(model, '/spec/admin/machineProfiles/default') + return machine || 'custom' + } + + async function fetchJsons() { + 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 updateAgentValue(val) { commit('wizard/model$update', { - path: reqCommitPath, - value: cpu, + path: '/spec/monitoring/agent', + value: val ? 'prometheus.io/operator' : '', force: true, }) + + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: comparePath, - value: cpu, + path: '/form/alert/enabled', + value: val ? 'warning' : 'none', force: true, }) - return cpu } -} - -function setRequests({ getValue, model, commit }, resource) { - const modelPath = `/spec/podResources/resources/requests/${resource}` - const val = getValue(model, modelPath) - commitPath = `/spec/podResources/resources/limits/${resource}` - commit('wizard/model$update', { - path: commitPath, - value: val, - force: true, - }) -} - -function setMachineToCustom({ getValue, model }) { - const machine = getValue(model, '/spec/admin/machineProfiles/default') - return machine || 'custom' -} -async function fetchJsons({ axios, itemCtx }) { - let ui = {} - let language = {} - let functions = {} - const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart + function getCreateNameSpaceUrl() { + const user = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - 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) + const domain = storeGet('/domain') || '' + if (domain.includes('bb.test')) { + return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } } - return { - ui: ui.data || {}, - language: language.data || {}, - functions, + const ifCapiProviderIsNotEmpty = () => { + // watchDependency('model#/form/capi/provider') + const val = getValue(model, '/form/capi/provider') + if (val) return true } -} -function updateAgentValue({ commit }, val) { - commit('wizard/model$update', { - path: '/spec/monitoring/agent', - value: val ? 'prometheus.io/operator' : '', - force: true, - }) - - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: val ? 'warning' : 'none', - force: true, - }) -} + const showMultiselectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + if (val === 'capz' && ifDedicated()) return true + } - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + const showSelectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') + if (val !== 'capz' && ifDedicated()) return true } -} -const ifCapiProviderIsNotEmpty = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/provider') - const val = getValue(model, '/form/capi/provider') - if (val) return true -} + const ifDedicated = () => { + const val = getValue(model, 'form/capi/dedicated') + if (val) return true + } -const showMultiselectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') + const dedicatedOnChange = () => { + const val = getValue(model, 'form/capi/dedicated') + if (!val) { + commit('wizard/model$delete', 'form/capi/zones') + commit('wizard/model$delete', 'form/capi/sku') + } + } - if (val === 'capz' && ifDedicated({ model, getValue })) return true -} + const ifZones = () => { + // watchDependency('model#/form/capi/zones') + // watchDependency('model#/form/capi/dedicated') + const zones = getValue(model, 'form/capi/zones') || [] + const isDedicated = getValue(model, 'form/capi/dedicated') + if (zones.length && isDedicated) return true + } -const showSelectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') - if (val !== 'capz' && ifDedicated({ model, getValue })) return true -} + const zonesOnChange = () => { + const zones = getValue(model, 'form/capi/zones') || [] + if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') + } -const ifDedicated = ({ model, getValue }) => { - const val = getValue(model, 'form/capi/dedicated') - if (val) return true -} + async function getZones() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const isDedicated = getValue(model, 'form/capi/dedicated') + if (isDedicated) { + try { + const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) + const val = resp.data.map((item) => { + return { value: item, text: item } + }) + return val + } catch (e) { + console.log(e) + return [] + } + } + } -const dedicatedOnChange = ({ model, getValue, commit }) => { - const val = getValue(model, 'form/capi/dedicated') - if (!val) { - commit('wizard/model$delete', 'form/capi/zones') - commit('wizard/model$delete', 'form/capi/sku') + async function getSKU() { + // watchDependency('model#/form/capi/zones') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const zones = getValue(model, 'form/capi/zones') || [] + if (zones.length) { + try { + let url = `clustersv2/${owner}/${cluster}/vms?` + if (typeof zones === 'string') { + url += `zones=${encodeURIComponent(zones)}` + } else { + zones.forEach((item) => { + url += `zones=${encodeURIComponent(item)}&` + }) + url = url.slice(0, -1) + } + const resp = await axios.get(url) + const val = resp.data.map((item) => { + return { + value: item.name, + text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb]`, + } + }) + return val + } catch (e) { + console.log(e) + return [] + } + } } -} -const ifZones = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/zones') - watchDependency('model#/form/capi/dedicated') - const zones = getValue(model, 'form/capi/zones') || [] - const isDedicated = getValue(model, 'form/capi/dedicated') - if (zones.length && isDedicated) return true -} + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false + } -const zonesOnChange = ({ model, getValue, commit }) => { - const zones = getValue(model, 'form/capi/zones') || [] - if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') -} + function setStorageClass() { + const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' + let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' + const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] + const suffix = '-retain' -async function getZones({ storeGet, axios, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const isDedicated = getValue(model, 'form/capi/dedicated') - if (isDedicated) { - try { - const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) - const val = resp.data.map((item) => { - return { value: item, text: item } + const simpleClassList = storageClassList.filter((item) => { + return !item.endsWith(suffix) + }) + const retainClassList = storageClassList.filter((item) => { + return item.endsWith(suffix) + }) + if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { + storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] + } else { + storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + } + + const isChangeable = isToggleOn('storageClasses') + if (isChangeable && storageClass) { + commit('wizard/model$update', { + path: '/spec/admin/storageClasses/default', + value: storageClass, + force: true, }) - return val - } catch (e) { - console.log(e) - return [] } } -} -async function getSKU({ storeGet, axios, model, getValue, watchDependency }) { - watchDependency('model#/form/capi/zones') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const zones = getValue(model, 'form/capi/zones') || [] - if (zones.length) { + let placement = [] + let versions = [] + let storageClass = [] + let clusterIssuers = [] + let nodetopologiesShared = [] + let nodetopologiesDedicated = [] + let features = [] + + async function initBundle() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + let db = getValue(model, '/metadata/resource/kind') + db = db.toLowerCase() + let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` + const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` try { - let url = `clustersv2/${owner}/${cluster}/vms?` - if (typeof zones === 'string') { - url += `zones=${encodeURIComponent(zones)}` - } else { - zones.forEach((item) => { - url += `zones=${encodeURIComponent(item)}&` + const resp = await axios.get(url) + features = resp.data.features || [] + placement = resp.data.placementpolicies || [] + versions = resp.data.versions || [] + storageClass = resp.data.storageclasses || [] + clusterIssuers = resp.data.clusterissuers || [] + nodetopologiesDedicated = resp.data.dedicated || [] + nodetopologiesShared = resp.data.shared || [] + + const response = await axios.get(annotationUrl) + const annotations = response.data?.metadata?.annotations || {} + const uidRange = annotations['openshift.io/sa.scc.uid-range'] + if (uidRange) { + const val = uidRange.split('/')[0] + commit('wizard/model$update', { + path: '/spec/openshift/securityContext/runAsUser', + value: val, + force: true, }) - url = url.slice(0, -1) } - const resp = await axios.get(url) - const val = resp.data.map((item) => { - return { - value: item.name, - text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, - } - }) - return val } catch (e) { console.log(e) - return [] } - } -} - -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} -function setStorageClass({ model, getValue, commit, discriminator, watchDependency }) { - const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' - let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' - const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] - const suffix = '-retain' - - const simpleClassList = storageClassList.filter((item) => { - return !item.endsWith(suffix) - }) - const retainClassList = storageClassList.filter((item) => { - return item.endsWith(suffix) - }) - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] - } else { - storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] - } - - const isChangeable = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'storageClasses', - ) - if (isChangeable && storageClass) { commit('wizard/model$update', { - path: '/spec/admin/storageClasses/default', - value: storageClass, + path: '/spec/deletionPolicy', + value: getDefault('deletionPolicy'), force: true, }) - } -} -let placement = [] -let versions = [] -let storageClass = [] -let clusterIssuers = [] -let nodetopologiesShared = [] -let nodetopologiesDedicated = [] -let features = [] -async function initBundle({ commit, model, getValue, axios, storeGet, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - let db = getValue(model, '/metadata/resource/kind') - db = db.toLowerCase() - let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` - const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - try { - const resp = await axios.get(url) - features = resp.data.features || [] - placement = resp.data.placementpolicies || [] - versions = resp.data.versions || [] - storageClass = resp.data.storageclasses || [] - clusterIssuers = resp.data.clusterissuers || [] - nodetopologiesDedicated = resp.data.dedicated || [] - nodetopologiesShared = resp.data.shared || [] - - const response = await axios.get(annotationUrl) - const annotations = response.data?.metadata?.annotations || {} - const uidRange = annotations['openshift.io/sa.scc.uid-range'] - if (uidRange) { - const val = uidRange.split('/')[0] + if (!getValue(model, `/spec/admin/databases/ClickHouse/mode/toggle`)) { + let defMode = getDefault('databases/ClickHouse/mode') || '' + if (defMode === '') { + const arr = getValue(model, '/spec/databases/ClickHouse/mode/available') || [] + if (arr.length) defMode = arr[0] + } commit('wizard/model$update', { - path: '/spec/openshift/securityContext/runAsUser', - value: val, + path: '/spec/mode', + value: defMode, force: true, }) } - } catch (e) { - console.log(e) - } - commit('wizard/model$update', { - path: '/spec/deletionPolicy', - value: getDefault({ getValue, model }, 'deletionPolicy'), - force: true, - }) - - if (!getValue(model, `/spec/admin/databases/ClickHouse/mode/toggle`)) { - let defMode = getDefault({ getValue, model }, 'databases/ClickHouse/mode') || '' - if (defMode === '') { - const arr = getValue(model, '/spec/databases/ClickHouse/mode/available') || [] - if (arr.length) defMode = arr[0] + if (!features.includes('tls')) { + commit('wizard/model$update', { + path: '/spec/admin/tls/default', + value: false, + force: true, + }) + } + if (!features.includes('binding')) { + commit('wizard/model$update', { + path: '/spec/admin/expose/default', + value: false, + force: true, + }) + } + if (!features.includes('monitoring')) { + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: 'none', + force: true, + }) + } + if (!features.includes('backup')) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: '', + force: true, + }) } - commit('wizard/model$update', { - path: '/spec/mode', - value: defMode, - force: true, - }) - } - if (!features.includes('tls')) { - commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: false, - force: true, - }) - } - if (!features.includes('binding')) { - commit('wizard/model$update', { - path: '/spec/admin/expose/default', - value: false, - force: true, - }) - } - if (!features.includes('monitoring')) { - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: 'none', - force: true, - }) - } - if (!features.includes('backup')) { - commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, - force: true, - }) - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: '', - force: true, - }) + setDiscriminatorValue('/bundleApiLoaded', true) } - setDiscriminatorValue('/bundleApiLoaded', true) -} + function fetchOptions(type) { + let kind = getValue(model, '/metadata/resource/kind') + + let returnArray = [] + if (type === 'clusterTier/placement') { + returnArray = placement + } else if (type === `databases/${kind}/versions`) { + returnArray = versions + } else if (type === 'storageClasses') { + returnArray = storageClass + } else if (type === 'clusterIssuers') { + returnArray = clusterIssuers + } -function fetchOptions({ model, getValue, commit }, type) { - let kind = getValue(model, '/metadata/resource/kind') - - let returnArray = [] - if (type === 'clusterTier/placement') { - returnArray = placement - } else if (type === `databases/${kind}/versions`) { - returnArray = versions - } else if (type === 'storageClasses') { - returnArray = storageClass - } else if (type === 'clusterIssuers') { - returnArray = clusterIssuers - } + if (returnArray.length === 1) { + const path = `/spec/admin/${type}/default` + commit('wizard/model$update', { + path: path, + value: returnArray[0], + force: true, + }) + } - if (returnArray.length === 1) { - const path = `/spec/admin/${type}/default` - commit('wizard/model$update', { - path: path, - value: returnArray[0], - force: true, - }) + return returnArray } - return returnArray -} - -function getAdminOptions({ getValue, model, watchDependency, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') - const options = getValue(model, `/spec/admin/${type}/available`) || [] + function getAdminOptions(type) { + // watchDependency('discriminator#/bundleApiLoaded') + const options = getValue(model, `/spec/admin/${type}/available`) || [] - if (options.length === 0) { - return fetchOptions({ model, getValue, commit }, type) - } - if (type.endsWith('/mode')) { - return ( - options?.map((item) => ({ - description: modeDetails[item]?.description || '', - text: modeDetails[item]?.text || '', - value: item, - })) || [] - ) + if (options.length === 0) { + return fetchOptions(type) + } + if (type.endsWith('/mode')) { + return ( + options?.map((item) => ({ + description: modeDetails[item]?.description || '', + text: modeDetails[item]?.text || '', + value: item, + })) || [] + ) + } + return options } - return options -} -function checkIfFeatureOn({ getValue, model }, type) { - let val = getValue(model, `/spec/admin/${type}/toggle`) - if (type === 'backup' || type === 'archiver') { - val = getValue(model, `/spec/admin/${type}/enable/toggle`) - } - const backupVal = getValue(model, '/spec/backup/tool') - - if (type === 'backup') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } else if (type === 'tls') { - return features.includes('tls') && val - } else if (type === 'expose') { - return features.includes('binding') && val - } else if (type === 'monitoring') { - return features.includes('monitoring') && val - } else if (type === 'archiver') { - return features.includes('backup') && backupVal === 'KubeStash' && val + let backupToolInitialValue = '' + function checkIfFeatureOn(type) { + let val = getValue(model, `/spec/admin/${type}/toggle`) + if (type === 'backup' || type === 'archiver') { + val = getValue(model, `/spec/admin/${type}/enable/toggle`) + } + const backupVal = getValue(model, '/spec/backup/tool') + if (type === 'backup') { + if (backupToolInitialValue === '') { + backupToolInitialValue = + features.includes('backup') && backupVal === 'KubeStash' && val ? 'on' : 'off' + return features.includes('backup') && backupVal === 'KubeStash' && val + } else { + if (backupToolInitialValue === 'on') { + return true + } else { + return false + } + } + } else if (type === 'tls') { + return features.includes('tls') && val + } else if (type === 'expose') { + return features.includes('binding') && val + } else if (type === 'monitoring') { + return features.includes('monitoring') && val + } else if (type === 'archiver') { + return features.includes('backup') && val + } } -} -function showAdditionalSettings({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return features.length -} + function showAdditionalSettings() { + // watchDependency('discriminator#/bundleApiLoaded') + return features.length + } -function isToggleOn({ getValue, model, discriminator, watchDependency }, type) { - watchDependency('discriminator#/bundleApiLoaded') - watchDependency('model#/spec/admin/deployment/default') - const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') - let deploymentType = getValue(model, `/spec/admin/deployment/default`) - if ( - type === 'tls' || - type === 'backup' || - type === 'expose' || - type === 'monitoring' || - type === 'archiver' - ) { - return checkIfFeatureOn({ getValue, model }, type) - } else if ( - type === 'clusterTier' || - type === 'clusterTier/placement' || - type === 'clusterTier/nodeTopology' - ) { - if (deploymentType === 'Dedicated' && bundleApiLoaded) return true - else return false - } else if (type === 'deployment') { - const deploymentType = getValue(model, '/spec/admin/deployment/default') - if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { - commit('wizard/model$update', { - path: '/spec/admin/deployment/default', - value: 'Shared', - force: true, - }) - } - return ( - getValue(model, `/spec/admin/${type}/toggle`) && - nodetopologiesDedicated.length && - bundleApiLoaded - ) - } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded -} + function isToggleOn(type) { + // watchDependency('discriminator#/bundleApiLoaded') + // watchDependency('model#/spec/admin/deployment/default') + const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') + let deploymentType = getValue(model, `/spec/admin/deployment/default`) + if ( + type === 'tls' || + type === 'backup' || + type === 'expose' || + type === 'monitoring' || + type === 'archiver' + ) { + return checkIfFeatureOn(type) + } else if ( + type === 'clusterTier' || + type === 'clusterTier/placement' || + type === 'clusterTier/nodeTopology' + ) { + if (deploymentType === 'Dedicated' && bundleApiLoaded) return true + else return false + } else if (type === 'deployment') { + const deploymentType = getValue(model, '/spec/admin/deployment/default') + if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + commit('wizard/model$update', { + path: '/spec/admin/deployment/default', + value: 'Shared', + force: true, + }) + } + return ( + getValue(model, `/spec/admin/${type}/toggle`) && + nodetopologiesDedicated.length && + bundleApiLoaded + ) + } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded + } -async function getNodeTopology({ model, getValue, axios, storeGet, watchDependency }) { - watchDependency('model#/spec/admin/deployment/default') - watchDependency('model#/spec/admin/clusterTier/default') - const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' - const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' - let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + async function getNodeTopology() { + // watchDependency('model#/spec/admin/deployment/default') + // watchDependency('model#/spec/admin/clusterTier/default') + const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' + const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' + let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] - const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' - if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared - else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared + else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated - const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) - return filteredList -} + const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) + return filteredList + } -function filterNodeTopology(list, tier, provider) { - // first filter the list from value that exists from the filtered list got from API - const filteredlist = list + function filterNodeTopology(list, tier, provider) { + // first filter the list from value that exists from the filtered list got from API + const filteredlist = list - // filter the list based on clusterTier - if (provider === 'EKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('c') - else if (tier === 'MemoryOptimized') return item.startsWith('r') - else return !item.startsWith('c') && !item.startsWith('r') - }) - } else if (provider === 'AKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - else - return ( - !(item.startsWith('f') || item.startsWith('fx')) && - !( + // filter the list based on clusterTier + if (provider === 'EKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('c') + else if (tier === 'MemoryOptimized') return item.startsWith('r') + else return !item.startsWith('c') && !item.startsWith('r') + }) + } else if (provider === 'AKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('e') || item.startsWith('eb') || item.startsWith('ec') || item.startsWith('m') || item.startsWith('d') ) - ) - }) - } else if (provider === 'GKE') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') - return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - else - return ( - !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && - !( + else + return ( + !(item.startsWith('f') || item.startsWith('fx')) && + !( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + ) + }) + } else if (provider === 'GKE') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') + return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('x4') || item.startsWith('m1') || item.startsWith('m2') || item.startsWith('m3') ) - ) - }) - } else return filteredlist -} - -function returnFalse() { - return false -} + else + return ( + !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && + !( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + ) + }) + } else return filteredlist + } -function showAlerts({ watchDependency, model, getValue, discriminator }) { - watchDependency('discriminator#/monitoring') - const isMonitorEnabled = getValue(discriminator, '/monitoring') - return ( - isMonitorEnabled && isToggleOn({ getValue, model, watchDependency, discriminator }, 'alert') - ) -} + function returnFalse() { + return false + } -function onBackupSwitch({ discriminator, getValue, commit }) { - const isBackupOn = getValue(discriminator, '/backup') - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: isBackupOn ? 'KubeStash' : '', - force: true, - }) -} + function showAlerts() { + // watchDependency('discriminator#/monitoring') + const isMonitorEnabled = getValue(discriminator, '/monitoring') + return isMonitorEnabled && isToggleOn('alert') + } -function clearArbiterHidden({ commit }) { - commit('wizard/model$update', { - path: `/spec/arbiter/enabled`, - value: false, - force: true, - }) - - commit('wizard/model$update', { - path: `/spec/hidden/enabled`, - value: false, - force: true, - }) -} + function onBackupSwitch() { + const isBackupOn = getValue(discriminator, '/backup') + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: isBackupOn ? 'KubeStash' : '', + force: true, + }) + } -function isConfigDatabaseOn({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configDatabase') - return getValue(discriminator, '/configDatabase') -} -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} -function showStorageSizeField({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - const validType = [] - return !validType.includes(modelPathValue) -} -function showHidden({ watchDependency, model, getValue }) { - watchDependency('model#/spec/hidden/enabled') - const isHiddenOn = getValue(model, '/spec/hidden/enabled') || '' - const notStandalone = notEqualToDatabaseMode({ model, getValue, watchDependency }, 'Standalone') - return isHiddenOn && notStandalone -} -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} -function showArbiter({ watchDependency, model, getValue }) { - watchDependency('model#/spec/arbiter/enabled') - const isArbiterOn = getValue(model, '/spec/arbiter/enabled') || '' - const notStandalone = notEqualToDatabaseMode({ model, getValue, watchDependency }, 'Standalone') - return isArbiterOn && notStandalone -} -function clearConfiguration({ discriminator, getValue, commit }) { - const configOn = getValue(discriminator, '/configDatabase') + function clearArbiterHidden() { + commit('wizard/model$update', { + path: `/spec/arbiter/enabled`, + value: false, + force: true, + }) - if (!configOn) { - commit('wizard/model$delete', '/spec/configuration') + commit('wizard/model$update', { + path: `/spec/hidden/enabled`, + value: false, + force: true, + }) } -} -function showIssuer({ model, getValue, watchDependency, discriminator }) { - watchDependency('model#/spec/admin/tls/default') - const isTlsEnabled = getValue(model, '/spec/admin/tls/default') - const isIssuerToggleEnabled = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'clusterIssuers', - ) - return isTlsEnabled && isIssuerToggleEnabled -} + function isConfigDatabaseOn() { + // watchDependency('discriminator#/configDatabase') + return getValue(discriminator, '/configDatabase') + } -function onAuthChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/authSecret/password', - value: '', - force: true, - }) -} -function setMonitoring({ getValue, model }) { - const agent = getValue(model, '/spec/admin/monitoring/agent') || '' - return !!agent -} + function notEqualToDatabaseMode(mode) { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + return modelPathValue && modelPathValue !== mode + } -function setBackup({ model, getValue }) { - const backup = getValue(model, '/spec/backup/tool') - const val = getValue(model, '/spec/admin/backup/enable/default') - return backup === 'KubeStash' && features.includes('backup') && val -} + function showHidden() { + // watchDependency('model#/spec/hidden/enabled') + const isHiddenOn = getValue(model, '/spec/hidden/enabled') || '' + const notStandalone = notEqualToDatabaseMode('Standalone') + return isHiddenOn && notStandalone + } -function isMachineCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue === 'custom' -} + function showArbiter() { + // watchDependency('model#/spec/arbiter/enabled') + const isArbiterOn = getValue(model, '/spec/arbiter/enabled') || '' + const notStandalone = notEqualToDatabaseMode('Standalone') + return isArbiterOn && notStandalone + } -function isMachineNotCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue !== 'custom' && !!modelPathValue -} + function clearConfiguration() { + const configOn = getValue(discriminator, '/configDatabase') -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], - }, - }, - ) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] + if (!configOn) { + commit('wizard/model$delete', '/spec/configuration') } - } catch (e) { - console.log(e) } - return [] -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function showIssuer() { + // watchDependency('model#/spec/admin/tls/default') + const isTlsEnabled = getValue(model, '/spec/admin/tls/default') + const isIssuerToggleEnabled = isToggleOn('clusterIssuers') + return isTlsEnabled && isIssuerToggleEnabled + } -function updateAlertValue({ commit, model, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const alert = isMonitorEnabled ? 'warning' : 'none' - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: alert, - force: true, - }) - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} + function onAuthChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/spec/authSecret/password', + value: '', + force: true, + }) + } -function getDefault({ getValue, model }, type) { - const val = getValue(model, `/spec/admin/${type}/default`) || '' - return val -} + function setMonitoring() { + const agent = getValue(model, '/spec/admin/monitoring/agent') || '' + return !!agent + } -function isConfigAvailable({ getValue, model }) { - const val = getValue(model, '/spec/configuration') - return val !== '' -} + function setBackup() { + const backup = getValue(model, '/spec/backup/tool') + const val = getValue(model, '/spec/admin/backup/enable/default') + return backup === 'KubeStash' && features.includes('backup') && val + } -async function getReferSecrets({ getValue, model, storeGet, axios, discriminator }) { - const referSecret = getValue(discriminator, '/referSecret') - if (!referSecret) { + function isMachineCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue === 'custom' + } + + function isMachineNotCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue !== 'custom' && !!modelPathValue + } + + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, + }, + ) + if (resp.data?.status?.projects) { + const projects = resp.data?.status?.projects + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } + } catch (e) { + console.log(e) + } return [] } - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/metadata/release/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - - const options = [] - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } + + function updateAlertValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const alert = isMonitorEnabled ? 'warning' : 'none' + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: alert, + force: true, + }) + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: agent, + force: true, }) - } catch (e) { - console.log(e) } - return options -} -function showAuthPasswordField({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function getDefault(type) { + const val = getValue(model, `/spec/admin/${type}/default`) || '' + return val + } -function showSecretDropdown({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + async function getReferSecrets() { + const referSecret = getValue(discriminator, '/referSecret') + if (!referSecret) { + return [] + } -function showReferSecret({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/createAuthSecret') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue -} + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/metadata/release/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` -function getDefaultValue({ getValue, model }, path) { - const val = getValue(model, `/${path}`) || '' - return val -} + const options = [] + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + return options + } -function showReferSecretSwitch({ model, getValue, watchDependency, discriminator }) { - const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showAuthPasswordField() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !modelPathValue && showReferSecret() + } -function onReferSecretChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) -} + function showSecretDropdown() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !!modelPathValue && showReferSecret() + } -function isExternallyManaged({ getValue, model, watchDependency }, expected) { - watchDependency('model#/spec/topology/clickHouseKeeper/externallyManaged') - const val = getValue(model, 'spec/topology/clickHouseKeeper/externallyManaged') - return (val && expected === 'true') || (!val && expected === 'false') -} + function showReferSecret() { + const modelPathValue = getValue(discriminator, '/createAuthSecret') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue + } -return { - isExternallyManaged, - showReferSecretSwitch, - onReferSecretChange, - getDefaultValue, - isRancherManaged, - showSecretDropdown, - showReferSecret, - getReferSecrets, - isConfigAvailable, - showAdditionalSettings, - returnFalse, - initBundle, - getNamespaces, - updateAlertValue, - getAdminOptions, - isToggleOn, - showAlerts, - getNodeTopology, - clearArbiterHidden, - showHidden, - isConfigDatabaseOn, - notEqualToDatabaseMode, - filterNodeTopology, - onAuthChange, - setMonitoring, - isMachineNotCustom, - isMachineCustom, - showIssuer, - showArbiter, - clearConfiguration, - showStorageSizeField, - onBackupSwitch, - isVariantAvailable, - fetchJsons, - showAuthPasswordField, - isEqualToModelPathValue, - showStorageSizeField, - getResources, - getMongoDbVersions, - onCreateAuthSecretChange, - getMachineListForOptions, - setLimits, - setRequests, - setMachineToCustom, - updateAgentValue, - getCreateNameSpaceUrl, - ifCapiProviderIsNotEmpty, - ifDedicated, - dedicatedOnChange, - ifZones, - zonesOnChange, - getZones, - getSKU, - showMultiselectZone, - showSelectZone, - setStorageClass, - showReplicaField, - onModeChange, - setBackup, - getDefault, + function getDefaultValue(path) { + const val = getValue(model, `/${path}`) || '' + return val + } + + function showReferSecretSwitch() { + const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue && showReferSecret() + } + + function onReferSecretChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + } + + function isExternallyManaged(expected) { + // watchDependency('model#/spec/topology/clickHouseKeeper/externallyManaged') + const val = getValue(model, 'spec/topology/clickHouseKeeper/externallyManaged') + return (val && expected === 'true') || (!val && expected === 'false') + } + + return { + isExternallyManaged, + showReferSecretSwitch, + onReferSecretChange, + getDefaultValue, + isRancherManaged, + showSecretDropdown, + showReferSecret, + getReferSecrets, + showAdditionalSettings, + returnFalse, + initBundle, + getNamespaces, + updateAlertValue, + getAdminOptions, + isToggleOn, + showAlerts, + getNodeTopology, + clearArbiterHidden, + showHidden, + isConfigDatabaseOn, + notEqualToDatabaseMode, + filterNodeTopology, + onAuthChange, + setMonitoring, + isMachineNotCustom, + isMachineCustom, + showIssuer, + showArbiter, + clearConfiguration, + showStorageSizeField, + onBackupSwitch, + isVariantAvailable, + fetchJsons, + showAuthPasswordField, + isEqualToModelPathValue, + getResources, + getMongoDbVersions, + onCreateAuthSecretChange, + getMachineListForOptions, + setLimits, + setRequests, + setMachineToCustom, + updateAgentValue, + getCreateNameSpaceUrl, + ifCapiProviderIsNotEmpty, + ifDedicated, + dedicatedOnChange, + ifZones, + zonesOnChange, + getZones, + getSKU, + showMultiselectZone, + showSelectZone, + setStorageClass, + showReplicaField, + onModeChange, + setBackup, + getDefault, + } } diff --git a/charts/kubedbcom-clickhouse-editor/ui/edit-ui.yaml b/charts/kubedbcom-clickhouse-editor/ui/edit-ui.yaml index 5cd4261774..df7b27ea9a 100644 --- a/charts/kubedbcom-clickhouse-editor/ui/edit-ui.yaml +++ b/charts/kubedbcom-clickhouse-editor/ui/edit-ui.yaml @@ -1,352 +1,231 @@ -steps: -- form: - discriminator: - dbDetails: - default: false - type: boolean +type: multi-step-form +step: + - type: single-step-form + id: compute-autoscaler + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: Select Db - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: Select Type - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComClickHouseAutoscaler/spec/compute/clickhouse/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/clickhouse/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/clickhouse/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/clickhouse/properties/resourceDiffPercentage - type: input - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/clickhouse/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/clickhouse/properties/minAllowed/properties/memory - type: input - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/clickhouse/properties/minAllowed - show_label: true - type: single-step-form - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/clickhouse/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/clickhouse/properties/maxAllowed/properties/memory - type: input - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/clickhouse/properties/maxAllowed - show_label: true - type: single-step-form - - fetch: setControlledResources|clickhouse - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/clickhouse/properties/controlledResources - type: multiselect - label: - text: ClickHouse - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/clickhouse - show_label: true - type: single-step-form - - elements: - - fetch: fetchNodeTopology - label: - text: Select Node Topology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name - type: select - - if: isNodeTopologySelected - label: - text: ScaleUp Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage - type: input - - if: isNodeTopologySelected - label: - text: ScaleDown Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage - type: input - label: - text: NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/nodeTopology - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply + - type: block-layout + if: + type: function + name: isConsole + elements: + - type: input + label: Name + schema: schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/metadata/properties/name + - type: select + label: Select Namespace + loader: getNamespaces + if: + type: function + name: isRancherManaged + schema: schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/metadata/properties/namespace + - type: select + label: Select Db + loader: getDbs + validation: + type: required + refresh: true + schema: schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/databaseRef/properties/name + watcher: + func: initMetadata + paths: + - schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/databaseRef/properties/name + + - type: radio + if: + type: function + name: isConsole + label: Select Type + validation: + type: required + schema: temp/properties/autoscalingType + watcher: + func: initMetadata + paths: + - temp/properties/autoscalingType options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: compute-autoscaler - title: steps.6.label -- form: - discriminator: - dbDetails: - default: false - type: boolean - elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - computed: getDbDetails - if: returnFalse - type: input - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: Select Db - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: Select Type - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComClickHouseAutoscaler/spec/storage/clickhouse/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/storage/properties/clickhouse/properties/trigger - type: select - - label: - text: Expansion Mode - options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/storage/properties/clickhouse/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/storage/properties/clickhouse/properties/usageThreshold - type: input - - addFormLabel: ScalingRules - element: + - text: Compute + value: compute + description: Scale your CPU Memory based on resource usage + - text: Storage + value: storage + description: Expand your database size based on volume usage + + - type: block-layout + showLabels: false + elements: + # clickhouse mode + - type: block-layout + label: ClickHouse + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/clickhouse elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/storage/properties/clickhouse/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/storage/properties/clickhouse/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComClickHouseAutoscaler/spec/storage/clickhouse/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/storage/properties/clickhouse/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComClickHouseAutoscaler/spec/storage/clickhouse/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/storage/properties/clickhouse/properties/upperBound - type: input - label: - text: ClickHouse - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/clickhouse - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: storage-autoscaler - title: steps.7.label -type: multi-step-form + - type: select + label: Trigger + init: + type: func + value: setTrigger|autoscalingKubedbComClickHouseAutoscaler/spec/compute/clickhouse/trigger + options: + - text: 'On' + value: 'On' + - text: 'Off' + value: 'Off' + schema: schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/clickhouse/properties/trigger + - type: input + label: Pod LifeTime Threshold + schema: schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/clickhouse/properties/podLifeTimeThreshold + - type: threshold-input + label: Resource Diff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/clickhouse/properties/resourceDiffPercentage + - type: block-layout + showLabels: false + elements: + - type: block-layout + label: Min Allowed + showLabels: true + fixedBlock: true + elements: + - type: input + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/clickhouse/properties/minAllowed/properties/cpu + - type: input + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/clickhouse/properties/minAllowed/properties/memory + - type: block-layout + label: Max Allowed + showLabels: true + fixedBlock: true + elements: + - type: input + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/clickhouse/properties/maxAllowed/properties/cpu + - type: input + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/clickhouse/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|clickhouse + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/clickhouse/properties/controlledResources + + - type: block-layout + label: Node Topology + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/nodeTopology + elements: + - type: select + label: Select Node Topology + loader: fetchNodeTopology + schema: schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name + - type: threshold-input + label: ScaleUp Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage + - type: threshold-input + label: ScaleDown Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage + + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + # schema: schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/opsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: storage-autoscaler + elements: + - type: block-layout + showLabels: false + elements: + - type: block-layout + showLabels: false + elements: + - type: block-layout + label: ClickHouse + showLabels: true + elements: + - type: select + label: Trigger + init: + type: func + value: setTrigger|autoscalingKubedbComClickHouseAutoscaler/spec/storage/clickhouse/trigger + options: + - text: 'On' + value: 'On' + - text: 'Off' + value: 'Off' + schema: schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/storage/properties/clickhouse/properties/trigger + - type: select + label: Expansion Mode + options: + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/storage/properties/clickhouse/properties/expansionMode + - type: threshold-input + label: UsageThreshold (%) + schema: schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/storage/properties/clickhouse/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/storage/properties/clickhouse/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComClickHouse/spec/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComClickHouseAutoscaler/spec/storage/clickhouse/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/storage/properties/clickhouse/properties/scalingRules + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/storage/properties/clickhouse/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComClickHouseAutoscaler/spec/storage/clickhouse/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/storage/properties/clickhouse/properties/upperBound + - type: block-layout + label: OpsRequest Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComClickHouseAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + \ No newline at end of file diff --git a/charts/kubedbcom-clickhouse-editor/ui/functions.js b/charts/kubedbcom-clickhouse-editor/ui/functions.js index 22ef13bf86..8fe7a58cfc 100644 --- a/charts/kubedbcom-clickhouse-editor/ui/functions.js +++ b/charts/kubedbcom-clickhouse-editor/ui/functions.js @@ -1,3175 +1,467 @@ -// ************************* common functions ******************************************** -// eslint-disable-next-line no-empty-pattern -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 disableLableChecker({ itemCtx }) { - const { key } = itemCtx - if (key.startsWith('app.kubernetes.io') || key.includes('helm')) return true - else return false -} - -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} - -async function getResources({ axios, storeGet }, 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 [] - } -} - -function isEqualToDiscriminatorPath( - { discriminator, getValue, watchDependency }, - value, - discriminatorPath, -) { - watchDependency('discriminator#' + discriminatorPath) - const discriminatorValue = getValue(discriminator, discriminatorPath) - return discriminatorValue === value -} - -function setValueFromModel({ getValue, model }, path) { - return getValue(model, path) -} - -function isNotShardModeSelected({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComClickHouse/spec') - const hasShardTopology = getValue(model, '/resources/kubedbComClickHouse/spec/shardTopology') - return !hasShardTopology -} - -function isShardModeSelected({ model, getValue, watchDependency, commit }) { - const resp = !isNotShardModeSelected({ model, getValue, watchDependency }) - if (resp) { - commit('wizard/model$delete', '/resources/kubedbComClickHouse/spec/configSecret') - commit('wizard/model$delete', '/resources/secret_config') - } - return resp -} - -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 -} - -async function getResourceList(axios, storeGet, { 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( - { axios, getValue, model, watchDependency, storeGet }, - 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 unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - 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, - } - }) -} - -function returnTrue() { - return true -} - -function returnStringYes() { - return 'yes' -} - -// ************************* Basic Info ********************************************** -async function getMongoDbVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, - }, - }, - } - - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) - - const resources = (resp && resp.data && resp.data.items) || [] - - // keep only non deprecated versions - const filteredMongoDbVersions = resources.filter((item) => item.spec && !item.spec.deprecated) - - filteredMongoDbVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredMongoDbVersions - } catch (e) { - console.log(e) - return [] - } -} - -// ************************* Auth Secret Field ****************************************** -function showAuthPasswordField({ model, getValue, watchDependency }) { - watchDependency('model#/resources') - const modelPathValue = getValue(model, '/resources') - return !!( - modelPathValue && - modelPathValue.secret && - modelPathValue.secret.metadata && - modelPathValue.secret.metadata.name && - !showAuthSecretField({ model, getValue, watchDependency }) - ) -} - -function showAuthSecretField({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComClickHouse/spec') - const modelPathValue = getValue(model, '/resources/kubedbComClickHouse/spec') - return !!(modelPathValue && modelPathValue.authSecret && modelPathValue.authSecret.name) -} - -function showNewSecretCreateField({ model, getValue, watchDependency, commit }) { - const resp = - !showAuthSecretField({ model, getValue, watchDependency }) && - !showAuthPasswordField({ model, getValue, watchDependency }) - const secret = getValue(model, '/resources/secret_auth') - if (resp && !secret) { - commit('wizard/model$update', { - path: '/resources/secret_auth', - value: { - data: { - password: '', - }, - }, - force: true, - }) - } - return resp -} - -// ********************* Database Mode *********************** -function isNotStandaloneMode({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - return mode !== 'Standalone' -} - -function showCommonStorageClassAndSizeField({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - const validType = ['Standalone', 'Replicaset'] - return validType.includes(mode) -} -function setDatabaseMode({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/resources/kubedbComClickHouse/spec') - - watchDependency('model#/resources/kubedbComClickHouse/spec') - if (modelPathValue.shardTopology) { - return 'Sharded' - } else if (modelPathValue.replicaSet) { - return 'Replicaset' - } else { - return 'Standalone' - } -} - -let storageClassList = [] -async function getStorageClassNames( - { axios, storeGet, commit, model, getValue, watchDependency, discriminator }, - mode, -) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const databaseModeShard = getValue(discriminator, '/activeDatabaseMode') === 'Sharded' - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/storage.k8s.io/v1/storageclasses`, - { - params: { - filter: { items: { metadata: { name: null, annotations: 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 - }) - storageClassList = resources - const path = - mode === 'shard' - ? '/resources/kubedbComClickHouse/spec/shardTopology/shard/storage/storageClassName' - : '/resources/kubedbComClickHouse/spec/storage/storageClassName' - const initialStorageClass = getValue(model, path) - if (!initialStorageClass) setStorageClass({ getValue, commit, model, discriminator }) - return resources -} - -function setStorageClass({ getValue, commit, model, discriminator }) { - const deletionPolicy = getValue(model, 'resources/kubedbComClickHouse/spec/deletionPolicy') || '' - const suffix = '-retain' - let storageClass = '' - - const simpleClassList = storageClassList.filter((item) => { - return !item.metadata?.name?.endsWith(suffix) - }) - - const retainClassList = storageClassList.filter((item) => { - return item.metadata?.name?.endsWith(suffix) - }) - - const defaultSimpleList = simpleClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] - ) - }) - - const defaultRetainList = retainClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] - ) - }) - - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - if (simpleClassList.length > 1) { - const found = defaultSimpleList.length ? defaultSimpleList[0] : simpleClassList[0] - storageClass = found.value - } else if (simpleClassList.length === 1) { - storageClass = simpleClassList[0]?.value - } else { - const found = defaultRetainList.length - ? defaultRetainList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found - } - } else { - if (retainClassList.length > 1) { - const found = defaultRetainList.length ? defaultRetainList[0] : retainClassList[0] - storageClass = found.value - } else if (retainClassList.length === 1) { - storageClass = retainClassList[0]?.value - } else { - const found = defaultSimpleList.length - ? defaultSimpleList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found - } - } - - const mode = getValue(discriminator, '/activeDatabaseMode') - - if (mode === 'Sharded') { - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/spec/shardTopology/shard/storage/storageClassName', - value: storageClass, - force: true, - }) - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/spec/shardTopology/configServer/storage/storageClassName', - value: storageClass, - force: true, - }) - commit('wizard/model$delete', '/resources/kubedbComClickHouse/spec/storage') - } else { - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/spec/storage/storageClassName', - value: storageClass, - force: true, - }) - } -} - -function updateConfigServerStorageClass({ getValue, model, commit }) { - const storageClass = - getValue( - model, - '/resources/kubedbComClickHouse/spec/shardTopology/shard/storage/storageClassName', - ) || '' - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/spec/shardTopology/configServer/storage/storageClassName', - value: storageClass, - force: true, - }) -} - -function deleteDatabaseModePath({ discriminator, getValue, commit, model }) { - const mode = getValue(discriminator, '/activeDatabaseMode') - const modelSpec = getValue(model, '/resources/kubedbComClickHouse/spec') - if (mode === 'Sharded') { - commit('wizard/model$delete', '/resources/kubedbComClickHouse/spec/replicaSet') - commit('wizard/model$delete', '/resources/kubedbComClickHouse/spec/replicas') - commit('wizard/model$delete', '/resources/kubedbComClickHouse/spec/storage') - commit('wizard/model$delete', '/resources/kubedbComClickHouse/spec/podTemplate') - commit('wizard/model$delete', '/resources/kubedbComClickHouse/spec/configSecret') - - commit('wizard/model$delete', '/resources/secret_config') - - if (!modelSpec.shardTopology) { - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/spec/shardTopology', - value: { - configServer: { - replicas: 3, - storage: { - resources: { - requests: { - storage: '', - }, - }, - }, - }, - mongos: { - replicas: 2, - }, - shard: { - replicas: 3, - shards: 3, - storage: { - resources: { - requests: { - storage: '', - }, - }, - }, - }, - }, - force: true, - }) - } - } else if (mode === 'Replicaset') { - commit('wizard/model$delete', '/resources/kubedbComClickHouse/spec/shardTopology') - - commit('wizard/model$delete', '/resources/secret_shard_config') - commit('wizard/model$delete', '/resources/secret_configserver_config') - commit('wizard/model$delete', '/resources/secret_mongos_config') - - if (!modelSpec.replicaSet) { - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/spec/replicaSet', - value: { name: '' }, - force: true, - }) - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/spec/replicas', - value: 3, - force: true, - }) - } - } else if (mode === 'Standalone') { - commit('wizard/model$delete', '/resources/kubedbComClickHouse/spec/shardTopology') - - commit('wizard/model$delete', '/resources/kubedbComClickHouse/spec/replicaSet') - commit('wizard/model$delete', '/resources/kubedbComClickHouse/spec/replicas') - - commit('wizard/model$delete', '/resources/secret_shard_config') - commit('wizard/model$delete', '/resources/secret_configserver_config') - commit('wizard/model$delete', '/resources/secret_mongos_config') - } -} - -function isEqualToDatabaseMode({ getValue, watchDependency, discriminator }, value) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - return mode === value -} - -// ************************** TLS ******************************88 - -function setApiGroup() { - return 'cert-manager.io' -} - -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - watchDependency('model#/resources/kubedbComClickHouse/spec/tls/issuerRef/apiGroup') - watchDependency('model#/resources/kubedbComClickHouse/spec/tls/issuerRef/kind') - watchDependency('model#/metadata/release/namespace') - const apiGroup = getValue(model, '/resources/kubedbComClickHouse/spec/tls/issuerRef/apiGroup') - const kind = getValue(model, '/resources/kubedbComClickHouse/spec/tls/issuerRef/kind') - const namespace = getValue(model, '/metadata/release/namespace') - - let url - if (kind === 'Issuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/namespaces/${namespace}/issuers` - } else if (kind === 'ClusterIssuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/clusterissuers` - } - - if (!url) return [] - - 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 [] - } -} - -async function hasIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await getIssuerRefsName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !!(resp && resp.length) -} - -async function hasNoIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await hasIssuerRefName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !resp -} - -function setClusterAuthMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComClickHouse/spec/clusterAuthMode') - return val || 'x509' -} - -function setSSLMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComClickHouse/spec/sslMode') - return val || 'requireSSL' -} - -function showTlsConfigureSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configureTLS') - const configureStatus = getValue(discriminator, '/configureTLS') - return configureStatus -} - -function onTlsConfigureChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/configureTLS') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/spec/tls', - value: { issuerRef: {}, certificates: [] }, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComClickHouse/spec/tls') - commit('wizard/model$delete', '/resources/kubedbComClickHouse/spec/clusterAuthMode') - commit('wizard/model$delete', '/resources/kubedbComClickHouse/spec/sslMode') - } -} - -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} - -/****** Monitoring *********/ - -function showMonitoringSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/enableMonitoring') - const configureStatus = getValue(discriminator, '/enableMonitoring') - return configureStatus -} - -function onEnableMonitoringChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/enableMonitoring') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/spec/monitor', - value: {}, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComClickHouse/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, getValue }) { - watchDependency('discriminator#/customizeExporter') - const configureStatus = getValue(discriminator, '/customizeExporter') - return configureStatus -} - -function onCustomizeExporterChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/customizeExporter') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/spec/monitor/prometheus/exporter', - value: {}, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComClickHouse/spec/monitor/prometheus/exporter') - } -} - -// ********************************* Initialization & Backup ************************************* -const stashAppscodeComRestoreSession_init = { - spec: { - repository: { - name: '', - }, - rules: [ - { - snapshots: ['latest'], - }, - ], - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} -const initScript = { - scriptPath: '', - secret: { - secretName: '', - }, -} -const stashAppscodeComRepository_init_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const stashAppscodeComRepository_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const restoreSessionInitRunTimeSettings = { - container: { - resources: { - requests: { - cpu: '', - memory: '', - }, - limits: { - cpu: '', - memory: '', - }, - }, - nice: { - adjustment: null, - }, - ionice: { - class: null, - classData: null, - }, - securityContext: { - privileged: false, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - env: [], - envFrom: [], - }, - pod: { - serviceAccountName: '', - imagePullSecrets: [], - securityContext: { - fsGroup: null, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - }, -} - -const stashAppscodeComBackupConfiguration = { - spec: { - repository: { - name: '', - }, - retentionPolicy: { - keepLast: 5, - name: 'keep-last-5', - prune: true, - }, - schedule: '*/5 * * * *', - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} - -function disableInitializationSection({ model, getValue, watchDependency }) { - const initialized = getValue(model, '/resources/kubedbComClickHouse/spec/init/initialized') - watchDependency('model#/resources/kubedbComClickHouse/spec/init/initialized') - return !!initialized -} - -function valueExists(value, getValue, path) { - const val = getValue(value, path) - if (val) return true - else return false -} - -function initPrePopulateDatabase({ getValue, model }) { - const waitForInitialRestore = getValue( - model, - '/resources/kubedbComClickHouse/spec/init/waitForInitialRestore', - ) - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - const script = getValue(model, '/resources/kubedbComClickHouse/spec/init/script') - - return waitForInitialRestore || !!stashAppscodeComRestoreSession_init || !!script ? 'yes' : 'no' -} - -function onPrePopulateDatabaseChange({ commit, getValue, discriminator, model }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - if (prePopulateDatabase === 'no') { - // delete related properties - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/spec/init/waitForInitialRestore', - value: false, - }) - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - commit('wizard/model$delete', '/resources/kubedbComClickHouse/spec/init/script') - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else { - const dbName = getValue(model, '/metadata/release/name') - // set stashAppscodeComRestoreSession_init if it doesn't exist - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - force: true, - }) - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - } - } -} - -function initDataSource({ getValue, model }) { - const script = getValue(model, '/resources/kubedbComClickHouse/spec/init/script') - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - - if (script) return 'script' - else if (stashAppscodeComRestoreSession_init) return 'stashBackup' - else return undefined -} - -function onDataSourceChange({ commit, getValue, discriminator, model }) { - const dataSource = getValue(discriminator, '/dataSource') - - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/spec/init/waitForInitialRestore', - value: dataSource === 'stashBackup', - force: true, - }) - - if (dataSource === 'script') { - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - - // create a new script if there is no script property - if (!valueExists(model, getValue, '/resources/kubedbComClickHouse/spec/init/script')) - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/spec/init/script', - value: initScript, - }) - } else if (dataSource === 'stashBackup') { - commit('wizard/model$delete', '/resources/kubedbComClickHouse/spec/init/script') - - // create a new stashAppscodeComRestoreSession_init if there is no stashAppscodeComRestoreSession_init property - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - const dbName = getValue(model, '/metadata/release/name') - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - }) - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - } - } -} - -// // for script -function initVolumeType({ getValue, model }) { - const configMap = getValue( - model, - '/resources/kubedbComClickHouse/spec/init/script/configMap/name', - ) - const secret = getValue( - model, - '/resources/kubedbComClickHouse/spec/init/script/secret/secretName', - ) - - if (configMap) return 'configMap' - else if (secret) return 'secret' - else return undefined -} - -function onVolumeTypeChange({ commit, getValue, discriminator, model }) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - if (sourceVolumeType === 'configMap') { - // add configMap object and delete secret object - commit('wizard/model$delete', '/resources/kubedbComClickHouse/spec/init/script/secret') - - if ( - !valueExists(model, getValue, '/resources/kubedbComClickHouse/spec/init/script/configMap') - ) { - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/spec/init/script/configMap', - value: { - name: '', - }, - }) - } - } else if (sourceVolumeType === 'secret') { - // delete configMap object and add secret object - commit('wizard/model$delete', '/resources/kubedbComClickHouse/spec/init/script/configMap') - - if (!valueExists(model, getValue, '/resources/kubedbComClickHouse/spec/init/script/secret')) { - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/spec/init/script/secret', - value: { - secretName: '', - }, - }) - } - } -} - -function showInitializationForm({ getValue, discriminator, watchDependency }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - watchDependency('discriminator#/prePopulateDatabase') - return prePopulateDatabase === 'yes' -} - -function showScriptOrStashForm({ getValue, discriminator, watchDependency }, value) { - const dataSource = getValue(discriminator, '/dataSource') - watchDependency('discriminator#/dataSource') - return dataSource === value -} - -function showConfigMapOrSecretName({ getValue, discriminator, watchDependency }, value) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - watchDependency('discriminator#/sourceVolumeType') - return sourceVolumeType === value -} - -// for stash backup -function initializeNamespace({ getValue, model }) { - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} - -function showRepositorySelectOrCreate({ getValue, discriminator, watchDependency }, value) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - return repositoryChoise === value -} - -function onInitRepositoryChoiseChange({ getValue, discriminator, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - if (repositoryChoise === 'select') { - // delete stashAppscodeComRepository_init_repo from model - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else if (repositoryChoise === 'create') { - // add stashAppscodeComRepository_init_repo to model - commit('wizard/model$update', { - path: 'resources/stashAppscodeComRepository_init_repo', - value: stashAppscodeComRepository_init_repo, - }) - - const repositoryName = `${getValue(model, '/metadata/release/name')}-init-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: repositoryName, - }) - } -} - -function initCustomizeRestoreJobRuntimeSettings({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function initCustomizeRestoreJobRuntimeSettingsForBackup({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function onCustomizeRestoreJobRuntimeSettingsChange({ commit, getValue, discriminator, model }) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - value: restoreSessionInitRunTimeSettings, - }) - } - } -} - -function onCustomizeRestoreJobRuntimeSettingsChangeForBackup({ - commit, - getValue, - discriminator, - model, -}) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - value: {}, - force: true, - }) - } - } -} - -function showRuntimeForm({ discriminator, getValue, watchDependency }, value) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - watchDependency('discriminator#/customizeRestoreJobRuntimeSettings') - return customizeRestoreJobRuntimeSettings === value -} - -async function getImagePullSecrets({ getValue, model, watchDependency, axios, storeGet }) { - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - - let resources = await getNamespacedResourceList(axios, storeGet, { - namespace, - group: 'core', - version: 'v1', - resource: 'secrets', - }) - - resources = resources.filter((item) => { - const validType = ['kubernetes.io/dockerconfigjson'] - return validType.includes(item.type) - }) - - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: { name: name }, - } - }) -} - -function showBackupOptions({ discriminator, getValue, watchDependency }, backup) { - const backupEnabled = getValue(discriminator, '/backupEnabled') - if (backupEnabled) { - if (backup === 'alert') return true - else return false - } else { - if (backup === 'alert') return false - else return true - } -} - -function isBlueprintOption({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/blueprintOptions') - const blueprintOptions = getValue(discriminator, '/blueprintOptions') - return blueprintOptions === value -} - -function ifUsagePolicy({ discriminator, getValue, watchDependency, model }, value) { - watchDependency( - 'model#/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', - ) - const usagePolicy = getValue( - model, - '/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', - ) - return usagePolicy === value -} - -async function getBlueprints({ getValue, model, setDiscriminatorValue, axios, storeGet }, backup) { - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const url = `clusters/${username}/${clusterName}/proxy/core.kubestash.com/v1alpha1/backupblueprints` - - try { - const resp = await axios.get(url) - let data = resp.data.items - return data - } catch (e) { - console.log(e) - } -} - -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} - -async function fetchNamespaces({ axios, storeGet }) { - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const group = storeGet('/route/params/group') - const version = storeGet('/route/params/version') - const resource = storeGet('/route/params/resource') - - const url = `clusters/${username}/${clusterName}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews` - - try { - const resp = await axios.post(url, { - _recurringCall: false, - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], - }, - }) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] - } - } catch (e) { - console.log(e) - } - return [] -} - -async function fetchNames( - { getValue, axios, storeGet, watchDependency, discriminator }, - version, - type, - discriminatorName, -) { - watchDependency(`discriminator#/${discriminatorName}`) - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const namespace = getValue(discriminator, `${discriminatorName}`) - const url = - type !== 'secrets' - ? `clusters/${username}/${clusterName}/proxy/storage.kubestash.com/${version}/namespaces/${namespace}/${type}` - : `clusters/${username}/${clusterName}/proxy/core/${version}/namespaces/${namespace}/${type}` - try { - if (namespace) { - const resp = await axios.get(url) - let data = resp.data.items - if (type === 'secrets') data = data.filter((ele) => !!ele.data['RESTIC_PASSWORD']) - data = data.map((ele) => ele.metadata.name) - return data - } - } catch (e) { - console.log(e) - } - return [] -} - -// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// FOR Backup Configuration - -// schedule backup - -function getBackupConfigsAndAnnotations(getValue, model) { - const stashAppscodeComBackupConfiguration = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration', - ) - - const coreKubestashComBackupConfiguration = getValue( - model, - '/resources/coreKubestashComBackupConfiguration', - ) - const kubeStashTarget = coreKubestashComBackupConfiguration?.spec?.target - - const mongoDB = getValue(model, '/resources/kubedbComClickHouse') - const mongoDbKind = mongoDB?.apiVersion?.split('/')?.at(0) - - let isKubeStash = false - if ( - mongoDB?.kind === kubeStashTarget?.kind && - mongoDB?.metadata?.name === kubeStashTarget?.name && - mongoDB?.metadata?.namespace === kubeStashTarget?.namespace && - mongoDbKind === kubeStashTarget?.apiGroup - ) { - isKubeStash = true - } - - const kubedbComClickHouseAnnotations = - getValue(model, '/resources/kubedbComClickHouse/metadata/annotations') || {} - - const isBluePrint = Object.keys(kubedbComClickHouseAnnotations).some( - (k) => - k === 'stash.appscode.com/backup-blueprint' || - k === 'stash.appscode.com/schedule' || - k.startsWith('params.stash.appscode.com/'), - ) - - return { - stashAppscodeComBackupConfiguration, - isBluePrint, - isKubeStash, - } -} - -function deleteKubeDbComMongDbAnnotation(getValue, model, commit) { - const annotations = getValue(model, '/resources/kubedbComClickHouse/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/kubedbComClickHouse/metadata/annotations', - value: filteredAnnotations, - }) -} - -function addKubeDbComMongDbAnnotation(getValue, model, commit, key, value, force) { - const annotations = getValue(model, '/resources/kubedbComClickHouse/metadata/annotations') || {} - - if (annotations[key] === undefined) { - annotations[key] = value - } else if (force) { - annotations[key] = value - } - - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/metadata/annotations', - value: annotations, - force: true, - }) -} - -function initScheduleBackupForEdit({ getValue, model, setDiscriminatorValue }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function initScheduleBackup({ getValue, model }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function onScheduleBackupChange({ commit, getValue, discriminator, model }) { - 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 kubedbComClickHouse annotation - deleteKubeDbComMongDbAnnotation(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, - }) - } - } -} - -// backup form -function showBackupForm({ getValue, discriminator, watchDependency }) { - 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({ storeGet, axios, getValue, model, setDiscriminatorValue }) { - // 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/kubedbComClickHouse') - 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, getValue, discriminator }) { - watchDependency('discriminator#/isBackupDataLoaded') - return !!getValue(discriminator, '/isBackupDataLoaded') -} - -async function setBackupType() { - return 'BackupConfig' -} - -async 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?.topology && isArchiverAvailable) { - arr.push({ - description: 'Enable/Disable Archiver', - text: 'Archiver', - value: 'Archiver', - }) - } - return arr -} - -function onBackupTypeChange({ commit, getValue, discriminator }) { - 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/kubedbComClickHouse', - value: objectCopy(dbResource), - force: true, - }) -} - -function isBackupType({ watchDependency, getValue, discriminator }, 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({ getValue, discriminator, commit, model, storeGet }) { - const blueprintSwitch = getValue(discriminator, '/blueprintEnabled') - if (blueprintSwitch) addLabelAnnotation(commit, storeGet, 'annotations') - else deleteLabelAnnotation(commit, 'annotations') -} - -function setArchiverSwitch() { - const archiver = dbResource?.spec?.archiver - return !!archiver -} - -function onArchiverChange({ getValue, discriminator, commit, model, storeGet }) { - const archiverSwitch = getValue(discriminator, '/archiverEnabled') - const path = 'resources/kubedbComClickHouse/spec/archiver' - if (archiverSwitch) { - commit('wizard/model$update', { - path: path, - value: initialArchiver ? initialArchiver : archiverObjectToCommit, - }) - } else { - commit('wizard/model$delete', path) - } -} -function addLabelAnnotation(commit, storeGet, 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/kubedbComClickHouse/metadata/${type}`, - value: obj, - force: true, - }) -} - -function deleteLabelAnnotation(commit, 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/kubedbComClickHouse/metadata/${type}`, - value: obj, - force: true, - }) -} - -function getContext() { - if (isBackupOn) return ['Create', 'Delete', 'Modify'] - return ['Create'] -} - -function onContextChange({ getValue, discriminator, commit, model }) { - 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, - }) - } -} - -function getConfigList({ storeGet }) { - 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({ getValue, discriminator, commit, storeGet, model }) { - 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, getValue, discriminator }) { - watchDependency('discriminator#/backupConfigContext') - watchDependency('discriminator#/config') - const contex = getValue(discriminator, '/backupConfigContext') - const configName = getValue(discriminator, '/config') - return !!configName && contex === 'Modify' -} - -function showConfigList({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/backupConfigContext') - const contex = getValue(discriminator, '/backupConfigContext') - return contex === 'Modify' || contex === 'Delete' -} - -function showSchedule({ watchDependency, getValue, discriminator }) { - 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 getNamespaceArray() { - return namespaceList -} - -// invoker form -function initBackupInvoker() { - return 'backupConfiguration' -} - -function initBlueprint() { - return 'create' -} -function initUsagePolicy() { - return 'Same' -} - -function onBackupInvokerChange({ getValue, discriminator, commit, model, storeGet }) { - const kind = storeGet('/resource/layout/result/resource/kind') - const backupInvoker = getValue(discriminator, '/backupInvoker') - const annotations = getValue(model, '/resources/kubedbComClickHouse/metadata/annotations') - - // get name namespace labels to set in db resource when backup is not enabled initially - - if (backupInvoker === 'backupConfiguration') { - commit('wizard/model$update', { - path: '/resources/coreKubestashComBackupConfiguration', - value: initialModel, - force: true, - }) - - if ( - !dbResource.metadata?.annotations?.['blueprint.kubestash.com/name'] && - !dbResource.metadata?.annotations?.['blueprint.kubestash.com/namespace'] - ) { - delete annotations['blueprint.kubestash.com/name'] - delete annotations['blueprint.kubestash.com/namespace'] - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/metadata/annotations', - value: annotations, - force: true, - }) - } - } else if (backupInvoker === 'backupBlueprint') { - if (!isBackupOn) { - commit('wizard/model$delete', '/resources/coreKubestashComBackupConfiguration') - } - annotations['blueprint.kubestash.com/name'] = `${kind.toLowerCase()}-blueprint` - annotations['blueprint.kubestash.com/namespace'] = 'kubedb' - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/metadata/annotations', - value: annotations, - force: true, - }) - } -} - -function showInvokerForm({ getValue, discriminator, watchDependency }, value) { - const backupInvoker = getValue(discriminator, '/backupInvoker') - watchDependency('discriminator#/backupInvoker') - - return backupInvoker === value -} - -// backup configuration form -function initalizeTargetReferenceName({ getValue, model, watchDependency }) { - const databaseName = getValue(model, '/metadata/release/name') - watchDependency('model#/metadata/release/name') - - return databaseName -} - -// restore session repository -function setInitialRestoreSessionRepo({ getValue, model }) { - const value = getValue(model, 'resources/stashAppscodeComRepository_init_repo') - return value ? 'create' : 'select' -} - -// backup config repository -function initRepositoryChoise({ getValue, model }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - - if (stashAppscodeComRepository_repo) return 'create' - else return 'select' -} - -function initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' - setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) - - return repoInitialSelectionStatus -} - -function onRepositoryChoiseChange({ getValue, discriminator, watchDependency, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - if (repositoryChoise === 'select') { - // delete the stashAppscodeComRepository_repo - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') - } else if (repositoryChoise === 'create') { - // create new stashAppscodeComRepository_repo - if (!valueExists(model, getValue, '/resources/stashAppscodeComRepository_repo')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRepository_repo', - value: stashAppscodeComRepository_repo, - }) - const repositoryName = `${getValue(model, '/metadata/release/name')}-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) - } - } -} - -function onRepositoryNameChange({ getValue, model, commit }) { - const repositoryName = getValue(model, 'resources/stashAppscodeComRepository_repo/metadata/name') - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) -} - -function onInputChange( - { getValue, discriminator, commit, model }, - modelPath, - field, - subfield, - discriminatorName, -) { - const value = getValue(discriminator, `/${discriminatorName}`) - const backends = getValue(model, modelPath) || [] - if (field !== 'encryptionSecret') backends[0][field][subfield] = value - else backends[0]['repositories'][0][field][subfield] = value - commit('wizard/model$update', { - path: modelPath, - value: backends, - }) -} -function setFileValueFromStash({ getValue, commit, model }, modelPath, field, subfield, value) { - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') backends[0][field][subfield] = value - else backends[0]['repositories'][0][field][subfield] = value - commit('wizard/model$update', { - path: modelPath, - value: backends, - }) -} - -function onInputChangeSchedule( - { getValue, discriminator, commit, model }, - modelPath, - discriminatorName, -) { - const value = getValue(discriminator, `/${discriminatorName}`) - const session = getValue(model, modelPath) - session[0].scheduler.schedule = value - commit('wizard/model$update', { - path: modelPath, - value: session, - }) -} - -function setInitSchedule( - { getValue, discriminator, watchDependency, commit, model }, - modelPath, - value, -) { - const session = getValue(model, modelPath) - session[0].scheduler.schedule = value - commit('wizard/model$update', { - path: modelPath, - value: session, - }) -} - -function getDefault({ getValue, model }, modelPath, field, subfield) { - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') return backends[0][field][subfield] - else { - return backends[0]['repositories'][0][field][subfield] - } -} - -function getDefaultSchedule({ getValue, model, watchDependency }, modelPath) { - watchDependency('discriminator#/config') - const session = getValue(model, modelPath) - return session?.length ? session[0]?.scheduler.schedule : '' -} - -// backup blueprint form -function getMongoAnnotations(getValue, model) { - const annotations = getValue(model, '/resources/kubedbComClickHouse/metadata/annotations') - return { ...annotations } || {} -} - -function initFromAnnotationValue({ getValue, model }, key) { - const annotations = getMongoAnnotations(getValue, model) - return annotations[key] -} - -function onBackupBlueprintNameChange({ getValue, discriminator, commit, model }) { - const backupBlueprintName = getValue(discriminator, '/backupBlueprintName') - addKubeDbComMongDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/backup-blueprint', - backupBlueprintName, - true, - ) -} - -function onBackupBlueprintScheduleChange({ getValue, discriminator, commit, model }) { - const backupBlueprintSchedule = getValue(discriminator, '/schedule') - addKubeDbComMongDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/schedule', - backupBlueprintSchedule, - true, - ) -} - -function initFromAnnotationKeyValue({ getValue, model }, prefix) { - const annotations = getMongoAnnotations(getValue, model) - const newOb = {} - Object.keys(annotations).forEach((key) => { - if (key.startsWith(prefix)) { - const newKey = key.replace(prefix, '') - newOb[newKey] = annotations[key] - } - }) - return newOb -} - -function onTaskParametersChange({ getValue, discriminator, model, commit }) { - const taskParameters = getValue(discriminator, '/taskParameters') - - const taskParamterKeys = Object.keys(taskParameters).map( - (tp) => `params.stash.appscode.com/${tp}`, - ) - const oldAnnotations = - getValue(model, '/resources/kubedbComClickHouse/metadata/annotations') || {} - const newAnnotations = {} - - const filteredAnnotationKeys = Object.keys(oldAnnotations).filter( - (key) => !taskParamterKeys.includes(key) && !key.startsWith('params.stash.appscode.com/'), - ) - - filteredAnnotationKeys.forEach((key) => { - newAnnotations[key] = oldAnnotations[key] - }) - - Object.keys(taskParameters).forEach((tpk) => { - newAnnotations[`params.stash.appscode.com/${tpk}`] = taskParameters[tpk] - }) - - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/metadata/annotations', - value: newAnnotations, - }) -} - -function isValueExistInModel({ model, getValue }, path) { - const modelValue = getValue(model, path) - return !!modelValue -} - -function onNamespaceChange({ commit, model, getValue }) { - const namespace = getValue(model, '/metadata/release/namespace') - const agent = getValue(model, '/resources/kubedbComClickHouse/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', - value: [namespace], - force: true, - }) - } -} - -function onLabelChange({ commit, model, getValue }) { - const labels = getValue(model, '/resources/kubedbComClickHouse/spec/metadata/labels') - - const agent = getValue(model, '/resources/kubedbComClickHouse/spec/monitor/agent') - - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) - } -} - -function onNameChange({ commit, model, getValue }) { - const dbName = getValue(model, '/metadata/release/name') - - const agent = getValue(model, '/resources/kubedbComClickHouse/spec/monitor/agent') - - const labels = getValue(model, '/resources/kubedbComClickHouse/spec/metadata/labels') - - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) - } - - const scheduleBackup = getValue(model, '/resources/stashAppscodeComBackupConfiguration') - - if (scheduleBackup) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_repo') - if (creatingNewRepo) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: `${dbName}-repo`, - force: true, - }) - } - } - - const prePopulateDatabase = getValue(model, '/resources/stashAppscodeComRestoreSession_init') - - if (prePopulateDatabase) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_init_repo') - if (creatingNewRepo) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: `${dbName}-init-repo`, - force: true, - }) - } - } - - // to reset configSecret name field - const hasSecretConfig = getValue(model, '/resources/secret_config') - if (hasSecretConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/spec/configSecret/name', - value: `${dbName}-config`, - force: true, - }) - } - - // to reset shard configSecret name field - const hasSecretShardConfig = getValue(model, '/resources/secret_shard_config') - if (hasSecretShardConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/spec/shardTopology/shard/configSecret/name', - value: `${dbName}-shard-config`, - force: true, - }) - } - - // to reset shard configSecret name field - const hasSecretConfigServerConfig = getValue(model, '/resources/secret_configserver_config') - if (hasSecretConfigServerConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/spec/shardTopology/configServer/configSecret/name', - value: `${dbName}-configserver-config`, - force: true, - }) - } - - // to reset mongos configSecret name field - const hasSecretMongosConfig = getValue(model, '/resources/secret_mongos_config') - if (hasSecretMongosConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/spec/shardTopology/mongos/configSecret/name', - value: `${dbName}-mongos-config`, - force: true, - }) - } -} - -function returnFalse() { - return false -} - -function onAgentChange({ commit, model, getValue }) { - const agent = getValue(model, '/resources/kubedbComClickHouse/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', - value: [], - force: true, - }) - - onNamespaceChange({ commit, model, getValue }) - onLabelChange({ commit, model, getValue }) - } else { - commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') - } -} - -/************************************* Database Secret Section ********************************************/ - -function getCreateAuthSecret({ model, getValue }) { - const authSecret = getValue(model, '/resources/kubedbComClickHouse/spec/authSecret') - - return !authSecret -} - -function showExistingSecretSection({ getValue, watchDependency, discriminator }) { - watchDependency('discriminator#/createAuthSecret') - - const hasAuthSecretName = getValue(discriminator, '/createAuthSecret') - return !hasAuthSecretName -} - -function showPasswordSection({ getValue, watchDependency, discriminator }) { - return !showExistingSecretSection({ - getValue, - watchDependency, - discriminator, - }) -} - -function setAuthSecretPassword({ model, getValue }) { - const encodedPassword = getValue(model, '/resources/secret_auth/data/password') - return encodedPassword ? decodePassword({}, encodedPassword) : '' -} +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} -function onAuthSecretPasswordChange({ getValue, discriminator, commit }) { - const stringPassword = getValue(discriminator, '/password') +// ************************* 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('/enableMonitoring', false) + setDiscriminatorValue('/customizeExporter', true) + setDiscriminatorValue('/valueFromType', 'input') + + // 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 autoscaleType = '' + let dbDetails = {} + let instance = {} + + async function getDbDetails() { + const annotations = + getValue(model, '/resources/autoscalingKubedbComClickHouseAutoscaler/metadata/annotations') || + {} + instance = annotations['kubernetes.io/instance-type'] + const owner = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + + const namespace = + storeGet('/route/query/namespace') || + getValue(model, '/resources/autoscalingKubedbComClickHouseAutoscaler/metadata/namespace') || + '' + const name = + storeGet('/route/params/name') || + getValue( + model, + '/resources/autoscalingKubedbComClickHouseAutoscaler/spec/databaseRef/name', + ) || + '' + + if (namespace && name) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/clickhouses/${name}`, + ) + dbDetails = resp.data || {} + + setDiscriminatorValue('/dbDetails', true) + } catch (e) { + console.log(e) + } + } - if (stringPassword) { commit('wizard/model$update', { - path: '/resources/secret_auth/data/password', - value: encodePassword({}, stringPassword), + path: `/metadata/release/name`, + value: name, force: true, }) commit('wizard/model$update', { - path: '/resources/secret_auth/data/username', - value: encodePassword({}, 'root'), + path: `/metadata/release/namespace`, + value: namespace, force: true, }) - } else { - commit('wizard/model$delete', '/resources/secret_auth') - } -} - -// eslint-disable-next-line no-empty-pattern -function encodePassword({}, value) { - return btoa(value) -} - -// eslint-disable-next-line no-empty-pattern -function decodePassword({}, value) { - return atob(value) -} - -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/resources/kubedbComClickHouse/spec/authSecret') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/resources/secret_auth') - } -} - -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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) + commit('wizard/model$update', { + path: `/resources/autoscalingKubedbComClickHouseAutoscaler/spec/databaseRef/name`, + value: name, + force: true, }) - - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + commit('wizard/model$update', { + path: `/resources/autoscalingKubedbComClickHouseAutoscaler/metadata/labels`, + value: dbDetails.metadata.labels, + force: true, }) - return filteredSecrets - } catch (e) { - console.log(e) - return [] } -} -//////////////////////////////////////// Service Monitor ////////////////////////////////////////////////////// - -//////////////////// service monitor /////////////////// + function isKubedb() { + return !!storeGet('/route/params/actions') + } -function isEqualToServiceMonitorType({ rootModel, watchDependency }, value) { - watchDependency('rootModel#/spec/type') - return rootModel && rootModel.spec && rootModel.spec.type === value -} + function isConsole() { + const isKube = isKubedb() -//////////////////// custom config ///////////////// -function onConfigurationSourceChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSource') - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_config') - } else { - const value = getValue(model, '/resources/secret_config') - if (!value) { + if (isKube) { + const dbName = storeGet('/route/params/name') || '' + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComClickHouseAutoscaler/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/secret_config', - value: {}, + path: '/resources/autoscalingKubedbComClickHouseAutoscaler/metadata/name', + value: modifiedName, force: true, }) + const namespace = storeGet('/route/query/namespace') || '' + if (namespace) { + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComClickHouseAutoscaler/metadata/namespace', + value: namespace, + force: true, + }) + } } - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/spec/configSecret/name', - value: configSecretName, - force: true, - }) - } -} - -function onConfigurationChange({ getValue, commit, discriminator, model }) { - const value = getValue(discriminator, '/configuration') - commit('wizard/model$update', { - path: '/resources/secret_config/stringData/mongod.conf', - value: value, - force: true, - }) - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/spec/configSecret/name', - value: configSecretName, - force: true, - }) -} -function setConfigurationSource({ model, getValue }) { - const modelValue = getValue(model, '/resources/secret_config') - if (modelValue) { - return 'create-new-config' + return !isKube } - return 'use-existing-config' -} - -function setSecretConfigNamespace({ getValue, model, watchDependency }) { - watchDependency('model#/metadata/release/namespace') - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} -//////////////////// custom config for sharded topology ///////////////// + async function getNamespaces() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function setConfigurationSourceShard({ model, getValue, discriminator }) { - const src = getValue(discriminator, '/configurationSourceShard') - if (src) return src - const value = getValue(model, '/resources/secret_shard_config') - return value ? 'create-new-config' : 'use-existing-config' -} - -function setConfigurationSourceConfigServer({ model, getValue, discriminator }) { - const src = getValue(discriminator, '/configurationSourceConfigServer') - if (src) return src - const value = getValue(model, '/resources/secret_configserver_config') - return value ? 'create-new-config' : 'use-existing-config' -} + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, + }) -function setConfigurationSourceMongos({ model, getValue, discriminator }) { - const src = getValue(discriminator, '/configurationSourceMongos') - if (src) return src - const value = getValue(model, '/resources/secret_mongos_config') - return value ? 'create-new-config' : 'use-existing-config' -} + const resources = (resp && resp.data && resp.data.items) || [] -function isSchemaOf(schema) { - if (schema === 'discriminator#/configurationSourceShard') { - return 'shard' - } else if (schema === 'discriminator#/configurationSourceConfigServer') { - return 'configserver' - } else { - return 'mongos' + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) } -} -function disableConfigSourceOption({ - itemCtx, - discriminator, - getValue, - watchDependency, - elementUi, -}) { - watchDependency('discriminator#/configurationSourceShard') - watchDependency('discriminator#/configurationSourceConfigServer') - watchDependency('discriminator#/configurationSourceMongos') - const configSrcShard = getValue(discriminator, '/configurationSourceShard') - const configSrcConfigServer = getValue(discriminator, '/configurationSourceConfigServer') - const configSrcMongos = getValue(discriminator, '/configurationSourceMongos') - if ( - itemCtx.value !== 'use-existing-config' && - itemCtx.value !== 'create-new-config' && - (configSrcShard === `same-as-${isSchemaOf(elementUi.schema.$ref)}-config-secret` || - configSrcConfigServer === `same-as-${isSchemaOf(elementUi.schema.$ref)}-config-secret` || - configSrcMongos === `same-as-${isSchemaOf(elementUi.schema.$ref)}-config-secret`) - ) { - return true - } - if ( - itemCtx.value === 'same-as-shard-config-secret' && - configSrcShard !== 'use-existing-config' && - configSrcShard !== 'create-new-config' - ) { - return true + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found } - if ( - itemCtx.value === 'same-as-configserver-config-secret' && - configSrcConfigServer !== 'use-existing-config' && - configSrcConfigServer !== 'create-new-config' - ) { - return true - } - if ( - itemCtx.value === 'same-as-mongos-config-secret' && - configSrcMongos !== 'use-existing-config' && - configSrcMongos !== 'create-new-config' - ) { - return true - } - return false -} -function onConfigurationSourceMongosChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSourceMongos') - const configSecretName = `${getValue(model, '/metadata/release/name')}-mongos-config` - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_mongos_config') - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'mongos', - configurationSource, - '/configurationMongos', - ) - } else if (configurationSource === 'create-new-config') { - const value = getValue(model, '/resources/secret_mongos_config') - if (!value) { + function onNamespaceChange() { + const namespace = getValue(model, '/metadata/release/namespace') + const agent = getValue(model, '/resources/kubedbComClickHouse/spec/monitor/agent') + if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: '/resources/secret_mongos_config', - value: {}, + path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + value: [namespace], force: true, }) } - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/spec/shardTopology/mongos/configSecret/name', - value: configSecretName, - force: true, - }) - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'mongos', - configurationSource, - '/configurationMongos', - ) - } else if (configurationSource === 'same-as-shard-config-secret') { - transferConfigSecret({ commit, model, getValue }, 'shard', 'mongos') - } else if (configurationSource === 'same-as-configserver-config-secret') { - transferConfigSecret({ commit, model, getValue }, 'configserver', 'mongos') } -} -function onConfigurationSourceShardChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSourceShard') - const configSecretName = `${getValue(model, '/metadata/release/name')}-shard-config` - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_shard_config') - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'shard', - configurationSource, - '/configurationShard', - ) - } else if (configurationSource === 'create-new-config') { - const value = getValue(model, '/resources/secret_shard_config') - if (!value) { + function initMetadata() { + const dbName = + getValue( + model, + '/resources/autoscalingKubedbComClickHouseAutoscaler/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/secret_shard_config', - value: {}, + path: '/resources/autoscalingKubedbComClickHouseAutoscaler/metadata/name', + value: modifiedName, force: true, }) - } - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/spec/shardTopology/shard/configSecret/name', - value: configSecretName, - force: true, - }) - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'shard', - configurationSource, - '/configurationShard', - ) - } else if (configurationSource === 'same-as-configserver-config-secret') { - transferConfigSecret({ commit, model, getValue }, 'configserver', 'shard') - } else if (configurationSource === 'same-as-mongos-config-secret') { - transferConfigSecret({ commit, model, getValue }, 'mongos', 'shard') - } -} -function onConfigurationSourceConfigServerChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSourceConfigServer') - const configSecretName = `${getValue(model, '/metadata/release/name')}-configserver-config` - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_configserver_config') - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'configserver', - configurationSource, - '/configurationConfigServer', - ) - } else if (configurationSource === 'create-new-config') { - const value = getValue(model, '/resources/secret_configserver_config') - if (!value) { - commit('wizard/model$update', { - path: '/resources/secret_configserver_config', - value: {}, - force: true, - }) - } - commit('wizard/model$update', { - path: '/resources/kubedbComClickHouse/spec/shardTopology/configServer/configSecret/name', - value: configSecretName, - force: true, - }) - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'configserver', - configurationSource, - '/configurationConfigServer', - ) - } else if (configurationSource === 'same-as-shard-config-secret') { - const configurationSourceReference = getValue(discriminator, '/configurationSourceShard') - transferConfigSecret( - { commit, model, getValue }, - 'shard', - 'configserver', - configurationSourceReference, - ) - } else if (configurationSource === 'same-as-mongos-config-secret') { - const configurationSourceReference = getValue(discriminator, '/configurationSourceMongos') - transferConfigSecret( - { commit, model, getValue }, - 'mongos', - 'configserver', - configurationSourceReference, - ) + // delete the other type object from vuex wizard model + if (type === 'compute') + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComClickHouseAutoscaler/spec/storage', + ) + if (type === 'storage') + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComClickHouseAutoscaler/spec/compute', + ) } -} -function transferConfigSecret({ commit, model, getValue }, src, des) { - const isShardedMode = getValue(model, '/resources/kubedbComClickHouse/spec/shardTopology') - if (isShardedMode) { - commit('wizard/model$update', { - path: `/resources/kubedbComClickHouse/spec/shardTopology/${ - des === 'configserver' ? 'configServer' : des - }/configSecret/name`, - value: getValue( - model, - `/resources/kubedbComClickHouse/spec/shardTopology/${ - src === 'configserver' ? 'configServer' : src - }/configSecret/name`, - ), - force: true, - }) + async function fetchTopologyMachines() { + const instance = hasAnnotations() - commit('wizard/model$delete', `/resources/secret_${des}_config`) - } -} + 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) -function onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - configType, - configSrc, - discriminatorPath, -) { - if (configSrc === 'create-new-config') { - const value = getValue(discriminator, discriminatorPath) - commit('wizard/model$update', { - path: `/resources/secret_${configType}_config/stringData/mongod.conf`, - value: value, - force: true, - }) + const nodeGroups = resp.data?.spec?.nodeGroups || [] + setDiscriminatorValue('/topologyMachines', nodeGroups) + return nodeGroups + } catch (e) { + console.log(e) + return [] + } + } } - const configSrcShard = getValue(discriminator, '/configurationSourceShard') - const configSrcConfigServer = getValue(discriminator, '/configurationSourceConfigServer') - const configSrcMongos = getValue(discriminator, '/configurationSourceMongos') - if (configSrcShard === `same-as-${configType}-config-secret`) { - transferConfigSecret({ commit, model, getValue }, configType, 'shard') + function setTrigger(path) { + let value = getValue(model, `/resources/${path}`) + if (value) return value + return 'On' } - if (configSrcConfigServer === `same-as-${configType}-config-secret`) { - transferConfigSecret({ commit, model, getValue }, configType, 'configserver') - } - if (configSrcMongos === `same-as-${configType}-config-secret`) { - transferConfigSecret({ commit, model, getValue }, configType, 'mongos') - } -} -function setConfiguration({ model, getValue }) { - return getValue(model, '/resources/secret_config/stringData/mongod.conf') -} + function hasAnnotations() { + const annotations = + getValue(model, '/resources/autoscalingKubedbComClickHouseAutoscaler/metadata/annotations') || + {} + const instance = annotations['kubernetes.io/instance-type'] -function setConfigurationShard({ model, getValue }) { - const value = getValue(model, '/resources/secret_shard_config/stringData/mongod.conf') - return value -} + return !!instance + } -function setConfigurationConfigServer({ model, getValue }) { - const value = getValue(model, '/resources/secret_configserver_config/stringData/mongod.conf') - return value -} + function setAllowedMachine(minmax) { + const mx = instance?.includes(',') ? instance.split(',')[1] : '' + const mn = instance?.includes(',') ? instance.split(',')[0] : '' + const machineName = minmax === 'min' ? mn : mx -function setConfigurationMongos({ model, getValue }) { - const value = getValue(model, '/resources/secret_mongos_config/stringData/mongod.conf') - return value -} + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] + const machineData = nodeGroups.find((item) => item.topologyValue === machineName) + if (machineData) { + return { + machine: machineName, + cpu: machineData.allocatable?.cpu, + memory: machineData.allocatable?.memory, + } + } + return { machine: machineName || '', cpu: '', memory: '' } + } -function setConfigurationFiles({ model, getValue }) { - const value = getValue(model, '/resources/secret_config/data/mongod.conf') - return atob(value) -} + async function getMachines(minmax) { + // watchDependency('discriminator#/topologyMachines') + const depends = minmax === 'min' ? 'max' : 'min' + const dependantPath = `/allowedMachine-${depends}` -function setConfigurationFilesShard({ model, getValue }) { - const value = getValue(model, '/resources/secret_shard_config/data/mongod.conf') - return atob(value) -} + // watchDependency(`discriminator#${dependantPath}`) + const dependantMachineObj = getValue(discriminator, dependantPath) + const dependantMachine = dependantMachineObj?.machine || '' -function setConfigurationFilesConfigServer({ model, getValue }) { - const value = getValue(model, '/resources/secret_configserver_config/data/mongod.conf') - return atob(value) -} + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] -function setConfigurationFilesMongos({ model, getValue }) { - const value = getValue(model, '/resources/secret_mongos_config/data/mongod.conf') - return atob(value) -} + const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) -function onSetCustomConfigChange({ discriminator, getValue, commit }) { - const value = getValue(discriminator, '/setCustomConfig') + 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, + }, + } + }) - if (value === 'no') { - commit('wizard/model$delete', '/resources/kubedbComClickHouse/spec/configSecret') - commit( - 'wizard/model$delete', - '/resources/kubedbComClickHouse/spec/shardTopology/shard/configSecret', - ) - commit( - 'wizard/model$delete', - '/resources/kubedbComClickHouse/spec/shardTopology/configServer/configSecret', + const filteredMachine = machines?.filter((item, ind) => + minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, ) - commit( - 'wizard/model$delete', - '/resources/kubedbComClickHouse/spec/shardTopology/mongos/configSecret', - ) - commit('wizard/model$delete', '/resources/secret_config') - commit('wizard/model$delete', '/resources/secret_shard_config') - commit('wizard/model$delete', '/resources/secret_configserver_config') - commit('wizard/model$delete', '/resources/secret_mongos_config') - } -} - -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + return dependantIndex === -1 ? machines : filteredMachine } -} - -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} -function showScheduleBackup({ storeGet }) { - const operationQuery = storeGet('/route/params/actions') || '' - const isBackupOperation = operationQuery === 'edit-self-backupconfiguration' ? true : false - return !isBackupOperation -} + function onMachineChange(type) { + const annoPath = '/resources/autoscalingKubedbComClickHouseAutoscaler/metadata/annotations' + const annotations = getValue(model, annoPath) || {} + const instance = annotations['kubernetes.io/instance-type'] -///////////////////////// Autoscaler /////////////////// -let autoscaleType = '' -let dbDetails = {} + 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 -function isConsole({ storeGet, commit }) { - const isKube = isKubedb({ storeGet }) + const minMachineAllocatable = minMachineObj + ? { cpu: minMachineObj.cpu, memory: minMachineObj.memory } + : null + const maxMachineAllocatable = maxMachineObj + ? { cpu: maxMachineObj.cpu, memory: maxMachineObj.memory } + : null + const allowedPath = `/resources/autoscalingKubedbComClickHouseAutoscaler/spec/compute/${type}` - if (isKube) { - const dbName = storeGet('/route/params/name') || '' - commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComClickHouseAutoscaler/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/autoscalingKubedbComClickHouseAutoscaler/metadata/name', - value: modifiedName, - force: true, - }) - const namespace = storeGet('/route/query/namespace') || '' - if (namespace) { + 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: '/resources/autoscalingKubedbComClickHouseAutoscaler/metadata/namespace', - value: namespace, + path: annoPath, + value: annotations, force: true, }) } } - return !isKube -} - -function isKubedb({ storeGet }) { - return !!storeGet('/route/params/actions') -} - -function showOpsRequestOptions({ model, getValue, watchDependency, storeGet, discriminator }) { - if (isKubedb({ storeGet }) === true) return true - watchDependency('model#/resources/autoscalingKubedbComClickHouseAutoscaler/spec/databaseRef/name') - watchDependency('discriminator#/autoscalingType') - return ( - !!getValue( - model, - '/resources/autoscalingKubedbComClickHouseAutoscaler/spec/databaseRef/name', - ) && !!getValue(discriminator, '/autoscalingType') - ) -} - -async function getNamespaces({ axios, storeGet }) { - 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({ axios, storeGet, model, getValue, watchDependency }) { - watchDependency('model#/resources/autoscalingKubedbComClickHouseAutoscaler/metadata/namespace') - const namespace = getValue( - model, - '/resources/autoscalingKubedbComClickHouseAutoscaler/metadata/namespace', - ) - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises`, - { - 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 hasNoAnnotations() { + return !hasAnnotations() + } -async function getDbDetails({ commit, setDiscriminatorValue, axios, storeGet, getValue, model }) { - const owner = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - const namespace = - storeGet('/route/query/namespace') || - getValue(model, '/resources/autoscalingKubedbComClickHouseAutoscaler/metadata/namespace') || - '' - const name = - storeGet('/route/params/name') || - getValue(model, '/resources/autoscalingKubedbComClickHouseAutoscaler/spec/databaseRef/name') || - '' + function setControlledResources(type) { + const list = ['cpu', 'memory'] + const path = `/resources/autoscalingKubedbComClickHouseAutoscaler/spec/compute/${type}/controlledResources` + commit('wizard/model$update', { + path: path, + value: list, + force: true, + }) + return list + } - if (namespace && name) { + 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( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/clickhouses/${name}`, - ) - dbDetails = resp.data || {} - setDiscriminatorValue('/dbDetails', true) + 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 [] } - commit('wizard/model$update', { - path: `/metadata/release/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/metadata/release/namespace`, - value: namespace, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComClickHouseAutoscaler/spec/databaseRef/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComClickHouseAutoscaler/metadata/labels`, - value: dbDetails.metadata.labels, - force: true, - }) -} - -async function dbTypeEqualsTo({ watchDependency, commit }, type) { - watchDependency('discriminator#/dbDetails') - - const { spec } = dbDetails || {} - const { topology } = spec || {} - let verd = '' - if (topology) verd = 'topology' - else { - verd = 'combined' + function isNodeTopologySelected() { + // watchDependency( + // 'model#/resources/autoscalingKubedbComClickHouseAutoscaler/spec/compute/nodeTopology/name', + // ) + const nodeTopologyName = + getValue( + model, + '/resources/autoscalingKubedbComClickHouseAutoscaler/spec/compute/nodeTopology/name', + ) || '' + return !!nodeTopologyName.length } - clearSpecModel({ commit }, verd) - return type === verd && spec -} -function clearSpecModel({ commit }, dbtype) { - if (dbtype === 'standalone') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComClickHouseAutoscaler/spec/${autoscaleType}/cluster`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComClickHouseAutoscaler/spec/${autoscaleType}/sentinel`, - ) - } else if (dbtype === 'cluster') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComClickHouseAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComClickHouseAutoscaler/spec/${autoscaleType}/sentinel`, - ) - } else if (dbtype === 'sentinel') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComClickHouseAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComClickHouseAutoscaler/spec/${autoscaleType}/cluster`, + function showOpsRequestOptions() { + if (isKubedb() === true) return true + // watchDependency('model#/resources/autoscalingKubedbComClickHouseAutoscaler/spec/databaseRef/name') + // watchDependency('discriminator#/autoscalingType') + return ( + !!getValue( + model, + '/resources/autoscalingKubedbComClickHouseAutoscaler/spec/databaseRef/name', + ) && !!getValue(discriminator, '/autoscalingType') ) } -} -function initMetadata({ getValue, discriminator, model, commit, storeGet }) { - const dbName = - getValue(model, '/resources/autoscalingKubedbComClickHouseAutoscaler/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/autoscalingKubedbComClickHouseAutoscaler/metadata/name', - value: modifiedName, - force: true, - }) + function setApplyToIfReady() { + return 'IfReady' + } - // delete the other type object from model - if (type === 'compute') - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComClickHouseAutoscaler/spec/storage', - ) - if (type === 'storage') - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComClickHouseAutoscaler/spec/compute', + async function getDbs() { + // watchDependency('model#/resources/autoscalingKubedbComClickHouseAutoscaler/metadata/namespace') + const namespace = getValue( + model, + '/resources/autoscalingKubedbComClickHouseAutoscaler/metadata/namespace', ) -} + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function onNamespaceChange({ model, getValue, commit }) { - const namespace = getValue( - model, - '/resources/autoscalingKubedbComClickHouseAutoscaler/metadata/namespace', - ) - if (!namespace) { - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComClickHouseAutoscaler/spec/databaseRef/name', + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, ) - } -} -function ifScalingTypeEqualsTo( - { storeGet, watchDependency, getValue, discriminator, model }, - type, -) { - watchDependency('discriminator#/autoscalingType') - watchDependency('model#/resources/autoscalingKubedbComClickHouseAutoscaler/spec/databaseRef/name') - - const operation = storeGet('/route/params/actions') || '' - if (operation.length) { - const splitOp = operation.split('-') - if (splitOp.length > 2) autoscaleType = splitOp[2] - } else autoscaleType = getValue(discriminator, '/autoscalingType') || '' - const isDatabaseSelected = !!getValue( - model, - '/resources/autoscalingKubedbComClickHouseAutoscaler/spec/databaseRef/name', - ) - return autoscaleType === type && isDatabaseSelected -} + const resources = (resp && resp.data && resp.data.items) || [] -async function fetchNodeTopology({ axios, storeGet }) { - 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) => { + return resources.map((item) => { const name = (item.metadata && item.metadata.name) || '' - return name + return { + text: name, + value: name, + } }) - return mappedList - } catch (e) { - console.log(e) } - return [] -} - -function isNodeTopologySelected({ watchDependency, model, getValue }) { - watchDependency( - 'model#/resources/autoscalingKubedbComClickHouseAutoscaler/spec/compute/nodeTopology/name', - ) - const nodeTopologyName = - getValue( - model, - '/resources/autoscalingKubedbComClickHouseAutoscaler/spec/compute/nodeTopology/name', - ) || '' - return !!nodeTopologyName.length -} - -function setControlledResources({ commit }, type) { - const list = ['cpu', 'memory'] - const path = `/resources/autoscalingKubedbComClickHouseAutoscaler/spec/compute/${type}/controlledResources` - commit('wizard/model$update', { - path: path, - value: list, - force: true, - }) - return list -} - -function setTrigger({ model, getValue }, path) { - let value = getValue(model, `/resources/${path}`) - if (value) return value - return 'On' -} - -function setApplyToIfReady() { - return 'IfReady' -} -function handleUnit({ commit, model, getValue }, 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' + 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, + }) } - if (!isNaN(threshold)) { - threshold += 'pc' + } else { + if (!isNaN(value)) { + value += 'Gi' + commit('wizard/model$update', { + path: `/resources/${path}`, + value: value, + force: true, + }) } - 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 objectCopy(obj) { - const temp = JSON.stringify(obj) - return JSON.parse(temp) -} - -function getOpsRequestUrl({ storeGet, model, getValue, mode }, 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 + `/create-opsrequest-${reqType.toLowerCase()}?namespace=${namespace}` - - if (mode === 'standalone-step') return pathConstructedForKubedb - else - return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/clickhouseopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` -} - -return { - getOpsRequestUrl, - handleUnit, - isConsole, - getNamespaces, - getDbs, - isKubedb, - getDbDetails, - dbTypeEqualsTo, - clearSpecModel, - initMetadata, - onNamespaceChange, - ifScalingTypeEqualsTo, - fetchNodeTopology, - isNodeTopologySelected, - setControlledResources, - setTrigger, - setApplyToIfReady, - showOpsRequestOptions, - setInitSchedule, - fetchNames, - fetchNamespaces, - isRancherManaged, - onInputChangeSchedule, - getDefaultSchedule, - getBlueprints, - ifUsagePolicy, - initUsagePolicy, - isBlueprintOption, - initBlueprint, - getDefault, - onInputChange, - showBackupOptions, - showScheduleBackup, - isVariantAvailable, - fetchJsons, - disableLableChecker, - isEqualToModelPathValue, - getResources, - isEqualToDiscriminatorPath, - setValueFromModel, - isNotShardModeSelected, - isShardModeSelected, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - returnTrue, - returnStringYes, - getMongoDbVersions, - showAuthPasswordField, - showAuthSecretField, - showNewSecretCreateField, - isNotStandaloneMode, - showCommonStorageClassAndSizeField, - setDatabaseMode, - getStorageClassNames, - setStorageClass, - deleteDatabaseModePath, - isEqualToDatabaseMode, - setApiGroup, - getIssuerRefsName, - hasIssuerRefName, - hasNoIssuerRefName, - setClusterAuthMode, - setSSLMode, - showTlsConfigureSection, - onTlsConfigureChange, - getAliasOptions, - showMonitoringSection, - onEnableMonitoringChange, - showCustomizeExporterSection, - onCustomizeExporterChange, - disableInitializationSection, - valueExists, - initPrePopulateDatabase, - onPrePopulateDatabaseChange, - initDataSource, - onDataSourceChange, - initVolumeType, - onVolumeTypeChange, - showInitializationForm, - showScriptOrStashForm, - showConfigMapOrSecretName, - initializeNamespace, - showRepositorySelectOrCreate, - onInitRepositoryChoiseChange, - initCustomizeRestoreJobRuntimeSettings, - initCustomizeRestoreJobRuntimeSettingsForBackup, - onCustomizeRestoreJobRuntimeSettingsChange, - onCustomizeRestoreJobRuntimeSettingsChangeForBackup, - showRuntimeForm, - getImagePullSecrets, - getBackupConfigsAndAnnotations, - deleteKubeDbComMongDbAnnotation, - addKubeDbComMongDbAnnotation, - initScheduleBackup, - initScheduleBackupForEdit, - onScheduleBackupChange, - showBackupForm, - initBackupInvoker, - onBackupInvokerChange, - showInvokerForm, - initalizeTargetReferenceName, - setInitialRestoreSessionRepo, - initRepositoryChoise, - initRepositoryChoiseForEdit, - onRepositoryChoiseChange, - onRepositoryNameChange, - getMongoAnnotations, - initFromAnnotationValue, - onBackupBlueprintNameChange, - onBackupBlueprintScheduleChange, - initFromAnnotationKeyValue, - onTaskParametersChange, - isValueExistInModel, - onNamespaceChange, - onLabelChange, - onNameChange, - returnFalse, - onAgentChange, - getCreateAuthSecret, - showExistingSecretSection, - showPasswordSection, - setAuthSecretPassword, - onAuthSecretPasswordChange, - encodePassword, - decodePassword, - onCreateAuthSecretChange, - getSecrets, - isEqualToServiceMonitorType, - onConfigurationSourceChange, - onConfigurationChange, - setConfigurationSource, - setSecretConfigNamespace, - setConfigurationSourceShard, - setConfigurationSourceConfigServer, - setConfigurationSourceMongos, - isSchemaOf, - disableConfigSourceOption, - onConfigurationSourceMongosChange, - onConfigurationSourceShardChange, - onConfigurationSourceConfigServerChange, - transferConfigSecret, - onConfigSecretModelChange, - setConfiguration, - setConfigurationShard, - setConfigurationConfigServer, - setConfigurationMongos, - setConfigurationFiles, - setConfigurationFilesShard, - setConfigurationFilesConfigServer, - setConfigurationFilesMongos, - onSetCustomConfigChange, - getCreateNameSpaceUrl, - updateConfigServerStorageClass, - - initBackupData, - isBackupDataLoadedTrue, - setBackupType, - getTypes, - getNamespaceArray, - isBackupType, - getContext, - onContextChange, - getConfigList, - onConfigChange, - showPause, - showSchedule, - showConfigList, - setBlueprintSwitch, - onBlueprintChange, - setArchiverSwitch, - onArchiverChange, - onBackupTypeChange, + return { + getDbDetails, + isKubedb, + isConsole, + getNamespaces, + isRancherManaged, + onNamespaceChange, + initMetadata, + fetchTopologyMachines, + setTrigger, + hasAnnotations, + setAllowedMachine, + getMachines, + onMachineChange, + hasNoAnnotations, + setControlledResources, + fetchNodeTopology, + isNodeTopologySelected, + showOpsRequestOptions, + setApplyToIfReady, + getDbs, + handleUnit, + } } diff --git a/charts/kubedbcom-druid-editor-options/ui/create-ui.yaml b/charts/kubedbcom-druid-editor-options/ui/create-ui.yaml index 5451918561..f89c080af4 100644 --- a/charts/kubedbcom-druid-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-druid-editor-options/ui/create-ui.yaml @@ -1,479 +1,526 @@ -steps: -- form: - discriminator: - bundleApiLoaded: - default: false - type: boolean +step: +- type: single-step-form + loader: initBundle + elements: + - type: label-element + label: '' + subtitle: Select the Druid version you want to deploy on Kubernetes. The chosen version determines the Druid engine features, compatibility, and runtime behavior of your analytics database. + - disableUnselect: true + loader: getAdminOptions|databases/Druid/versions + if: + type: function + name: isToggleOn|databases/Druid/versions + label: Database Version + schema: schema/properties/spec/properties/admin/properties/databases/properties/Druid/properties/versions/properties/default + type: select + - elements: + - elements: + - type: label-element + label: '' + subtitle: Middle Manager nodes handle data ingestion tasks. Configure storage, replicas, and resource allocation for efficient data processing and ingestion workloads. + - type: horizontal-layout + showLabels: true + elements: + - label: Storage Size + schema: schema/properties/spec/properties/topology/properties/middleManagers/properties/persistence/properties/size + type: input + - label: Replicaset Number + schema: schema/properties/spec/properties/topology/properties/middleManagers/properties/replicas + type: input + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/topology/properties/middleManagers/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu|topology/middleManagers + disable: isMachineNotCustom|topology/middleManagers + if: + type: function + name: isMachineCustom|topology/middleManagers + label: CPU + loader: setLimits|cpu|topology/middleManagers + watcher: + func: setRequests|cpu|topology/middleManagers + paths: + - schema/properties/spec/properties/topology/properties/middleManagers/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/topology/properties/middleManagers/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/middleManagers/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory|topology/middleManagers + disable: isMachineNotCustom|topology/middleManagers + if: + type: function + name: isMachineCustom|topology/middleManagers + label: Memory + loader: setLimits|memory|topology/middleManagers + watcher: + func: setRequests|memory|topology/middleManagers + paths: + - schema/properties/spec/properties/topology/properties/middleManagers/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/topology/properties/middleManagers/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/middleManagers/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + label: Middle Managers + showLabels: true + type: block-layout + - elements: + - type: label-element + label: '' + subtitle: Historical nodes serve cached and historical data segments. Configure storage, replicas, and resource allocation for optimal query performance on historical data. + - type: horizontal-layout + showLabels: true + elements: + - label: Storage Size + schema: schema/properties/spec/properties/topology/properties/historicals/properties/persistence/properties/size + type: input + - label: Replicaset Number + schema: schema/properties/spec/properties/topology/properties/historicals/properties/replicas + type: input + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/topology/properties/historicals/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu|topology/historicals + disable: isMachineNotCustom|topology/historicals + if: + type: function + name: isMachineCustom|topology/historicals + label: CPU + loader: setLimits|cpu|topology/historicals + watcher: + func: setRequests|cpu|topology/historicals + paths: + - schema/properties/spec/properties/topology/properties/historicals/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/topology/properties/historicals/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/historicals/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory|topology/historicals + disable: isMachineNotCustom|topology/historicals + if: + type: function + name: isMachineCustom|topology/historicals + label: Memory + loader: setLimits|memory|topology/historicals + watcher: + func: setRequests|memory|topology/historicals + paths: + - schema/properties/spec/properties/topology/properties/historicals/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/topology/properties/historicals/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/historicals/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + label: Historicals + showLabels: true + type: block-layout + - elements: + - type: label-element + label: '' + subtitle: Broker nodes handle client queries and route them to appropriate data nodes. Configure replicas and resource allocation for efficient query handling and routing. + - label: Replicaset Number + schema: schema/properties/spec/properties/topology/properties/brokers/properties/replicas + type: input + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/topology/properties/brokers/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu|topology/brokers + disable: isMachineNotCustom|topology/brokers + if: + type: function + name: isMachineCustom|topology/brokers + label: CPU + loader: setLimits|cpu|topology/brokers + watcher: + func: setRequests|cpu|topology/brokers + paths: + - schema/properties/spec/properties/topology/properties/brokers/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/topology/properties/brokers/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/brokers/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory|topology/brokers + disable: isMachineNotCustom|topology/brokers + if: + type: function + name: isMachineCustom|topology/brokers + label: Memory + loader: setLimits|memory|topology/brokers + watcher: + func: setRequests|memory|topology/brokers + paths: + - schema/properties/spec/properties/topology/properties/brokers/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/topology/properties/brokers/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/brokers/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + label: Brokers + showLabels: true + type: block-layout + - elements: + - type: label-element + label: '' + subtitle: Coordinator nodes manage data availability and segment distribution across the cluster. Configure replicas and resource allocation for reliable cluster coordination. + - label: Replicaset Number + schema: schema/properties/spec/properties/topology/properties/coordinators/properties/replicas + type: input + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/topology/properties/coordinators/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu|topology/coordinators + disable: isMachineNotCustom|topology/coordinators + if: + type: function + name: isMachineCustom|topology/coordinators + label: CPU + loader: setLimits|cpu|topology/coordinators + watcher: + func: setRequests|cpu|topology/coordinators + paths: + - schema/properties/spec/properties/topology/properties/coordinators/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/topology/properties/coordinators/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/coordinators/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory|topology/coordinators + disable: isMachineNotCustom|topology/coordinators + if: + type: function + name: isMachineCustom|topology/coordinators + label: Memory + loader: setLimits|memory|topology/coordinators + watcher: + func: setRequests|memory|topology/coordinators + paths: + - schema/properties/spec/properties/topology/properties/coordinators/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/topology/properties/coordinators/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/coordinators/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + label: Coordinators + showLabels: true + type: block-layout + type: block-layout + - type: horizontal-layout + showLabels: true + elements: + - loader: getAdminOptions|storageClasses + if: + type: function + name: isToggleOn|storageClasses + label: Storage Class + schema: schema/properties/spec/properties/admin/properties/storageClasses/properties/default + type: select + - label: Deep Storage + options: + - s3 + - google + - azure + - hdfs + schema: schema/properties/spec/properties/deepStorage/properties/type + type: select + - loader: getSecrets + label: Config Secret + refresh: true + schema: schema/properties/spec/properties/deepStorage/properties/configSecret + type: select + - description: Configure Credentials, Deployment Mode etc. elements: - - computed: initBundle - if: returnFalse - type: label-element - - disableUnselect: true - fetch: getAdminOptions|databases/Druid/versions - if: isToggleOn|databases/Druid/versions - label: - text: labels.database.version - schema: - $ref: schema#/properties/spec/properties/admin/properties/databases/properties/Druid/properties/versions/properties/default - type: select - elements: - - elements: - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/topology/properties/middleManagers/properties/persistence/properties/size - type: input - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/topology/properties/middleManagers/properties/replicas - type: input - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/topology/properties/middleManagers/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu|topology/middleManagers - disabled: isMachineNotCustom|topology/middleManagers - if: isMachineCustom|topology/middleManagers - label: - text: labels.cpu - onChange: setRequests|cpu|topology/middleManagers - schema: - $ref: schema#/properties/spec/properties/topology/properties/middleManagers/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory|topology/middleManagers - disabled: isMachineNotCustom|topology/middleManagers - if: isMachineCustom|topology/middleManagers - label: - text: labels.memory - onChange: setRequests|memory|topology/middleManagers - schema: - $ref: schema#/properties/spec/properties/topology/properties/middleManagers/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - label: - text: labels.middleManagers - show_label: true - type: single-step-form - - elements: - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/topology/properties/historicals/properties/persistence/properties/size - type: input - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/topology/properties/historicals/properties/replicas - type: input - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/topology/properties/historicals/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu|topology/historicals - disabled: isMachineNotCustom|topology/historicals - if: isMachineCustom||topology/historicals - label: - text: labels.cpu - onChange: setRequests|cpu|topology/historicals - schema: - $ref: schema#/properties/spec/properties/topology/properties/historicals/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory|topology/historicals - disabled: isMachineNotCustom|topology/historicals - if: isMachineCustom||topology/historicals - label: - text: labels.memory - onChange: setRequests|memory|topology/historicals - schema: - $ref: schema#/properties/spec/properties/topology/properties/historicals/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - label: - text: labels.historicals - show_label: true - type: single-step-form - - elements: - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/topology/properties/brokers/properties/replicas - type: input - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/topology/properties/brokers/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu|topology/brokers - disabled: isMachineNotCustom|topology/brokers - if: isMachineCustom|topology/brokers - label: - text: labels.cpu - onChange: setRequests|cpu|topology/middleManagers - schema: - $ref: schema#/properties/spec/properties/topology/properties/brokers/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory|topology/brokers - disabled: isMachineNotCustom|topology/brokers - if: isMachineCustom|topology/brokers - label: - text: labels.memory - onChange: setRequests|memory|topology/brokers - schema: - $ref: schema#/properties/spec/properties/topology/properties/brokers/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - label: - text: labels.brokers - show_label: true - type: single-step-form - - elements: - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/topology/properties/coordinators/properties/replicas - type: input - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/topology/properties/coordinators/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu|topology/coordinators - disabled: isMachineNotCustom|topology/coordinators - if: isMachineCustom|topology/coordinators - label: - text: labels.cpu - onChange: setRequests|cpu|topology/middleManagers - schema: - $ref: schema#/properties/spec/properties/topology/properties/coordinators/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory|topology/coordinators - disabled: isMachineNotCustom|topology/coordinators - if: isMachineCustom|topology/coordinators - label: - text: labels.memory - onChange: setRequests|memory|topology/coordinators - schema: - $ref: schema#/properties/spec/properties/topology/properties/coordinators/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - label: - text: labels.coordinators - show_label: true - type: single-step-form - type: single-step-form - - customClass: mt-10 - fetch: getAdminOptions|storageClasses - if: isToggleOn|storageClasses - label: - text: labels.storage.class - schema: - $ref: schema#/properties/spec/properties/admin/properties/storageClasses/properties/default + - type: label-element + label: '' + subtitle: Add custom labels and annotations to your database resources for organization, monitoring, and integration with other Kubernetes tools and services. + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/annotations + label: Labels & Annotations + showLabels: true + hideBlock: true + type: block-layout + - init: + type: func + value: getDefault|deletionPolicy + customClass: mt-20 + if: + type: function + name: isToggleOn|deletionPolicy + label: Deletion Policy + watcher: + func: setStorageClass + paths: + - schema/properties/spec/properties/deletionPolicy + options: + - description: options.deletionPolicy.delete.description + text: Delete + value: Delete + - description: options.deletionPolicy.halt.description + text: Halt + value: Halt + - description: options.deletionPolicy.wipeOut.description + text: WipeOut + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: DoNotTerminate + value: DoNotTerminate + schema: schema/properties/spec/properties/deletionPolicy type: select - - label: - text: labels.deepStorage + - label: Metadata Storage External + schema: schema/properties/spec/properties/metadataStorage/properties/externallyManaged + type: switch + - if: + type: function + name: isExternallyManaged|metadataStorage + label: Metadata Storage Type + watcher: + func: clearRefs|metadataStorage + paths: + - schema/properties/spec/properties/metadataStorage/properties/type options: - - s3 - - google - - azure - - hdfs - schema: - $ref: schema#/properties/spec/properties/deepStorage/properties/type + - text: MySQL + value: MySQL + - text: Postgres + value: Postgres + schema: schema/properties/spec/properties/metadataStorage/properties/type type: select - - fetch: getSecrets - label: - text: labels.configSecret + - loader: getAppBindings|mysql + if: + type: function + name: isMetadataStorageTypeEqualsTo|MySQL + label: MySQL + watcher: + func: onRefChange|metadataStorage + paths: + - temp/metadataStorage refresh: true - schema: - $ref: schema#/properties/spec/properties/deepStorage/properties/configSecret + validation: + type: required + schema: temp/metadataStorage type: select - - accordion: true - description: - text: Configure Credentials, Deployment Mode etc. - discriminator: - configDatabase: - default: false - type: boolean - createAuthSecret: - default: false - type: boolean - metadataStorage: - default: {} - type: object - referSecret: - default: false - type: boolean - zookeeperRef: - default: {} - type: object - elements: - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties - type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties - type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - computed: getDefault|deletionPolicy - customClass: mt-20 - if: isToggleOn|deletionPolicy - 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/spec/properties/deletionPolicy - type: select - - label: - text: labels.metadataStorage.external - schema: - $ref: schema#/properties/spec/properties/metadataStorage/properties/externallyManaged - type: switch - - if: isExternallyManaged|metadataStorage - label: - text: labels.metadataStorage.type - onChange: clearRefs|metadataStorage - options: - - text: MySQL - value: MySQL - - text: Postgres - value: Postgres - schema: - $ref: schema#/properties/spec/properties/metadataStorage/properties/type - type: select - - fetch: getAppBindings|mysql - if: isMetadataStorageTypeEqualsTo|MySQL - label: - text: labels.metadataStorage.mysql - onChange: onRefChange|metadataStorage - refresh: true - required: true - schema: - $ref: discriminator#/metadataStorage - type: select - - fetch: getAppBindings|postgres - if: isMetadataStorageTypeEqualsTo|Postgres - label: - text: labels.metadataStorage.postgres - onChange: onRefChange|metadataStorage - refresh: true - required: true - schema: - $ref: discriminator#/metadataStorage - type: select - - label: - text: labels.zookeeperRef.external - schema: - $ref: schema#/properties/spec/properties/zookeeperRef/properties/externallyManaged - type: switch - - fetch: getAppBindings|zookeeper - if: isExternallyManaged|zookeeperRef - label: - text: labels.zookeeperRef.zookeeper - onChange: onRefChange|zookeeperRef - refresh: true - required: true - schema: - $ref: discriminator#/zookeeperRef - type: select - - if: getDefaultValue|spec/admin/authCredential/customize - label: - text: Provide Authentication Credentials? - onChange: onAuthChange - schema: - $ref: discriminator#/createAuthSecret - type: switch - - if: showReferSecretSwitch - label: - text: Refer existing Secret? - onChange: onReferSecretChange - schema: - $ref: discriminator#/referSecret - type: switch - - fetch: getReferSecrets - if: showSecretDropdown - label: - text: Secret - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/name - type: select - - if: showReferSecret - label: - text: labels.password - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/password - type: input - - computed: isConfigAvailable - if: getDefaultValue|spec/admin/customConfiguration - label: - text: Configure Database? - onChange: clearConfiguration - schema: - $ref: discriminator#/configDatabase + - loader: getAppBindings|postgres + if: + type: function + name: isMetadataStorageTypeEqualsTo|Postgres + label: Postgres + watcher: + func: onRefChange|metadataStorage + paths: + - temp/metadataStorage + refresh: true + validation: + type: required + schema: temp/metadataStorage + type: select + - label: Zookeeper External + schema: schema/properties/spec/properties/zookeeperRef/properties/externallyManaged + type: switch + - loader: getAppBindings|zookeeper + if: + type: function + name: isExternallyManaged|zookeeperRef + label: Zookeeper + watcher: + func: onRefChange|zookeeperRef + paths: + - temp/zookeeperRef + refresh: true + validation: + type: required + schema: temp/zookeeperRef + type: select + - if: + type: function + name: getDefaultValue|spec/admin/authCredential/customize + label: Provide Authentication Credentials? + watcher: + func: onAuthChange + paths: + - temp/createAuthSecret + schema: temp/createAuthSecret + type: switch + - if: + type: function + name: showReferSecretSwitch + label: Refer existing Secret? + watcher: + func: onReferSecretChange + paths: + - temp/referSecret + schema: temp/referSecret + type: switch + - loader: getReferSecrets + if: + type: function + name: showSecretDropdown + label: Secret + schema: schema/properties/spec/properties/authSecret/properties/name + type: select + - if: + type: function + name: showReferSecret + label: password + schema: schema/properties/spec/properties/authSecret/properties/password + type: input + - if: + type: function + name: getDefaultValue|spec/admin/customConfiguration + label: Configure Database? + watcher: + func: clearConfiguration + paths: + - temp/configDatabase + schema: temp/configDatabase + type: switch + - if: + type: function + name: isConfigDatabaseOn + label: Configuration + # hasCopy: true + schema: schema/properties/spec/properties/configuration + type: textarea + - if: + type: function + name: isToggleOn|deployment + label: Deployment name + options: + - description: labels.deployment.shared + text: Shared + value: Shared + - description: labels.deployment.dedicated + text: Dedicated + value: Dedicated + schema: schema/properties/spec/properties/admin/properties/deployment/properties/default + type: radio + - if: + type: function + name: isToggleOn|clusterTier + isHorizontal: true + label: Cluster Tier + options: + - text: General Purpose + value: GeneralPurpose + - text: Memory Optimized + value: MemoryOptimized + - text: CPU Optimized + value: CPUOptimized + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/default + type: radio + - disableUnselect: true + loader: getAdminOptions|clusterTier/placement + if: + type: function + name: isToggleOn|clusterTier/placement + label: Placement + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + type: select + - disableUnselect: true + loader: getNodeTopology + if: + type: function + name: isToggleOn|clusterTier/nodeTopology + label: Node Topology + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + type: select + label: Advanced Configuration + showLabels: true + type: block-layout + - description: Enable Backup, Monitoring, TLS etc. + elements: + - elements: + - init: + type: func + value: setMonitoring + label: Enable Monitoring? + watcher: + func: updateAlertValue + paths: + - temp/monitoring + schema: temp/monitoring type: switch - - if: isConfigDatabaseOn - label: - text: Configuration - schema: - $ref: schema#/properties/spec/properties/configuration - type: editor - - hasDescription: true - if: isToggleOn|deployment - label: - text: labels.deployment.name - options: - - description: labels.deployment.shared - text: Shared - value: Shared - - description: labels.deployment.dedicated - text: Dedicated - value: Dedicated - schema: - $ref: schema#/properties/spec/properties/admin/properties/deployment/properties/default - type: radio - - if: isToggleOn|clusterTier - isHorizontal: true - label: - text: labels.clusterTier + - customClass: mt-10 + if: + type: function + name: showAlerts + label: Alert Options options: - - text: General Purpose - value: GeneralPurpose - - text: Memory Optimized - value: MemoryOptimized - - text: CPU Optimized - value: CPUOptimized - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/default - type: radio - - disableUnselect: true - fetch: getAdminOptions|clusterTier/placement - if: isToggleOn|clusterTier/placement - label: - text: labels.placement - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + - text: None + value: none + - text: Critical + value: critical + - text: Warning + value: warning + - text: Info + value: info + schema: schema/properties/form/properties/alert/properties/enabled type: select - - disableUnselect: true - fetch: getNodeTopology - if: isToggleOn|clusterTier/nodeTopology - label: - text: labels.nodeTopology - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default - type: select - hideForm: true - label: - text: Advanced Configuration - show_label: true - type: single-step-form - - accordion: true - description: - text: Enable Backup, Monitoring, TLS etc. - discriminator: - backup: - default: false - type: boolean - elements: - - discriminator: - monitoring: - default: false - type: boolean - elements: - - computed: setMonitoring - label: - text: labels.enable_monitoring - onChange: updateAlertValue - schema: - $ref: discriminator#/monitoring - type: switch - - customClass: mt-10 - if: showAlerts - label: - text: labels.alert.options - options: - - text: None - value: none - - text: Critical - value: critical - - text: Warning - value: warning - - text: Info - value: info - schema: - $ref: schema#/properties/form/properties/alert/properties/enabled - sortable: true - type: select - if: isToggleOn|monitoring - type: single-step-form - - computed: setBackup - if: isToggleOn|backup - label: - text: Enable Backup? - onChange: onBackupSwitch - schema: - $ref: discriminator#/backup + if: + type: function + name: isToggleOn|monitoring + type: block-layout + - init: + type: func + value: setBackup + if: + type: function + name: isToggleOn|backup + label: Enable Backup? + watcher: + func: onBackupSwitch + paths: + - temp/backup + schema: temp/backup + type: switch + - elements: + - label: Expose via Gateway? + schema: schema/properties/spec/properties/admin/properties/expose/properties/default type: switch - - elements: - - label: - text: Expose via Gateway? - schema: - $ref: schema#/properties/spec/properties/admin/properties/expose/properties/default - type: switch - if: isToggleOn|expose - type: single-step-form - if: showAdditionalSettings - label: - text: Additional Options - show_label: true - type: single-step-form - type: single-step-form + if: + type: function + name: isToggleOn|expose + type: block-layout + if: + type: function + name: showAdditionalSettings + label: Additional Options + showLabels: true + type: block-layout id: options - title: steps.0.label type: multi-step-form diff --git a/charts/kubedbcom-druid-editor-options/ui/functions.js b/charts/kubedbcom-druid-editor-options/ui/functions.js index 7b6cff6d74..7103b9ce2d 100644 --- a/charts/kubedbcom-druid-editor-options/ui/functions.js +++ b/charts/kubedbcom-druid-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -304,821 +306,869 @@ const machineList = [ 'db.r.24xlarge', ] -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) + + setDiscriminatorValue('bundleApiLoaded', false) + setDiscriminatorValue('configDatabase', false) + setDiscriminatorValue('createAuthSecret', false) + setDiscriminatorValue('metadataStorage', {}) + setDiscriminatorValue('referSecret', false) + setDiscriminatorValue('zookeeperRef', {}) + setDiscriminatorValue('backup', false) + setDiscriminatorValue('monitoring', false) + + let placement = [] + let versions = [] + let storageClass = [] + let clusterIssuers = [] + let nodetopologiesShared = [] + let nodetopologiesDedicated = [] + let features = [] + + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, }, - }, - ) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] + ) + if (resp.data?.status?.projects) { + const projects = resp.data?.status?.projects + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } + } catch (e) { + console.log(e) } - } catch (e) { - console.log(e) + return [] } - return [] -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + 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') - const secrets = (resp && resp.data && resp.data.items) || [] + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }, + ) - const filteredSecrets = secrets.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) + const secrets = (resp && resp.data && resp.data.items) || [] - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return filteredSecrets -} + const filteredSecrets = secrets.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) -function getMachineListForOptions({ model, getValue }) { - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') + filteredSecrets.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true + }) + return filteredSecrets + } let array = [] + function getMachineListForOptions() { + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') - if (available.length) { - array = available.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - else { - let subText = '', - text = '' - const machineData = machinesFromPreset.find((val) => val.id === machine) - if (machineData) { - subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` - text = machineData.name ? machineData.name : machineData.id - } - return { text, subText, value: machine } - } - }) - } else { - array = machineList - .map((machine) => { + if (available.length) { + array = available.map((machine) => { if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + else { + let subText = '', + text = '' + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + text = machineData.name ? machineData.name : machineData.id + } + return { text, subText, value: machine } + } }) - .filter((val) => !!val) + } else { + array = machineList + .map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { text, subText, value: machine } + }) + .filter((val) => !!val) + } + return array } - return array -} -function setLimits({ model, getValue, commit, watchDependency }, resource, type) { - const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' - watchDependency(`model#${path}`) - const selectedMachine = getValue(model, path) || 'custom' - const reqCommitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - const comparePath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - - const resourceValue = getValue(model, comparePath) - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - - let cpu = '', - memory = '' - if (available.length && selectedMachine !== 'custom') { - const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) - if (machineData) { - cpu = machineData.limits.cpu - memory = machineData.limits.memory + function setLimits(resource, type) { + const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' + // watchDependency(`model#${path}`) + const selectedMachine = getValue(model, path) || 'custom' + const reqCommitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + const comparePath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + + const resourceValue = getValue(model, comparePath) + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + let cpu = '', + memory = '' + if (available.length && selectedMachine !== 'custom') { + const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) + if (machineData) { + cpu = machineData.limits.cpu + memory = machineData.limits.memory + } + } else { + if (selectedMachine === 'custom') { + cpu = resourceValue + memory = resourceValue + } else { + cpu = machines[selectedMachine].resources.limits.cpu + memory = machines[selectedMachine].resources.limits.memory + } } - } else { - if (selectedMachine === 'custom') { - cpu = resourceValue - memory = resourceValue + + if (resource === 'memory') { + commit('wizard/model$update', { + path: reqCommitPath, + value: memory, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: memory, + force: true, + }) + return memory } else { - cpu = machines[selectedMachine].resources.limits.cpu - memory = machines[selectedMachine].resources.limits.memory + commit('wizard/model$update', { + path: reqCommitPath, + value: cpu, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: cpu, + force: true, + }) + return cpu } } - if (resource === 'memory') { - commit('wizard/model$update', { - path: reqCommitPath, - value: memory, - force: true, - }) + function setRequests(resource, type) { + const modelPath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + + const fullpath = `/spec/podResources/machine` + const modelPathValue = getValue(model, fullpath) + commit('wizard/model$update', { - path: comparePath, - value: memory, + path: commitPath, + value: val, force: true, }) - return memory - } else { - commit('wizard/model$update', { - path: reqCommitPath, - value: cpu, - force: true, + + if (modelPathValue === 'custom') { + return + } + let commitCpuMemory, ModelPathValue + if (resource && type) { + const fullPath = `/spec/${type}/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/${type}/podResources/resources/requests/${resource}` + } else { + const fullPath = `/spec/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/podResources/resources/requests/${resource}` + } + let cpuMemoryValue + array.forEach((item) => { + if (item.value === ModelPathValue) { + // Parse subText like "CPU: 2, Memory: 2Gi" + const subText = item.subText || '' + if (resource === 'cpu') { + // Extract CPU value + const cpuMatch = subText.match(/CPU:\s*([^,]+)/) + cpuMemoryValue = cpuMatch ? cpuMatch[1].trim() : '' + } else if (resource === 'memory') { + // Extract Memory value + const memoryMatch = subText.match(/Memory:\s*(.+)/) + cpuMemoryValue = memoryMatch ? memoryMatch[1].trim() : '' + } + } }) commit('wizard/model$update', { - path: comparePath, - value: cpu, + path: commitCpuMemory, + value: cpuMemoryValue, force: true, }) - return cpu + return cpuMemoryValue } -} - -function setRequests({ getValue, model, commit }, resource, type) { - const modelPath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - const val = getValue(model, modelPath) - commitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - commit('wizard/model$update', { - path: commitPath, - value: val, - force: true, - }) -} - -function setMachineToCustom({ getValue, model }) { - const machine = getValue(model, '/spec/admin/machineProfiles/default') - return machine || 'custom' -} - -function isMachineCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue === 'custom' -} - -function isMachineNotCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue !== 'custom' && !!modelPathValue -} -function updateAlertValue({ commit, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const alert = isMonitorEnabled ? 'warning' : 'none' - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: alert, - force: true, - }) - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} - -function getCreateNameSpaceUrl({ storeGet }) { - 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + function setMachineToCustom() { + const machine = getValue(model, '/spec/admin/machineProfiles/default') + return machine || 'custom' } -} -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} - -function setStorageClass({ model, getValue, commit, discriminator, watchDependency }) { - const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' - let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' - const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] - const suffix = '-retain' - - const simpleClassList = storageClassList.filter((item) => { - return !item.endsWith(suffix) - }) - - const retainClassList = storageClassList.filter((item) => { - return item.endsWith(suffix) - }) + function isMachineCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue === 'custom' + } - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] - } else { - storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + function isMachineNotCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue !== 'custom' && !!modelPathValue } - const isChangeable = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'storageClasses', - ) - if (isChangeable && storageClass) { + function updateAlertValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const alert = isMonitorEnabled ? 'warning' : 'none' + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: '/spec/admin/storageClasses/default', - value: storageClass, + path: '/form/alert/enabled', + value: alert, + force: true, + }) + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: agent, force: true, }) } -} - -function showAlerts({ watchDependency, model, getValue, discriminator }) { - watchDependency('discriminator#/monitoring') - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const isAlertToggleEnabled = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'alert', - ) - return isMonitorEnabled && isAlertToggleEnabled -} - -function showIssuer({ model, getValue, watchDependency, discriminator }) { - watchDependency('model#/spec/admin/tls/default') - const isTlsEnabled = getValue(model, '/spec/admin/tls/default') - const isIssuerToggleEnabled = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'clusterIssuers', - ) - return isTlsEnabled && isIssuerToggleEnabled -} - -function onBackupSwitch({ discriminator, getValue, commit }) { - const isBackupOn = getValue(discriminator, '/backup') - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: isBackupOn ? 'KubeStash' : '', - force: true, - }) -} - -function setMonitoring({ getValue, model }) { - const agent = getValue(model, '/spec/admin/monitoring/agent') || '' - return !!agent -} - -function setBackup({ model, getValue }) { - const backup = getValue(model, '/spec/backup/tool') - const val = getValue(model, '/spec/admin/backup/enable/default') - return backup === 'KubeStash' && features.includes('backup') && val -} -function onAuthChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/authSecret/password', - value: '', - force: true, - }) -} - -function isConfigDatabaseOn({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configDatabase') - return getValue(discriminator, '/configDatabase') -} + function getCreateNameSpaceUrl() { + const user = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function clearConfiguration({ discriminator, getValue, commit }) { - const configOn = getValue(discriminator, '/configDatabase') - - if (!configOn) { - commit('wizard/model$delete', '/spec/configuration') + const domain = storeGet('/domain') || '' + if (domain.includes('bb.test')) { + return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } } -} -async function getAppBindings({ axios, storeGet }, type) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const queryParams = { - filter: { - items: { - metadata: { name: null, namespace: null }, - spec: { type: null }, - }, - }, + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false } - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/appcatalog.appscode.com/v1alpha1/appbindings`, - queryParams, - ) - const resources = (resp && resp.data && resp.data.items) || [] - - const fileredResources = resources - .filter((item) => item.spec?.type === `kubedb.com/${type}`) - .map((item) => { - const name = item.metadata?.name || '' - const namespace = item.metadata?.namespace || '' - return { - text: `${namespace}/${name}`, - value: { - name: name, - namespace: namespace, - }, - } - }) - return fileredResources - } catch (e) { - console.log(e) - return [] - } -} -function onRefChange({ discriminator, getValue, commit }, type) { - const ref = getValue(discriminator, `/${type}`) || {} - commit('wizard/model$update', { - path: `/spec/${type}/name`, - value: ref.name || '', - force: true, - }) - commit('wizard/model$update', { - path: `/spec/${type}/namespace`, - value: ref.namespace || '', - force: true, - }) -} + function setStorageClass() { + const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' + let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' + const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] + const suffix = '-retain' -function isExternallyManaged( - { getValue, model, watchDependency, commit, setDiscriminatorValue }, - type, -) { - watchDependency(`model#/spec/${type}/externallyManaged`) - const isManaged = getValue(model, `/spec/${type}/externallyManaged`) || false - if (!isManaged) clearRefs({ commit, setDiscriminatorValue }, type) - return isManaged -} + const simpleClassList = storageClassList.filter((item) => { + return !item.endsWith(suffix) + }) -function isMetadataStorageTypeEqualsTo({ getValue, model, watchDependency }, type) { - watchDependency('model#/spec/metadataStorage/type') - watchDependency('model#/spec/metadataStorage/externallyManaged') - const dbType = getValue(model, '/spec/metadataStorage/type') || '' - const isManaged = getValue(model, '/spec/metadataStorage/externallyManaged') || false - return isManaged && dbType === type -} + const retainClassList = storageClassList.filter((item) => { + return item.endsWith(suffix) + }) -function clearRefs({ commit, setDiscriminatorValue }, type) { - setDiscriminatorValue(`/${type}`, '') - commit('wizard/model$update', { - path: `/spec/${type}/name`, - value: '', - force: true, - }) - commit('wizard/model$update', { - path: `/spec/${type}/namespace`, - value: '', - force: true, - }) -} + if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { + storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] + } else { + storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + } -let placement = [] -let versions = [] -let storageClass = [] -let clusterIssuers = [] -let nodetopologiesShared = [] -let nodetopologiesDedicated = [] -let features = [] -async function initBundle({ commit, model, getValue, axios, storeGet, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - - let db = getValue(model, '/metadata/resource/kind') - db = db.toLowerCase() - let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` - const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - try { - const resp = await axios.get(url) - features = resp.data.features || [] - placement = resp.data.placementpolicies || [] - versions = resp.data.versions || [] - storageClass = resp.data.storageclasses || [] - clusterIssuers = resp.data.clusterissuers || [] - nodetopologiesDedicated = resp.data.dedicated || [] - nodetopologiesShared = resp.data.shared || [] - - const response = await axios.get(annotationUrl) - const annotations = response.data?.metadata?.annotations || {} - const uidRange = annotations['openshift.io/sa.scc.uid-range'] - if (uidRange) { - const val = uidRange.split('/')[0] + const isChangeable = isToggleOn('storageClasses') + if (isChangeable && storageClass) { commit('wizard/model$update', { - path: '/spec/openshift/securityContext/runAsUser', - value: val, + path: '/spec/admin/storageClasses/default', + value: storageClass, force: true, }) } - } catch (e) { - console.log(e) } - commit('wizard/model$update', { - path: '/spec/deletionPolicy', - value: getDefault({ getValue, model }, 'deletionPolicy'), - force: true, - }) - - if (!getValue(model, `/spec/admin/databases/Druid/mode/toggle`)) { - let defMode = getDefault({ getValue, model }, 'databases/Druid/mode') || '' - if (defMode === '') { - const arr = getValue(model, '/spec/databases/Druid/mode/available') || [] - if (arr.length) defMode = arr[0] - } + function showAlerts() { + // watchDependency('discriminator#/monitoring') + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const isAlertToggleEnabled = isToggleOn('alert') + return isMonitorEnabled && isAlertToggleEnabled + } + + function showIssuer() { + // watchDependency('model#/spec/admin/tls/default') + const isTlsEnabled = getValue(model, '/spec/admin/tls/default') + const isIssuerToggleEnabled = isToggleOn('clusterIssuers') + return isTlsEnabled && isIssuerToggleEnabled + } + + function onBackupSwitch() { + const isBackupOn = getValue(discriminator, '/backup') commit('wizard/model$update', { - path: '/spec/mode', - value: defMode, + path: '/spec/backup/tool', + value: isBackupOn ? 'KubeStash' : '', force: true, }) } - if (!features.includes('tls')) { + function setMonitoring() { + const agent = getValue(model, '/spec/admin/monitoring/agent') || '' + return !!agent + } + + function setBackup() { + const backup = getValue(model, '/spec/backup/tool') + const val = getValue(model, '/spec/admin/backup/enable/default') + return backup === 'KubeStash' && features.includes('backup') && val + } + + function onAuthChange() { commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: false, + path: '/spec/authSecret/name', + value: '', force: true, }) - } - if (!features.includes('binding')) { commit('wizard/model$update', { - path: '/spec/admin/expose/default', - value: false, + path: '/spec/authSecret/password', + value: '', force: true, }) } - if (!features.includes('monitoring')) { + + function isConfigDatabaseOn() { + // watchDependency('discriminator#/configDatabase') + return getValue(discriminator, '/configDatabase') + } + + function clearConfiguration() { + const configOn = getValue(discriminator, '/configDatabase') + + if (!configOn) { + commit('wizard/model$delete', '/spec/configuration') + } + } + + async function getAppBindings(type) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const queryParams = { + filter: { + items: { + metadata: { name: null, namespace: null }, + spec: { type: null }, + }, + }, + } + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/appcatalog.appscode.com/v1alpha1/appbindings`, + queryParams, + ) + const resources = (resp && resp.data && resp.data.items) || [] + + const fileredResources = resources + .filter((item) => item.spec?.type === `kubedb.com/${type}`) + .map((item) => { + const name = item.metadata?.name || '' + const namespace = item.metadata?.namespace || '' + return { + text: `${namespace}/${name}`, + value: { + name: name, + namespace: namespace, + }, + } + }) + return fileredResources + } catch (e) { + console.log(e) + return [] + } + } + + function onRefChange(type) { + const ref = getValue(discriminator, `/${type}`) || {} commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: '', + path: `/spec/${type}/name`, + value: ref.name || '', force: true, }) commit('wizard/model$update', { - path: '/form/alert/enabled', - value: 'none', + path: `/spec/${type}/namespace`, + value: ref.namespace || '', force: true, }) } - if (!features.includes('backup')) { + + function isExternallyManaged(type) { + // watchDependency(`model#/spec/${type}/externallyManaged`) + const isManaged = getValue(model, `/spec/${type}/externallyManaged`) || false + if (!isManaged) clearRefs(type) + return isManaged + } + + function isMetadataStorageTypeEqualsTo(type) { + // watchDependency('model#/spec/metadataStorage/type') + // watchDependency('model#/spec/metadataStorage/externallyManaged') + const dbType = getValue(model, '/spec/metadataStorage/type') || '' + const isManaged = getValue(model, '/spec/metadataStorage/externallyManaged') || false + return isManaged && dbType === type + } + + function clearRefs(type) { + setDiscriminatorValue(`/${type}`, '') commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, + path: `/spec/${type}/name`, + value: '', force: true, }) commit('wizard/model$update', { - path: '/spec/backup/tool', + path: `/spec/${type}/namespace`, value: '', force: true, }) } - setDiscriminatorValue('/bundleApiLoaded', true) -} - -function fetchOptions({ model, getValue, commit }, type) { - let kind = getValue(model, '/metadata/resource/kind') - - let returnArray = [] - if (type === 'clusterTier/placement') { - returnArray = placement - } else if (type === `databases/${kind}/versions`) { - returnArray = versions - } else if (type === 'storageClasses') { - returnArray = storageClass - } else if (type === 'clusterIssuers') { - returnArray = clusterIssuers - } + async function initBundle() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + + let db = getValue(model, '/metadata/resource/kind') + db = db.toLowerCase() + let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` + const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` + try { + const resp = await axios.get(url) + features = resp.data.features || [] + placement = resp.data.placementpolicies || [] + versions = resp.data.versions || [] + storageClass = resp.data.storageclasses || [] + clusterIssuers = resp.data.clusterissuers || [] + nodetopologiesDedicated = resp.data.dedicated || [] + nodetopologiesShared = resp.data.shared || [] + + const response = await axios.get(annotationUrl) + const annotations = response.data?.metadata?.annotations || {} + const uidRange = annotations['openshift.io/sa.scc.uid-range'] + if (uidRange) { + const val = uidRange.split('/')[0] + commit('wizard/model$update', { + path: '/spec/openshift/securityContext/runAsUser', + value: val, + force: true, + }) + } + } catch (e) { + console.log(e) + } - if (returnArray.length === 1) { - const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: path, - value: returnArray[0], + path: '/spec/deletionPolicy', + value: getDefault('deletionPolicy'), force: true, }) - } - return returnArray -} - -function getAdminOptions({ getValue, model, watchDependency, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') + if (!getValue(model, `/spec/admin/databases/Druid/mode/toggle`)) { + let defMode = getDefault('databases/Druid/mode') || '' + if (defMode === '') { + const arr = getValue(model, '/spec/databases/Druid/mode/available') || [] + if (arr.length) defMode = arr[0] + } + commit('wizard/model$update', { + path: '/spec/mode', + value: defMode, + force: true, + }) + } - const options = getValue(model, `/spec/admin/${type}/available`) || [] + if (!features.includes('tls')) { + commit('wizard/model$update', { + path: '/spec/admin/tls/default', + value: false, + force: true, + }) + } + if (!features.includes('binding')) { + commit('wizard/model$update', { + path: '/spec/admin/expose/default', + value: false, + force: true, + }) + } + if (!features.includes('monitoring')) { + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: 'none', + force: true, + }) + } + if (!features.includes('backup')) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: '', + force: true, + }) + } - if (options.length === 0) { - return fetchOptions({ model, getValue, commit }, type) + setDiscriminatorValue('/bundleApiLoaded', true) } - return options -} - -function checkIfFeatureOn({ getValue, model }, type) { - let val = getValue(model, `/spec/admin/${type}/toggle`) - if (type === 'backup' || type === 'archiver') { - val = getValue(model, `/spec/admin/${type}/enable/toggle`) - } - const backupVal = getValue(model, '/spec/backup/tool') - - if (type === 'backup') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } else if (type === 'tls') { - return features.includes('tls') && val - } else if (type === 'expose') { - return features.includes('binding') && val - } else if (type === 'monitoring') { - return features.includes('monitoring') && val - } else if (type === 'archiver') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } -} + function fetchOptions(type) { + let kind = getValue(model, '/metadata/resource/kind') + + let returnArray = [] + if (type === 'clusterTier/placement') { + returnArray = placement + } else if (type === `databases/${kind}/versions`) { + returnArray = versions + } else if (type === 'storageClasses') { + returnArray = storageClass + } else if (type === 'clusterIssuers') { + returnArray = clusterIssuers + } -function isToggleOn({ getValue, model, discriminator, watchDependency }, type) { - watchDependency('discriminator#/bundleApiLoaded') - watchDependency('model#/spec/admin/deployment/default') - const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') - let deploymentType = getValue(model, `/spec/admin/deployment/default`) - if ( - type === 'tls' || - type === 'backup' || - type === 'expose' || - type === 'monitoring' || - type === 'archiver' - ) { - return checkIfFeatureOn({ getValue, model }, type) - } else if ( - type === 'clusterTier' || - type === 'clusterTier/placement' || - type === 'clusterTier/nodeTopology' - ) { - if (deploymentType === 'Dedicated' && bundleApiLoaded) return true - else return false - } else if (type === 'deployment') { - const deploymentType = getValue(model, '/spec/admin/deployment/default') - if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + if (returnArray.length === 1) { + const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: '/spec/admin/deployment/default', - value: 'Shared', + path: path, + value: returnArray[0], force: true, }) } - return ( - getValue(model, `/spec/admin/${type}/toggle`) && - nodetopologiesDedicated.length && - bundleApiLoaded - ) - } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded -} -async function getNodeTopology({ model, getValue, axios, storeGet, watchDependency }) { - watchDependency('model#/spec/admin/deployment/default') - watchDependency('model#/spec/admin/clusterTier/default') - const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' - const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' - let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + return returnArray + } - const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + function getAdminOptions(type) { + // watchDependency('discriminator#/bundleApiLoaded') - if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared - else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + const options = getValue(model, `/spec/admin/${type}/available`) || [] - const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) - return filteredList -} + if (options.length === 0) { + return fetchOptions(type) + } -function filterNodeTopology(list, tier, provider) { - // first filter the list from value that exists from the filtered list got from API - const filteredlist = list + return options + } - // filter the list based on clusterTier - if (provider === 'EKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('c') - else if (tier === 'MemoryOptimized') return item.startsWith('r') - else return !item.startsWith('c') && !item.startsWith('r') - }) - } else if (provider === 'AKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - else - return ( - !(item.startsWith('f') || item.startsWith('fx')) && - !( + let backupToolInitialValue = '' + function checkIfFeatureOn(type) { + let val = getValue(model, `/spec/admin/${type}/toggle`) + if (type === 'backup' || type === 'archiver') { + val = getValue(model, `/spec/admin/${type}/enable/toggle`) + } + const backupVal = getValue(model, '/spec/backup/tool') + if (type === 'backup') { + if (backupToolInitialValue === '') { + backupToolInitialValue = + features.includes('backup') && backupVal === 'KubeStash' && val ? 'on' : 'off' + return features.includes('backup') && backupVal === 'KubeStash' && val + } else { + if (backupToolInitialValue === 'on') { + return true + } else { + return false + } + } + } else if (type === 'tls') { + return features.includes('tls') && val + } else if (type === 'expose') { + return features.includes('binding') && val + } else if (type === 'monitoring') { + return features.includes('monitoring') && val + } else if (type === 'archiver') { + return features.includes('backup') && val + } + } + + function isToggleOn(type) { + // watchDependency('discriminator#/bundleApiLoaded') + // watchDependency('model#/spec/admin/deployment/default') + const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') + let deploymentType = getValue(model, `/spec/admin/deployment/default`) + if ( + type === 'tls' || + type === 'backup' || + type === 'expose' || + type === 'monitoring' || + type === 'archiver' + ) { + return checkIfFeatureOn(type) + } else if ( + type === 'clusterTier' || + type === 'clusterTier/placement' || + type === 'clusterTier/nodeTopology' + ) { + if (deploymentType === 'Dedicated' && bundleApiLoaded) return true + else return false + } else if (type === 'deployment') { + const deploymentType = getValue(model, '/spec/admin/deployment/default') + if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + commit('wizard/model$update', { + path: '/spec/admin/deployment/default', + value: 'Shared', + force: true, + }) + } + return ( + getValue(model, `/spec/admin/${type}/toggle`) && + nodetopologiesDedicated.length && + bundleApiLoaded + ) + } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded + } + + async function getNodeTopology() { + // watchDependency('model#/spec/admin/deployment/default') + // watchDependency('model#/spec/admin/clusterTier/default') + const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' + const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' + let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + + const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + + if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared + else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + + const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) + return filteredList + } + + function filterNodeTopology(list, tier, provider) { + // first filter the list from value that exists from the filtered list got from API + const filteredlist = list + + // filter the list based on clusterTier + if (provider === 'EKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('c') + else if (tier === 'MemoryOptimized') return item.startsWith('r') + else return !item.startsWith('c') && !item.startsWith('r') + }) + } else if (provider === 'AKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('e') || item.startsWith('eb') || item.startsWith('ec') || item.startsWith('m') || item.startsWith('d') ) - ) - }) - } else if (provider === 'GKE') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') - return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - else - return ( - !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && - !( + else + return ( + !(item.startsWith('f') || item.startsWith('fx')) && + !( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + ) + }) + } else if (provider === 'GKE') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') + return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('x4') || item.startsWith('m1') || item.startsWith('m2') || item.startsWith('m3') ) - ) - }) - } else return filteredlist -} + else + return ( + !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && + !( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + ) + }) + } else return filteredlist + } -function returnFalse() { - return false -} + function returnFalse() { + return false + } -function showAdditionalSettings({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return features.length -} + function showAdditionalSettings() { + // watchDependency('discriminator#/bundleApiLoaded') + return features.length + } -function getDefault({ getValue, model }, type) { - const val = getValue(model, `/spec/admin/${type}/default`) || '' - return val -} + function getDefault(type) { + const val = getValue(model, `/spec/admin/${type}/default`) || '' + return val + } -function isConfigAvailable({ getValue, model }) { - const val = getValue(model, '/spec/configuration') - return val !== '' -} + async function getReferSecrets() { + const referSecret = getValue(discriminator, '/referSecret') + if (!referSecret) { + return [] + } -async function getReferSecrets({ getValue, model, storeGet, axios, discriminator }) { - const referSecret = getValue(discriminator, '/referSecret') - if (!referSecret) { - return [] + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/metadata/release/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` + + const options = [] + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + return options } - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/metadata/release/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - - const options = [] - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) - } catch (e) { - console.log(e) + function showAuthPasswordField() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !modelPathValue && showReferSecret() } - return options -} - -function showAuthPasswordField({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} -function showSecretDropdown({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showSecretDropdown() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !!modelPathValue && showReferSecret() + } -function showReferSecret({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/createAuthSecret') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue -} + function showReferSecret() { + const modelPathValue = getValue(discriminator, '/createAuthSecret') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue + } -function getDefaultValue({ getValue, model }, path) { - const val = getValue(model, `/${path}`) || '' - return val -} + function getDefaultValue(path) { + const val = getValue(model, `/${path}`) || '' + return val + } -function showReferSecretSwitch({ model, getValue, watchDependency, discriminator }) { - const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showReferSecretSwitch() { + const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue && showReferSecret() + } -function onReferSecretChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) -} + function onReferSecretChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + } -return { - showReferSecretSwitch, - onReferSecretChange, - getDefaultValue, - isRancherManaged, - showSecretDropdown, - showReferSecret, - getReferSecrets, - isConfigAvailable, - showAdditionalSettings, - returnFalse, - initBundle, - isVariantAvailable, - showAuthPasswordField, - getNamespaces, - getSecrets, - getMachineListForOptions, - setLimits, - setRequests, - setMachineToCustom, - isMachineNotCustom, - isMachineCustom, - updateAlertValue, - getCreateNameSpaceUrl, - setStorageClass, - showAlerts, - showIssuer, - onBackupSwitch, - setMonitoring, - onAuthChange, - isConfigDatabaseOn, - clearConfiguration, - getNodeTopology, - filterNodeTopology, - getAppBindings, - onRefChange, - isExternallyManaged, - isMetadataStorageTypeEqualsTo, - clearRefs, - isToggleOn, - getAdminOptions, - setBackup, - getDefault, + return { + showReferSecretSwitch, + onReferSecretChange, + getDefaultValue, + isRancherManaged, + showSecretDropdown, + showReferSecret, + getReferSecrets, + showAdditionalSettings, + returnFalse, + initBundle, + isVariantAvailable, + showAuthPasswordField, + getNamespaces, + getSecrets, + getMachineListForOptions, + setLimits, + setRequests, + setMachineToCustom, + isMachineNotCustom, + isMachineCustom, + updateAlertValue, + getCreateNameSpaceUrl, + setStorageClass, + showAlerts, + showIssuer, + onBackupSwitch, + setMonitoring, + onAuthChange, + isConfigDatabaseOn, + clearConfiguration, + getNodeTopology, + filterNodeTopology, + getAppBindings, + onRefChange, + isExternallyManaged, + isMetadataStorageTypeEqualsTo, + clearRefs, + isToggleOn, + getAdminOptions, + setBackup, + getDefault, + } } diff --git a/charts/kubedbcom-druid-editor/ui/edit-ui.yaml b/charts/kubedbcom-druid-editor/ui/edit-ui.yaml index 8ea43385ee..50e83471a8 100644 --- a/charts/kubedbcom-druid-editor/ui/edit-ui.yaml +++ b/charts/kubedbcom-druid-editor/ui/edit-ui.yaml @@ -1,997 +1,909 @@ -steps: -- form: - discriminator: - dbDetails: - default: false - type: boolean +type: multi-step-form +step: + - type: single-step-form + id: compute-autoscaler + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: SelectDb - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: SelectType - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - elements: - - discriminator: - topologyMachines: - default: [] - type: array + - type: block-layout + if: + type: function + name: isConsole + elements: + - type: input + label: Name + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/metadata/properties/name + - type: select + label: Select Namespace + loader: getNamespaces + if: + type: function + name: isRancherManaged + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/metadata/properties/namespace + - type: select + label: Select Db + loader: getDbs + validation: + type: required + refresh: true + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/databaseRef/properties/name + watcher: + func: initMetadata + paths: + - schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/databaseRef/properties/name + + - type: radio + if: + type: function + name: isConsole + label: Select Type + validation: + type: required + schema: temp/properties/autoscalingType + watcher: + func: initMetadata + paths: + - temp/properties/autoscalingType + options: + - text: Compute + value: compute + description: Scale your CPU Memory based on resource usage + - text: Storage + value: storage + description: Expand your database size based on volume usage + + - type: block-layout + showLabels: false + loader: fetchTopologyMachines elements: - - fetch: fetchTopologyMachines - if: returnFalse - schema: - $ref: discriminator#/topologyMachines - type: input - - elements: - - computed: setTrigger|autoscalingKubedbComDruidAutoscaler/spec/compute/brokers/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/brokers/properties/trigger - type: select - - label: - text: PodLifeTimeThreshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/brokers/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/brokers/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-brokers-max: - type: string - allowedMachine-brokers-min: - type: string + # brokers mode + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComDruidAutoscaler/spec/compute/brokers/trigger + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/brokers/properties/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + customClass: width-300 + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/brokers/properties/podLifeTimeThreshold + - type: block-layout + label: Brokers + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/brokers elements: - - computed: setAllowedMachine|brokers|min - disableUnselect: true - fetch: getMachines|brokers|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|brokers - schema: - $ref: discriminator#/properties/allowedMachine-brokers-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/brokers/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/brokers/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/brokers/properties/minAllowed - show_label: true - type: single-step-form - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/brokers/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/brokers/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/brokers/properties/maxAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|brokers|max - disableUnselect: true - fetch: getMachines|brokers|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|brokers - schema: - $ref: discriminator#/properties/allowedMachine-brokers-max - type: select - type: single-step-form - - fetch: setControlledResources|brokers - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/brokers/properties/controlledResources - type: multiselect - label: - text: Brokers - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/brokers - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComDruidAutoscaler/spec/compute/coordinators/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/coordinators/properties/trigger - type: select - - label: - text: PodLifeTimeThreshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/coordinators/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/coordinators/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-coordinators-max: - type: string - allowedMachine-coordinators-min: - type: string + - type: threshold-input + label: ResourceDiff Percentage + customClass: width-300 + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/brokers/properties/resourceDiffPercentage + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-brokers-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|brokers|min + loader: + name: getMachines|brokers|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-brokers-max + watcher: + func: onMachineChange|brokers + paths: + - temp/properties/allowedMachine-brokers-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/brokers/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/brokers/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-brokers-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|brokers|max + loader: + name: getMachines|brokers|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-brokers-min + watcher: + func: onMachineChange|brokers + paths: + - temp/properties/allowedMachine-brokers-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/brokers/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/brokers/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|brokers + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/brokers/properties/controlledResources + + # coordinators mode + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComDruidAutoscaler/spec/compute/coordinators/trigger + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/coordinators/properties/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + customClass: width-300 + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/coordinators/properties/podLifeTimeThreshold + - type: block-layout + label: Coordinators + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/coordinators elements: - - computed: setAllowedMachine|coordinators|min - disableUnselect: true - fetch: getMachines|coordinators|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|coordinators - schema: - $ref: discriminator#/properties/allowedMachine-coordinators-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/coordinators/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/coordinators/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/coordinators/properties/minAllowed - show_label: true - type: single-step-form - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/coordinators/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/coordinators/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/coordinators/properties/maxAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|coordinators|max - disableUnselect: true - fetch: getMachines|coordinators|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|coordinators - schema: - $ref: discriminator#/properties/allowedMachine-coordinators-max - type: select - type: single-step-form - - fetch: setControlledResources|coordinators - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/coordinators/properties/controlledResources - type: multiselect - label: - text: Coordinators - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/coordinators - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComDruidAutoscaler/spec/compute/historicals/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/historicals/properties/trigger - type: select - - label: - text: PodLifeTimeThreshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/historicals/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/historicals/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-historicals-max: - type: string - allowedMachine-historicals-min: - type: string + - type: threshold-input + label: ResourceDiff Percentage + customClass: width-300 + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/coordinators/properties/resourceDiffPercentage + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-coordinators-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|coordinators|min + loader: + name: getMachines|coordinators|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-coordinators-max + watcher: + func: onMachineChange|coordinators + paths: + - temp/properties/allowedMachine-coordinators-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/coordinators/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/coordinators/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-coordinators-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|coordinators|max + loader: + name: getMachines|coordinators|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-coordinators-min + watcher: + func: onMachineChange|coordinators + paths: + - temp/properties/allowedMachine-coordinators-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/coordinators/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/coordinators/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|coordinators + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/coordinators/properties/controlledResources + + # historicals mode + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComDruidAutoscaler/spec/compute/historicals/trigger + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/historicals/properties/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + customClass: width-300 + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/historicals/properties/podLifeTimeThreshold + - type: block-layout + label: Historicals + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/historicals elements: - - computed: setAllowedMachine|historicals|min - disableUnselect: true - fetch: getMachines|historicals|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|historicals - schema: - $ref: discriminator#/properties/allowedMachine-historicals-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/historicals/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/historicals/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/historicals/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|historicals|max - disableUnselect: true - fetch: getMachines|historicals|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|historicals - schema: - $ref: discriminator#/properties/allowedMachine-historicals-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/historicals/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/historicals/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/historicals/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|historicals - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/historicals/properties/controlledResources - type: multiselect - label: - text: Historicals - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/historicals - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComDruidAutoscaler/spec/compute/middleManagers/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/middleManagers/properties/trigger - type: select - - label: - text: PodLifeTimeThreshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/middleManagers/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/middleManagers/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-middleManagers-max: - type: string - allowedMachine-middleManagers-min: - type: string + - type: threshold-input + label: ResourceDiff Percentage + customClass: width-300 + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/historicals/properties/resourceDiffPercentage + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-historicals-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|historicals|min + loader: + name: getMachines|historicals|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-historicals-max + watcher: + func: onMachineChange|historicals + paths: + - temp/properties/allowedMachine-historicals-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/historicals/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/historicals/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-historicals-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|historicals|max + loader: + name: getMachines|historicals|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-historicals-min + watcher: + func: onMachineChange|historicals + paths: + - temp/properties/allowedMachine-historicals-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/historicals/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/historicals/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|historicals + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/historicals/properties/controlledResources + + + # middleManagers mode + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComDruidAutoscaler/spec/compute/middleManagers/trigger + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/middleManagers/properties/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + customClass: width-300 + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/middleManagers/properties/podLifeTimeThreshold + - type: block-layout + label: Middle Managers + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/middleManagers elements: - - computed: setAllowedMachine|middleManagers|min - disableUnselect: true - fetch: getMachines|middleManagers|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|middleManagers - schema: - $ref: discriminator#/properties/allowedMachine-middleManagers-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/middleManagers/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/middleManagers/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/middleManagers/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|middleManagers|max - disableUnselect: true - fetch: getMachines|middleManagers|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|middleManagers - schema: - $ref: discriminator#/properties/allowedMachine-middleManagers-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/middleManagers/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/middleManagers/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/middleManagers/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|middleManagers - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/middleManagers/properties/controlledResources - type: multiselect - label: - text: MiddleManagers - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/middleManagers - show_label: true - type: single-step-form - type: single-step-form - - elements: - - fetch: fetchNodeTopology - label: - text: Select NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name - type: select - - if: isNodeTopologySelected - label: - text: ScaleUp Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage - type: input - - if: isNodeTopologySelected - label: - text: ScaleDown Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage - type: input - if: hasNoAnnotations - label: - text: NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/nodeTopology - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: OpsRequest Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: compute-autoscaler - title: steps.0.label -- form: - discriminator: - dbDetails: - default: false - type: boolean + - type: threshold-input + label: ResourceDiff Percentage + customClass: width-300 + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/middleManagers/properties/resourceDiffPercentage + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-middleManagers-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|middleManagers|min + loader: + name: getMachines|middleManagers|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-middleManagers-max + watcher: + func: onMachineChange|middleManagers + paths: + - temp/properties/allowedMachine-middleManagers-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/middleManagers/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/middleManagers/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-middleManagers-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|middleManagers|max + loader: + name: getMachines|middleManagers|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-middleManagers-min + watcher: + func: onMachineChange|middleManagers + paths: + - temp/properties/allowedMachine-middleManagers-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/middleManagers/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/middleManagers/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|middleManagers + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/middleManagers/properties/controlledResources + + - type: block-layout + label: Node Topology + if: + type: function + name: hasNoAnnotations + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/nodeTopology + elements: + - type: select + label: Select NodeTopology + loader: fetchNodeTopology + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name + - type: threshold-input + label: ScaleUp Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage + - type: threshold-input + label: ScaleDown Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage + + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + # schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/opsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: storage-autoscaler elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: SelectDb - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: SelectType - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - elements: - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComDruidAutoscaler/spec/storage/historicals/trigger - label: - text: trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/historicals/properties/trigger - type: select - - label: - text: Expansion Mode - options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/historicals/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/historicals/properties/usageThreshold - type: input - - addFormLabel: ScalingRules - element: + - type: block-layout + showLabels: false + elements: + - type: block-layout + showLabels: false + elements: + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComDruidAutoscaler/spec/storage/historicals/trigger + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/historicals/properties/trigger + - type: label-element + 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: select + label: Mode + description: Select how the storage expansion should be handled. + options: + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/historicals/properties/expansionMode + - type: block-layout + label: Historicals + showLabels: true elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/historicals/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/historicals/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComDruidAutoscaler/spec/storage/historicals/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/historicals/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComDruidAutoscaler/spec/storage/historicals/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/historicals/properties/upperBound - type: input - label: - text: Historicals - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/historicals - show_label: true - type: single-step-form - type: single-step-form - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComDruidAutoscaler/spec/storage/middleManagers/trigger - label: - text: trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/middleManagers/properties/trigger - type: select - - label: - text: Expansion Mode - options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/middleManagers/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/middleManagers/properties/usageThreshold - type: input - - addFormLabel: ScalingRules - element: + - type: threshold-input + label: UsageThreshold (%) + subtitle: Set the threshold percentage of storage usage to trigger scaling. + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/historicals/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/historicals/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComDruid/spec/topology/historicals/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComDruidAutoscaler/spec/storage/historicals/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/historicals/properties/scalingRules + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/historicals/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComDruidAutoscaler/spec/storage/historicals/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/historicals/properties/upperBound + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComDruidAutoscaler/spec/storage/middleManagers/trigger + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/middleManagers/properties/trigger + - type: label-element + 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: select + label: Mode + description: Select how the storage expansion should be handled. + options: + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/middleManagers/properties/expansionMode + - type: block-layout + label: MiddleManagers + showLabels: true elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/middleManagers/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/middleManagers/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComDruidAutoscaler/spec/storage/middleManagers/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/middleManagers/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComDruidAutoscaler/spec/storage/middleManagers/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/middleManagers/properties/upperBound - type: input - label: - text: MiddleManagers - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/middleManagers - show_label: true - type: single-step-form - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: OpsRequest Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: storage-autoscaler - title: steps.1.label -- form: - discriminator: - binding: - default: false - type: boolean - elements: - - computed: isBindingAlreadyOn - label: - text: Expose Database - onChange: addOrRemoveBinding - schema: - $ref: discriminator#/properties/binding - type: switch - type: single-step-form - id: binding - title: Gateway Binding -- form: - discriminator: - enableMonitoring: - default: true - type: boolean + - type: threshold-input + label: UsageThreshold (%) + subtitle: Set the threshold percentage of storage usage to trigger scaling. + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/middleManagers/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/middleManagers/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComDruid/spec/topology/middleManagers/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComDruidAutoscaler/spec/storage/middleManagers/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/middleManagers/properties/scalingRules + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/middleManagers/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComDruidAutoscaler/spec/storage/middleManagers/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/storage/properties/middleManagers/properties/upperBound + - type: block-layout + label: OpsRequest Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComDruidAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: monitoring + loader: initMonitoring elements: - - label: - text: labels.to_update_exporter_resources - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - function: getOpsRequestUrl|VerticalScaling - - computed: isValueExistInModel|/resources/kubedbComDruid/spec/monitor - label: - text: labels.enable_monitoring - onChange: onEnableMonitoringChange - schema: - $ref: discriminator#/enableMonitoring - type: switch - - discriminator: - customizeExporter: - default: true - type: boolean + - type: label-element + label: To update Exporter Resource section click on Create OpsRequest + - type: anchor + label: Create OpsRequest + schema: temp/properties/opsRequestUrl + init: + type: func + value: getOpsRequestUrl|scale-vertically + - type: switch + label: Enable Monitoring + fullwidth: true + schema: temp/properties/enableMonitoring + init: + type: func + value: isValueExistInModel|/resources/kubedbComDruid/spec/monitor + watcher: + func: onEnableMonitoringChange + paths: + - temp/properties/enableMonitoring + - type: block-layout + if: + type: function + name: showMonitoringSection 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/kubedbComDruid/properties/spec/properties/monitor/properties/agent - type: radio - - elements: - - label: - text: labels.scrapping_interval - schema: - $ref: schema#/properties/resources/properties/kubedbComDruid/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval - type: input - if: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComDruid/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: radio + label: Select a Monitoring Method + schema: schema/properties/resources/properties/kubedbComDruid/properties/spec/properties/monitor/properties/agent + isHorizontal: true + options: + - text: Prometheus Operator + value: prometheus.io/operator + description: Inject metric exporter sidecar and creates a ServiceMonitor + - text: Custom ServiceMonitor + value: prometheus.io + description: Injects the metric exporter sidecar and let you customize ServiceMonitor + - text: Custom Scrapper + value: prometheus.io/builtin + description: Inject metric exporter sidecar and add Prometheus annotations to the stats Service + init: + type: static + value: prometheus.io/operator + watcher: + func: onAgentChange + paths: + - schema/properties/resources/properties/kubedbComDruid/properties/spec/properties/monitor/properties/agent + - type: block-layout + label: ServiceMonitor Configuration + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComDruid/spec/monitor/agent + elements: + - label: Scrapping Interval + schema: schema/properties/resources/properties/kubedbComDruid/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval + type: input + - type: block-layout + label: Service Monitor + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComDruid/spec/monitor/agent + elements: + - type: array-object-form + label: Endpoints + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/endpoints + elements: + - type: switch + label: Honor labels + fullwidth: true + schema: honorLabels + - type: input + label: Interval + schema: interval + validation: + type: required + - type: input + label: Path + schema: path + validation: + type: required + - type: input + label: Port + schema: port + validation: + type: required + - type: select + multiple: true + label: Match Namespaces + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/namespaceSelector/properties/matchNames + loader: getResources|core|v1|namespaces + if: + type: function + name: returnFalse + - type: block-layout + showLabels: false + # schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector + if: + type: function + name: returnFalse + elements: + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector/properties/matchLabels + - type: object-item + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/metadata/properties/labels + label : Labels + buttonClass: is-light is-outlined + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComDruid/spec/monitor/agent + # individualItemDisabilityCheck: disableLableChecker + - type: label-element + label: Exporter Configuration + schema: '' + - type: switch + label: Customize Exporter Sidecar + fullwidth: true + schema: temp/properties/customizeExporter + init: + type: static + value: true + watcher: + func: onCustomizeExporterChange + paths: + - temp/properties/customizeExporter + - type: block-layout + label: Customer Exporter Section + showLabels: false + if: + type: function + name: showCustomizeExporterSection + elements: + - type: machine-compare + label: Resources + schema: schema/properties/resources/properties/kubedbComDruid/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/resources + if: + type: function + name: returnFalse + - type: label-element + label: Security Context + schema: '' + - type: input + schema: schema/properties/resources/properties/kubedbComDruid/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsUser + label: Run as User + - type: input + schema: schema/properties/resources/properties/kubedbComDruid/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup + label: Run as Group + - type: input + schema: schema/properties/resources/properties/kubedbComDruid/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/port + label: Port + - type: array-item-form + label: Args + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/kubedbComDruid/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args + init: + type: static + value: ['--compatible-mode'] + element: 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/kubedbComDruid/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/kubedbComDruid/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: - - if: returnFalse - label: - text: labels.resources - schema: - $ref: schema#/properties/resources/properties/kubedbComDruid/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/kubedbComDruid/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/kubedbComDruid/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup - type: input - - label: - text: labels.port - schema: - $ref: schema#/properties/resources/properties/kubedbComDruid/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/kubedbComDruid/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args/items - type: input - label: - text: labels.args - schema: - $ref: schema#/properties/resources/properties/kubedbComDruid/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args - type: list-input-form - - alias: reusable_env - chart: - name: uibytebuildersdev-component-env - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComDruid/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 -type: multi-step-form + label: Args + # isSubsection: true + - type: block-layout + label: Metadata + showLabels: false + elements: + - type: array-object-form + init: + type: func + value: initEnvArray + label: Environment Variables + buttonClass: is-light is-outlined + watcher: + func: onEnvArrayChange + paths: + - temp/properties/env + schema: temp/properties/env + elements: + - type: input + label: Name + schema: name + validation: + type: required + - type: radio + label: Value From + schema: temp/properties/valueFromType + validation: + type: required + init: + type: func + value: setValueFrom + options: + - text: Input + value: input + - text: Secret + value: secret + - text: ConfigMap + value: configMap + watcher: + func: onValueFromChange + paths: + - temp/properties/valueFromType + - type: input + label: Value + schema: value + validation: + type: required + if: + name: isEqualToTemp|input + type: function + - type: select + if: + type: function + name: isEqualToTemp|configMap + label: ConfigMap Name + schema: valueFrom/properties/configMapKeyRef/properties/name + loader: + name: resourceNames|core|v1|configmaps + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: ConfigMap Key + schema: valueFrom/properties/configMapKeyRef/properties/key + if: + type: function + name: isEqualToTemp|configMap + loader: + name: getConfigMapKeys + watchPaths: + - schema/resources/kubedbComDruid/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/configMapKeyRef/name + - schema/metadata/release/namespace + - type: select + label: Secret Name + schema: valueFrom/properties/secretKeyRef/properties/name + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecrets + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: Secret Key + schema: valueFrom/properties/secretKeyRef/properties/key + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecretKeys + watchPaths: + - schema/resources/kubedbComDruid/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/secretKeyRef/name + - schema/metadata/release/namespace + + - type: single-step-form + id: binding + elements: + - type: switch + label: Expose Database + schema: temp/properties/binding + fullwidth: true + init: + type: func + value: isBindingAlreadyOn + watcher: + func: addOrRemoveBinding + paths: + - temp/properties/binding diff --git a/charts/kubedbcom-druid-editor/ui/functions.js b/charts/kubedbcom-druid-editor/ui/functions.js index 2c69984a80..8b26ad5391 100644 --- a/charts/kubedbcom-druid-editor/ui/functions.js +++ b/charts/kubedbcom-druid-editor/ui/functions.js @@ -1,3434 +1,2148 @@ -// ************************* common functions ******************************************** -// eslint-disable-next-line no-empty-pattern -async function fetchJsons({ axios, itemCtx, setDiscriminatorValue }, discriminatorPath) { - 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) - } +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + +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', true) + setDiscriminatorValue('/customizeExporter', true) + setDiscriminatorValue('/valueFromType', 'input') + setDiscriminatorValue('/env', []) + + // Compute Autoscaler Discriminators + setDiscriminatorValue('/dbDetails', false) + setDiscriminatorValue('/topologyMachines', []) + setDiscriminatorValue('/allowedMachine-coordinators-min', '') + setDiscriminatorValue('/allowedMachine-coordinators-max', '') + setDiscriminatorValue('/allowedMachine-overlords-min', '') + setDiscriminatorValue('/allowedMachine-overlords-max', '') + setDiscriminatorValue('/allowedMachine-brokers-min', '') + setDiscriminatorValue('/allowedMachine-brokers-max', '') + setDiscriminatorValue('/allowedMachine-routers-min', '') + setDiscriminatorValue('/allowedMachine-routers-max', '') + setDiscriminatorValue('/allowedMachine-historicals-min', '') + setDiscriminatorValue('/allowedMachine-historicals-max', '') + setDiscriminatorValue('/allowedMachine-middleManagers-min', '') + setDiscriminatorValue('/allowedMachine-middleManagers-max', '') + + // ************************* Common Helper Functions ******************************************** + + // eslint-disable-next-line no-empty-pattern + 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) + } - if (discriminatorPath) { - setDiscriminatorValue(discriminatorPath, { + return { ui: ui.data || {}, language: language.data || {}, functions, - }) + } } - return { - ui: ui.data || {}, - language: language.data || {}, - functions, + function disableLableChecker({ itemCtx }) { + const { key } = itemCtx + if (key.startsWith('app.kubernetes.io') || key.includes('helm')) return true + else return false } -} - -function disableLableChecker({ itemCtx }) { - const { key } = itemCtx - if (key.startsWith('app.kubernetes.io') || key.includes('helm')) return true - else return false -} -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} - -async function getResources({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - const resources = (resp && resp.data && resp.data.items) || [] + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) - 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 [] + 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 isEqualToDiscriminatorPath( - { discriminator, getValue, watchDependency }, - value, - discriminatorPath, -) { - watchDependency('discriminator#' + discriminatorPath) - const discriminatorValue = getValue(discriminator, discriminatorPath) - return discriminatorValue === value -} + function isConfigMapTypeValueFrom() { + const valueFrom = getValue(discriminator, '/valueFrom') + return !!(valueFrom && valueFrom.configMapKeyRef) + } -function setValueFromModel({ getValue, model }, path) { - return getValue(model, path) -} + function isSecretTypeValueFrom() { + const valueFrom = getValue(discriminator, '/valueFrom') + return !!(valueFrom && valueFrom.secretKeyRef) + } -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function isInputTypeValueFrom() { + return !isConfigMapTypeValueFrom() && !isSecretTypeValueFrom() + } - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + 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, + }) + } + } - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }) + function isEqualToDiscriminatorPath( + { discriminator, getValue, watchDependency }, + value, + discriminatorPath, + ) { + watchDependency('discriminator#' + discriminatorPath) + const discriminatorValue = getValue(discriminator, discriminatorPath) + return discriminatorValue === value + } - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + function setValueFromModel({ getValue, model }, path) { + return getValue(model, path) } - return ans -} + // function isEqualToValueFromType(value) { + // //watchDependency('discriminator#/valueFromType') + // const valueFrom = getValue(discriminator, '/valueFromType') + // return valueFrom === value + // } -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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}/${resource}` + 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 } }, - }, - }) + 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) + } - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + return ans } - return ans -} + async function getResourceList(axios, storeGet, { group, version, resource }) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - 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, - }) + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) - } + let ans = [] + try { + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + const items = (resp && resp.data && resp.data.items) || [] + ans = items + } catch (e) { + console.log(e) } - }) -} -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) + return ans + } - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) + 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, }) - } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) } - }) -} -function returnTrue() { - return true -} + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -function returnStringYes() { - return 'yes' -} + async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { + let resources = await getResourceList(axios, storeGet, { + group, + version, + resource, + }) -function isDedicatedModeSelected({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComDruid/spec/topology') - isDedicatedSelected = getValue(model, '/resources/kubedbComDruid/spec/topology') + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } - return !!isDedicatedSelected -} + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -function isCombinedModeSelected({ model, getValue, watchDependency }) { - return !isDedicatedSelected({ model, getValue, watchDependency }) -} + function returnTrue() { + return true + } -function isDiscriminatorEqualTo( - { discriminator, getValue, watchDependency }, - discriminatorPath, - value, -) { - watchDependency('discriminator#' + discriminatorPath) - const pathValue = getValue(discriminator, discriminatorPath) + function returnFalse() { + return false + } - return value === pathValue -} + function returnStringYes() { + return 'yes' + } -function isAuthPluginNotSearchGuard({ discriminator, getValue, watchDependency, commit }) { - watchDependency('discriminator#/selectedVersionAuthPlugin') - const pathValue = getValue(discriminator, '/selectedVersionAuthPlugin') + // ************************* Helper Functions ********************************************** - if (!pathValue) return false + /** + * Creates a deep copy of an object using JSON serialization + * @param {Object} obj - The object to copy + * @returns {Object} Deep copy of the input object + */ + function objectCopy(obj) { + return JSON.parse(JSON.stringify(obj)) + } - const ret = pathValue !== 'SearchGuard' && pathValue !== '' + /** + * Encodes a password to base64 format + * @param {string} value - The password to encode + * @returns {string} Base64 encoded password + */ + function encodePassword(value) { + return btoa(value) + } - if (!ret) { - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/topology/dataWarm') - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/topology/dataHot') + /** + * Decodes a base64 encoded password + * @param {string} value - The base64 encoded password + * @returns {string} Decoded password + */ + function decodePassword(value) { + return atob(value) } - return ret -} -// required for outer form section. where discriminator can not be saved -async function showInternalUsersAndRolesMapping({ - model, - getValue, - watchDependency, - axios, - storeGet, - setDiscriminatorValue, - commit, -}) { - watchDependency('model#/resources/kubedbComDruid/spec/disableSecurity') - watchDependency('model#/resources/kubedbComDruid/spec/version') - - const dist = await getSelectedVersionAuthPlugin({ - model, - getValue, - watchDependency, - axios, - storeGet, - setDiscriminatorValue, - }) + /** + * Checks if a value exists at a given path + * @param {Object} value - The object to check + * @param {Function} getValue - Function to get value from path + * @param {string} path - The path to check + * @returns {boolean} True if value exists, false otherwise + */ + function valueExists(value, getValue, path) { + const val = getValue(value, path) + if (val) return true + else return false + } - const ret = - (dist === 'OpenDistro' || dist === 'SearchGuard') && - isSecurityEnabled({ model, getValue, watchDependency }) + /** + * Clears the spec model for a specific resource path + * @param {Object} commit - Vuex commit function + * @param {string} path - The path to clear + */ + function clearSpecModel(commit, path) { + commit('wizard/model$delete', path) + } - if (ret) { - commit('wizard/showSteps$update', { - stepId: 'internal-users', - show: true, - }) + /** + * Gets the URL for creating a namespace + * @returns {string} The namespace creation URL + */ + function getCreateNameSpaceUrl() { + const cluster = storeGet('/route/params/cluster') + const domain = storeGet('/domain') || '' + const owner = storeGet('/route/params/user') - commit('wizard/showSteps$update', { - stepId: 'roles-mapping', - show: true, - }) - } else { - commit('wizard/showSteps$update', { - stepId: 'internal-users', - show: false, - }) + return `${domain}/${owner}/kubernetes/${cluster}/core/v1/namespaces/create` + } - commit('wizard/showSteps$update', { - stepId: 'roles-mapping', - show: false, - }) + function isRancherManaged({ storeGet }) { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found } - return ret -} -// required for outer form section. where discriminator can not be saved -async function showSecureCustomConfig({ - model, - getValue, - watchDependency, - axios, - storeGet, - setDiscriminatorValue, - commit, -}) { - watchDependency('model#/resources/kubedbComDruid/spec/version') - - const dist = await getSelectedVersionAuthPlugin({ - model, - getValue, - watchDependency, - axios, - storeGet, - setDiscriminatorValue, - }) + function isKubedb() { + return !!storeGet('/route/params/actions') + } - const ret = dist === 'X-Pack' + async function getNamespaces() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - if (ret) { - commit('wizard/showSteps$update', { - stepId: 'secure-custom-config', - show: true, - }) - } else { - commit('wizard/showSteps$update', { - stepId: 'secure-custom-config', - show: false, + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, }) - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/secureConfigSecret') - commit('wizard/model$delete', '/resources/secret_secure_config') - } - return ret -} + const resources = (resp && resp.data && resp.data.items) || [] -// ************************* Basic Info ********************************************** + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -async function getDruidVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + // ************************* Backup & Restore Functions ************************************* - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null, authPlugin: null }, + const stashAppscodeComRestoreSession_init = { + spec: { + repository: { + name: '', + }, + rules: [ + { + snapshots: ['latest'], + }, + ], + target: { + ref: { + apiVersion: 'appcatalog.appscode.com/v1alpha1', + kind: 'AppBinding', + name: '', + }, }, }, } - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, + const initScript = { + scriptPath: '', + secret: { + secretName: '', }, - ) - - const resources = (resp && resp.data && resp.data.items) || [] - - // keep only non deprecated versions - const filteredDruidVersions = resources.filter((item) => item.spec && !item.spec.deprecated) - - filteredDruidVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredDruidVersions -} + } + const stashAppscodeComRepository_init_repo = { + spec: { + backend: { + gcs: { + bucket: '', + prefix: '', + }, + storageSecretName: '', + }, + }, + } + const stashAppscodeComRepository_repo = { + spec: { + backend: { + gcs: { + bucket: '', + prefix: '', + }, + storageSecretName: '', + }, + }, + } + const restoreSessionInitRunTimeSettings = { + container: { + resources: { + requests: { + cpu: '', + memory: '', + }, + limits: { + cpu: '', + memory: '', + }, + }, + nice: { + adjustment: null, + }, + ionice: { + class: null, + classData: null, + }, + securityContext: { + privileged: false, + runAsNonRoot: false, + runAsUser: null, + runAsGroup: null, + seLinuxOptions: { + level: '', + role: '', + type: '', + user: '', + }, + }, + env: [], + envFrom: [], + }, + pod: { + serviceAccountName: '', + imagePullSecrets: [], + securityContext: { + fsGroup: null, + runAsNonRoot: false, + runAsUser: null, + runAsGroup: null, + seLinuxOptions: { + level: '', + role: '', + type: '', + user: '', + }, + }, + }, + } -function isSecurityEnabled({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComDruid/spec/disableSecurity') - const value = getValue(model, '/resources/kubedbComDruid/spec/disableSecurity') - return !value -} + const stashAppscodeComBackupConfiguration = { + spec: { + repository: { + name: '', + }, + retentionPolicy: { + keepLast: 5, + name: 'keep-last-5', + prune: true, + }, + schedule: '*/5 * * * *', + target: { + ref: { + apiVersion: 'appcatalog.appscode.com/v1alpha1', + kind: 'AppBinding', + name: '', + }, + }, + }, + } -function onDisableSecurityChange({ model, getValue, commit }) { - const disableSecurity = getValue(model, '/resources/kubedbComDruid/spec/disableSecurity') + function getBackupConfigsAndAnnotations(getValue, model) { + const stashAppscodeComBackupConfiguration = getValue( + model, + '/resources/stashAppscodeComBackupConfiguration', + ) - if (disableSecurity) { - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/authSecret') - commit('wizard/model$delete', '/resources/secret_admin_cred') - commit('wizard/model$delete', '/resources/secret_elastic_cred') - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/internalUsers') - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/rolesMapping') - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/tls') - } -} + const coreKubestashComBackupConfiguration = getValue( + model, + '/resources/coreKubestashComBackupConfiguration', + ) + const kubeStashTarget = coreKubestashComBackupConfiguration?.spec?.target -async function onVersionChange({ - model, - getValue, - watchDependency, - axios, - storeGet, - commit, - setDiscriminatorValue, -}) { - const dist = await getSelectedVersionAuthPlugin({ - model, - getValue, - watchDependency, - axios, - storeGet, - setDiscriminatorValue, - }) - - const isOpenDistro = dist === 'OpenDistro' - const isSearchGuard = dist === 'SearchGuard' - const isXpack = dist === 'X-Pack' - - if (!isOpenDistro && !isSearchGuard) { - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/internalUsers') - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/rolesMapping') - if (isXpack) { - removeCertificatesOfAliases({ model, getValue, commit }, ['admin']) - } - } else { - if (!isOpenDistro) { - const internalUsers = getValue(model, '/resources/kubedbComDruid/spec/internalUsers') - - if (internalUsers) { - Object.keys(internalUsers).map((key) => { - if (internalUsers[key]?.opendistroSecurityRoles) - delete internalUsers[key]?.opendistroSecurityRoles - }) - } + const druid = getValue(model, '/resources/kubedbComDruid') + const druidKind = druid?.apiVersion?.split('/')?.at(0) - commit('wizard/model$update', { - path: '/resources/kubedbComDruid/spec/internalUsers', - value: internalUsers, - force: true, - }) - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/topology/dataHot') - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/topology/dataWarm') + let isKubeStash = false + if ( + druid?.kind === kubeStashTarget?.kind && + druid?.metadata?.name === kubeStashTarget?.name && + druid?.metadata?.namespace === kubeStashTarget?.namespace && + druidKind === kubeStashTarget?.apiGroup + ) { + isKubeStash = true } - if (!isSearchGuard) { - const internalUsers = getValue(model, '/resources/kubedbComDruid/spec/internalUsers') - if (internalUsers) { - Object.keys(internalUsers).map((key) => { - if (internalUsers[key]?.searchGuardRoles) delete internalUsers[key]?.searchGuardRoles - }) - } + const kubedbComDruidAnnotations = + getValue(model, '/resources/kubedbComDruid/metadata/annotations') || {} - commit('wizard/model$update', { - path: '/resources/kubedbComDruid/spec/internalUsers', - value: internalUsers, - force: true, - }) - } + const isBluePrint = Object.keys(kubedbComDruidAnnotations).some( + (k) => + k === 'stash.appscode.com/backup-blueprint' || + k === 'stash.appscode.com/schedule' || + k.startsWith('params.stash.appscode.com/'), + ) - if (!isXpack) { - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/topology/dataCold') - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/topology/dataContent') - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/topology/dataFrozen') - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/topology/ml') - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/topology/transform') + return { + stashAppscodeComBackupConfiguration, + isBluePrint, + isKubeStash, } } -} -function onEnableSSLChange({ model, getValue, commit }) { - const enabelSSL = getValue(model, '/resources/kubedbComDruid/spec/enableSSL') - - if (enabelSSL === false) { - removeCertificatesOfAliases({ model, getValue, commit }, [ - 'http', - 'archiver', - 'metrics-exporter', - ]) + function deleteKubeDbComDruidAnnotation(getValue, model, commit) { + const annotations = getValue(model, '/resources/kubedbComDruid/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/kubedbComDruid/metadata/annotations', + value: filteredAnnotations, + }) } -} -function removeCertificatesOfAliases({ model, getValue, commit }, aliasesToRemove) { - const certificates = getValue(model, '/resources/kubedbComDruid/spec/tls/certificates') || [] - const updatedCertificates = certificates.filter((item) => !aliasesToRemove.includes(item.alias)) - commit('wizard/model$update', { - path: '/resources/kubedbComDruid/spec/tls/certificates', - value: updatedCertificates, - force: true, - }) -} + function addKubeDbComDruidAnnotation(getValue, model, commit, key, value, force) { + const annotations = getValue(model, '/resources/kubedbComDruid/metadata/annotations') || {} -/************************************* Database Secret Section ********************************************/ + if (annotations[key] === undefined) { + annotations[key] = value + } else if (force) { + annotations[key] = value + } -function getCreateAuthSecret({ model, getValue }) { - const authSecret = getValue(model, '/resources/kubedbComDruid/spec/authSecret') + commit('wizard/model$update', { + path: '/resources/kubedbComDruid/metadata/annotations', + value: annotations, + force: true, + }) + } - return !authSecret -} + function initScheduleBackupForEdit() { + const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( + getValue, + model, + ) -function showExistingSecretSection({ getValue, watchDependency, discriminator }) { - watchDependency('discriminator#/createAuthSecret') + initRepositoryChoiseForEdit() - const hasAuthSecretName = getValue(discriminator, '/createAuthSecret') - return !hasAuthSecretName -} + if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' + else return 'no' + } -function showPasswordSection({ getValue, watchDependency, discriminator }) { - return !showExistingSecretSection({ - getValue, - watchDependency, - discriminator, - }) -} + function initScheduleBackup({ getValue, model }) { + const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( + getValue, + model, + ) -function setAuthSecretPassword({ model, getValue, watchDependency, discriminator, commit }) { - watchDependency('discriminator#/selectedVersionAuthPlugin') + if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' + else return 'no' + } + + function onScheduleBackupChange() { + const scheduleBackup = getValue(discriminator, '/scheduleBackup') - const dist = getValue(discriminator, '/selectedVersionAuthPlugin') - if (dist) { - if (dist === 'X-Pack') { - const encodedPassword = getValue(model, '/resources/secret_elastic_cred/data/password') - commit('wizard/model$delete', '/resources/secret_admin_cred') - return encodedPassword ? decodePassword({}, encodedPassword) : '' + if (scheduleBackup === 'no') { + // delete stashAppscodeComBackupConfiguration + commit('wizard/model$delete', '/resources/stashAppscodeComBackupConfiguration') + commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') + // delete annotation from KubeDBComDruid annotation + deleteKubeDbComDruidAnnotation(getValue, model, commit) } else { - const encodedPassword = getValue(model, '/resources/secret_admin_cred/data/password') - commit('wizard/model$delete', '/resources/secret_elastic_cred') - return encodedPassword ? decodePassword({}, encodedPassword) : '' - } - } -} + const { isBluePrint } = getBackupConfigsAndAnnotations(getValue, model) -function onAuthSecretPasswordChange({ getValue, discriminator, commit }) { - const stringPassword = getValue(discriminator, '/password') - const dist = getValue(discriminator, '/selectedVersionAuthPlugin') + // create stashAppscodeComBackupConfiguration and initialize it if not exists - if (dist) { - if (stringPassword) { - if (dist === 'X-Pack') { - commit('wizard/model$update', { - path: '/resources/secret_elastic_cred/data/password', - value: encodePassword({}, stringPassword), - force: true, - }) + const dbName = getValue(model, '/metadata/release/name') + + if ( + !valueExists(model, getValue, '/resources/stashAppscodeComBackupConfiguration') && + !isBluePrint + ) { commit('wizard/model$update', { - path: '/resources/secret_elastic_cred/data/username', - value: encodePassword({}, 'elastic'), - force: true, + path: '/resources/stashAppscodeComBackupConfiguration', + value: stashAppscodeComBackupConfiguration, }) - commit('wizard/model$delete', '/resources/secret_admin_cred') - } else { commit('wizard/model$update', { - path: '/resources/secret_admin_cred/data/password', - value: encodePassword({}, stringPassword), + path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', + value: dbName, force: true, }) - commit('wizard/model$update', { - path: '/resources/secret_admin_cred/data/username', - value: encodePassword({}, 'admin'), - force: true, - }) - commit('wizard/model$delete', '/resources/secret_elastic_cred') } - } else { - commit('wizard/model$delete', '/resources/secret_admin_cred') - commit('wizard/model$delete', '/resources/secret_elastic_cred') } } -} - -// eslint-disable-next-line no-empty-pattern -function encodePassword({}, value) { - return btoa(value) -} - -// eslint-disable-next-line no-empty-pattern -function decodePassword({}, value) { - return atob(value) -} -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/authSecret') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/resources/secret_admin_cred') - commit('wizard/model$delete', '/resources/secret_elastic_cred') + // backup form + function showBackupForm() { + const scheduleBackup = getValue(discriminator, '/scheduleBackup') + // watchDependency('discriminator#/scheduleBackup') + if (scheduleBackup === 'yes') return true + else return false } -} - -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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 [] + function showScheduleBackup() { + // watchDependency('discriminator#/scheduleBackup') + const scheduleBackup = getValue(discriminator, '/scheduleBackup') + if (scheduleBackup === 'yes') return true + else return false } -} - -function showSecretSection({ model, getValue, watchDependency, storeGet }) { - const steps = storeGet('/wizard/configureOptions') - return ( - !steps.includes('internal-users') && isSecurityEnabled({ model, getValue, watchDependency }) - ) -} - -// ********************* Database Mode *********************** -function isNotCombinedMode({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - return mode !== 'Combined' -} + // backup configuration form + function initalizeTargetReferenceName({ getValue, model, watchDependency }) { + const databaseName = getValue(model, '/metadata/release/name') + watchDependency('model#/metadata/release/name') -function setDatabaseMode({ model, getValue }) { - isDedicatedSelected = getValue(model, '/resources/kubedbComDruid/spec/topology') - if (isDedicatedSelected) { - return 'Dedicated' - } else { - return 'Combined' + return databaseName } -} - -let storageClassList = [] -async function getStorageClassNames( - { axios, storeGet, commit, setDiscriminatorValue, getValue, model }, - path, -) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/storage.k8s.io/v1/storageclasses`, - { - params: { - filter: { items: { metadata: { name: null, annotations: 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 - }) - if (!path) { - setDiscriminatorValue('/storageClasses', resources) + // restore session repository + function setInitialRestoreSessionRepo({ getValue, model }) { + const value = getValue(model, 'resources/stashAppscodeComRepository_init_repo') + return value ? 'create' : 'select' } - storageClassList = resources - const initialStorageClass = getValue(model, path) - if (!initialStorageClass) setStorageClass({ model, getValue, commit }, path) - return resources -} - -function setStorageClass({ model, getValue, commit }, path) { - const deletionPolicy = getValue(model, 'resources/kubedbComDruid/spec/deletionPolicy') || '' - let storageClass = getValue(model, path) || '' - const suffix = '-retain' - - const simpleClassList = storageClassList.filter((item) => { - return !item.metadata?.name?.endsWith(suffix) - }) - - const retainClassList = storageClassList.filter((item) => { - return item.metadata?.name?.endsWith(suffix) - }) - const defaultSimpleList = simpleClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] + // backup config repository + function initRepositoryChoise({ getValue, model }) { + const stashAppscodeComRepository_repo = getValue( + model, + '/resources/stashAppscodeComRepository_repo', ) - }) - const defaultRetainList = retainClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] - ) - }) - - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - if (simpleClassList.length > 1) { - const found = defaultSimpleList.length ? defaultSimpleList[0] : simpleClassList[0] - storageClass = found.value - } else if (simpleClassList.length === 1) { - storageClass = simpleClassList[0]?.value - } else { - const found = defaultRetainList.length - ? defaultRetainList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found - } - } else { - if (retainClassList.length > 1) { - const found = defaultRetainList.length ? defaultRetainList[0] : retainClassList[0] - storageClass = found.value - } else if (retainClassList.length === 1) { - storageClass = retainClassList[0]?.value - } else { - const found = defaultSimpleList.length - ? defaultSimpleList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found - } + if (stashAppscodeComRepository_repo) return 'create' + else return 'select' } - if (storageClass && path) { - commit('wizard/model$update', { - path: path, - value: storageClass, - force: true, - }) - } -} + function initRepositoryChoiseForEdit() { + const stashAppscodeComRepository_repo = getValue( + model, + '/resources/stashAppscodeComRepository_repo', + ) + const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' + setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) -function deleteDatabaseModePath({ discriminator, getValue, commit }) { - const mode = getValue(discriminator, '/activeDatabaseMode') - if (mode === 'Dedicated') { - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/replicas') - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/storage') - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/maxUnavailable') - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/podTemplate') - } else if (mode === 'Combined') { - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/topology') + return repoInitialSelectionStatus } -} - -function isEqualToDatabaseMode({ getValue, watchDependency, discriminator }, value) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - return mode === value -} + function onRepositoryChoiseChange({ getValue, discriminator, watchDependency, commit, model }) { + const repositoryChoise = getValue(discriminator, '/repositoryChoise') + watchDependency('discriminator#/repositoryChoise') -function getMaxUnavailableOptions({ model, getValue, watchDependency, commit, elementUi }, path) { - let prefixPath - if (path) { - prefixPath = path - } else { - const { $ref } = elementUi.schema || {} - const replacedPath = ($ref || '').replace( - 'schema#/properties/resources/properties/kubedbComDruid/properties/spec/properties/topology/properties/', - '', - ) - const dyn = replacedPath.split('/').shift() - prefixPath = `/resources/kubedbComDruid/spec/topology/${dyn}` + if (repositoryChoise === 'select') { + // delete the stashAppscodeComRepository_repo + commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') + } else if (repositoryChoise === 'create') { + // create new stashAppscodeComRepository_repo + if (!valueExists(model, getValue, '/resources/stashAppscodeComRepository_repo')) { + commit('wizard/model$update', { + path: '/resources/stashAppscodeComRepository_repo', + value: stashAppscodeComRepository_repo, + }) + const repositoryName = `${getValue(model, '/metadata/release/name')}-repo` + // set this name in stashAppscodeComRestoreSession_init + commit('wizard/model$update', { + path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', + value: repositoryName, + }) + } + } } - watchDependency(`model#${prefixPath}/replicas`) - - const replicas = getValue(model, `${prefixPath}/replicas`) - const maxUnavailable = getValue(model, `${prefixPath}/maxUnavailable`) - - if (maxUnavailable > replicas) { + function onRepositoryNameChange({ getValue, model, commit }) { + const repositoryName = getValue( + model, + 'resources/stashAppscodeComRepository_repo/metadata/name', + ) + // set this name in stashAppscodeComRestoreSession_init commit('wizard/model$update', { - path: `${prefixPath}/maxUnavailable`, - value: replicas, - force: true, + path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', + value: repositoryName, }) } - const options = [] + // KubeStash Backup Functions + 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/kubedbComDruid') + 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 - for (let i = 0; i <= Math.min(replicas, 1000); i++) { - options.push(i) - } - return options -} + let url = `/clusters/${user}/${cluster}/helm/packageview/values?name=${chartName}&sourceApiGroup=${sourceApiGroup}&sourceKind=${sourceKind}&sourceNamespace=${sourceNamespace}&sourceName=${sourceName}&version=${chartVersion}&format=json` -function getStorageClassNamesFromDiscriminator( - { model, discriminator, getValue, watchDependency, commit }, - path, -) { - watchDependency('discriminator#/storageClasses') - const options = getValue(discriminator, '/storageClasses') || [] + if (spoke) + url = `/clusters/${user}/${spoke}/helm/packageview/values?name=${chartName}&sourceApiGroup=${sourceApiGroup}&sourceKind=${sourceKind}&sourceNamespace=${sourceNamespace}&sourceName=${sourceName}&version=${chartVersion}&format=json` - setStorageClass({ model, getValue, commit }, path) + const resp = await axios.get(url) - return options -} + valuesFromWizard = objectCopy(resp.data?.resources?.coreKubestashComBackupConfiguration) || {} + } catch (e) { + console.log(e) + } -async function getSelectedVersionAuthPlugin( - { model, getValue, watchDependency, axios, storeGet, setDiscriminatorValue }, - path, -) { - watchDependency('model#/resources/kubedbComDruid/spec/version') - const version = getValue(model, '/resources/kubedbComDruid/spec/version') || '' - - const elasticVersions = await getDruidVersions( - { axios, storeGet }, - 'catalog.kubedb.com', - 'v1alpha1', - 'druidversions', - ) + // check storageclass archiver annotation + if (initialArchiver) { + isArchiverAvailable = true + } else { + const storageClassName = dbResource?.spec?.topology?.historicals?.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) + } + } - const selectedVersion = elasticVersions?.find((item) => item.value === version) + // 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, + ) - const ret = selectedVersion?.spec?.authPlugin || '' + // 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, + ) - if (path) { - setDiscriminatorValue(path, ret) - } + // set backup switch here + isBackupOn = !!config - return ret -} + // set initial data from stash-presets + const stashPreset = storeGet('/backup/stashPresets') + if (stashPreset) { + const { retentionPolicy, encryptionSecret, schedule, storageRef } = stashPreset -function onNodeSwitchFalse({ elementSchema, commit }) { - const { $ref } = elementSchema || {} - const node = ($ref || '').split('/').pop() - commit('wizard/model$delete', `/resources/kubedbComDruid/spec/topology/${node}`) -} + const tempBackends = valuesFromWizard.spec?.backends + tempBackends[0]['storageRef'] = storageRef + tempBackends[0]['retentionPolicy'] = retentionPolicy + valuesFromWizard.spec['backends'] = tempBackends -function hasTopologyNode({ model, getValue, itemCtx }) { - const nodeValue = getValue(model, `/resources/kubedbComDruid/spec/topology/${itemCtx}`) + 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}` - return !nodeValue -} + tempSessions[0]['repositories'] = tempRepositories + tempSessions[0]['scheduler']['schedule'] = schedule + valuesFromWizard.spec['sessions'] = tempSessions + } -function hideNode({ itemCtx, discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/selectedVersionAuthPlugin') - const authPlugin = getValue(discriminator, '/selectedVersionAuthPlugin') - - let hiddenNodes = ['coordinating'] - - if (authPlugin === 'OpenDistro') { - hiddenNodes = ['coordinating', 'ml', 'dataCold', 'dataFrozen', 'dataContent', 'transform'] - } else if (authPlugin === 'SearchGuard') { - hiddenNodes = [ - 'coordinating', - 'ml', - 'dataWarm', - 'dataHot', - 'dataCold', - 'dataFrozen', - 'dataContent', - 'transform', - ] + 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) } - const verd = hiddenNodes.includes(itemCtx) - return verd -} + function isBackupDataLoadedTrue() { + // watchDependency('discriminator#/isBackupDataLoaded') + return !!getValue(discriminator, '/isBackupDataLoaded') + } -function setInitialStatusFalse({ elementSchema }) { - const disableNodes = ['master', 'data', 'ingest'] - const { $ref } = elementSchema || {} - const node = ($ref || '').split('/').pop() - return !disableNodes.includes(node) -} + function setBackupType() { + return 'BackupConfig' + } -function disableNode({ elementSchema }) { - const disableNodes = ['master', 'data', 'ingest'] - const { $ref } = elementSchema || {} - const node = ($ref || '').split('/').pop() - return disableNodes.includes(node) -} + function getTypes() { + const arr = [ + { + description: 'Create, Delete or Modify BackupConfig', + text: 'BackupConfig', + value: 'BackupConfig', + }, + { + description: 'Enable/Disable BackupBlueprint', + text: 'BackupBlueprint', + value: 'BackupBlueprint', + }, + ] -// ************************** Internal Users ******************************** - -const defaultUsers = [ - 'admin', - 'kibanaro', - 'kibanaserver', - 'logstash', - 'readall', - 'snapshotrestore', - 'metrics_exporter', -] - -function onInternalUsersChange({ discriminator, getValue, commit }) { - const users = getValue(discriminator, '/internalUsers') - - const internalUsers = {} - - if (users) { - users.forEach((item) => { - const { username, createCred, secretName, password, ...obj } = item - if (createCred === 'no') { - obj.secretName = secretName - commit('wizard/model$delete', `/resources/secret_${username}_cred`) - } else if (createCred === 'yes') { - if (password) { - commit('wizard/model$update', { - path: `/resources/secret_${username}_cred/data/password`, - value: encodePassword({}, password), - force: true, - }) - commit('wizard/model$update', { - path: `/resources/secret_${username}_cred/data/username`, - value: encodePassword({}, username), - force: true, - }) - } else { - commit('wizard/model$delete', `/resources/secret_${username}_cred`) - } - } - internalUsers[username] = obj - }) + if (dbResource?.spec?.topology && isArchiverAvailable) { + arr.push({ + description: 'Enable/Disable Archiver', + text: 'Archiver', + value: 'Archiver', + }) + } + return arr } - if (Object.keys(internalUsers).length) { + function onBackupTypeChange() { + const type = getValue(discriminator, '/backupType') commit('wizard/model$update', { - path: '/resources/kubedbComDruid/spec/internalUsers', - value: internalUsers, + path: '/backupType', + value: type, force: true, }) - } else { - // on initial call discriminator value is undefined - // to ignore model$delete for this case, - // users value checking is required, - // model$delete will be executed only if users value is not falsy value (empty array) - // and internalUsers is emptyObject - if (users) commit('wizard/model$delete', '/resources/kubedbComDruid/spec/internalUsers') - } -} - -function setInternalUsers({ model, getValue, watchDependency, setDiscriminatorValue }) { - watchDependency('model#/resources/kubedbComDruid/spec/internalUsers') - const internalUsers = getValue(model, '/resources/kubedbComDruid/spec/internalUsers') - - const users = [] - - for (const item in internalUsers) { - internalUsers[item].username = item - const encodedPassword = getValue(model, `/resources/secret_${item}_cred/data/password`) - if (internalUsers[item].secretName) { - internalUsers[item].createCred = 'no' + if (!isBackupOnModel) { + commit('wizard/model$delete', '/resources/coreKubestashComBackupConfiguration') } else { - if (encodedPassword) { - internalUsers[item].password = decodePassword({}, encodedPassword) - } - internalUsers[item].createCred = 'yes' + commit('wizard/model$update', { + path: '/resources/coreKubestashComBackupConfiguration', + value: objectCopy(initialModel), + force: true, + }) } - users.push(internalUsers[item]) + commit('wizard/model$delete', '/context') + commit('wizard/model$update', { + path: '/resources/kubedbComDruid', + value: objectCopy(dbResource), + force: true, + }) } - setDiscriminatorValue('/internalUsers', users) + function isBackupType(type) { + // watchDependency('discriminator#/backupType') + const selectedType = getValue(discriminator, '/backupType') - return users -} - -function validateNewUser({ itemCtx }) { - if (defaultUsers.includes(itemCtx.username) && itemCtx.isCreate) { - return { isInvalid: true, message: "Can't use this username" } + return selectedType === type } - return {} -} -function disableUsername({ rootModel }) { - return defaultUsers.includes(rootModel && rootModel.username) -} + function setBlueprintSwitch() { + const annotations = initialDbMetadata?.annotations -function disableUserEdit({ itemCtx }) { - if (defaultUsers.includes(itemCtx.username)) { - return { isEditDisabled: false, isDeleteDisabled: true } + return !!( + annotations['blueprint.kubestash.com/name'] && + annotations['blueprint.kubestash.com/namespace'] + ) } - return {} -} - -async function isAuthPluginEqualTo( - { model, getValue, watchDependency, axios, storeGet, setDiscriminatorValue }, - authPlugin, -) { - const dist = await getSelectedVersionAuthPlugin({ - model, - getValue, - watchDependency, - axios, - storeGet, - setDiscriminatorValue, - }) - return dist === authPlugin -} -// internal user cred -function showPasswordCredSection({ rootModel, getValue, watchDependency }) { - watchDependency('rootModel#/createCred') - const createCred = getValue(rootModel, '/createCred') + function onBlueprintChange() { + const blueprintSwitch = getValue(discriminator, '/blueprintEnabled') + if (blueprintSwitch) addLabelAnnotation(commit, storeGet, 'annotations') + else deleteLabelAnnotation(commit, 'annotations') + } - return createCred === 'yes' -} + function setArchiverSwitch() { + const archiver = dbResource?.spec?.archiver + return !!archiver + } -function showExistingCredSection({ rootModel, getValue, watchDependency }) { - return !showPasswordCredSection({ rootModel, getValue, watchDependency }) -} + function onArchiverChange() { + const archiverSwitch = getValue(discriminator, '/archiverEnabled') + const path = 'resources/kubedbComDruid/spec/archiver' + if (archiverSwitch) { + commit('wizard/model$update', { + path: path, + value: initialArchiver ? initialArchiver : archiverObjectToCommit, + }) + } else { + commit('wizard/model$delete', path) + } + } -function disableRoleDeletion({ itemCtx, rootModel }) { - return itemCtx === 'admin' && rootModel.username === 'admin' -} + function addLabelAnnotation(commit, storeGet, type) { + const obj = objectCopy(initialDbMetadata[type]) -// ************************** Roles Mapping ******************************** + 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' + } -const defaultRoles = ['readall_and_monitor'] + commit('wizard/model$update', { + path: `/resources/kubedbComDruid/metadata/${type}`, + value: obj, + force: true, + }) + } -function onRolesMappingChange({ discriminator, getValue, commit }) { - const roles = getValue(discriminator, '/rolesMapping') + function deleteLabelAnnotation(commit, type) { + const obj = initialDbMetadata[type] - const rolesMapping = {} + if (type === 'annotations') { + delete obj['blueprint.kubestash.com/name'] + delete obj['blueprint.kubestash.com/namespace'] + } else delete obj['kubedb.com/archiver'] - if (roles) { - roles.forEach((item) => { - const { roleName, ...obj } = item - rolesMapping[roleName] = obj + commit('wizard/model$update', { + path: `/resources/kubedbComDruid/metadata/${type}`, + value: obj, + force: true, }) } - if (Object.keys(rolesMapping).length) { + function getContext() { + if (isBackupOn) return ['Create', 'Delete', 'Modify'] + return ['Create'] + } + + function onContextChange() { + const context = getValue(discriminator, '/backupConfigContext') commit('wizard/model$update', { - path: '/resources/kubedbComDruid/spec/rolesMapping', - value: rolesMapping, + path: '/context', + value: context, force: true, }) - } else { - // on initial call discriminator value is undefined - // to ignore model$delete for this case, - // roles value checking is required, - // model$delete will be executed only if roles value is not falsy value (empty array) - // and rolesMapping is emptyObject - if (roles) commit('wizard/model$delete', '/resources/kubedbComDruid/spec/rolesMapping') + 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 setRolesMapping({ model, getValue, watchDependency, setDiscriminatorValue }) { - watchDependency('model#/resources/kubedbComDruid/spec/rolesMapping') - const rolesMapping = getValue(model, '/resources/kubedbComDruid/spec/rolesMapping') - const roles = [] + function onConfigChange() { + const configName = getValue(discriminator, '/config') + const configs = objectCopy(backupConfigurationsFromStore) + const configDetails = configs?.find((item) => item?.metadata?.name === configName) - for (const item in rolesMapping) { - rolesMapping[item].roleName = item - roles.push(rolesMapping[item]) + commit('wizard/model$update', { + path: '/resources/coreKubestashComBackupConfiguration', + value: configDetails, + force: true, + }) } - setDiscriminatorValue('/rolesMapping', roles) - - return roles -} - -function disableRolesEdit({ itemCtx }) { - if (defaultRoles.includes(itemCtx.roleName)) { - return { isEditDisabled: false, isDeleteDisabled: true } + function showPause() { + // watchDependency('discriminator#/backupConfigContext') + // watchDependency('discriminator#/config') + const contex = getValue(discriminator, '/backupConfigContext') + const configName = getValue(discriminator, '/config') + return !!configName && contex === 'Modify' } - return {} -} - -function disableRoleName({ rootModel }) { - return defaultRoles.includes(rootModel && rootModel.roleName) -} -function validateNewRole({ itemCtx }) { - if (defaultRoles.includes(itemCtx.roleName) && itemCtx.isCreate) { - return { isInvalid: true, message: "Can't use this role name" } + function showConfigList() { + // watchDependency('discriminator#/backupConfigContext') + const contex = getValue(discriminator, '/backupConfigContext') + return contex === 'Modify' || contex === 'Delete' } - return {} -} -function getInternalUsers({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComDruid/spec/internalUsers') - const internalUsers = getValue(model, '/resources/kubedbComDruid/spec/internalUsers') + 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 + } - return Object.keys(internalUsers) -} + function getNamespaceArray() { + return namespaceList + } -function disableUserDeletion({ itemCtx, rootModel }) { - return itemCtx.value === 'metrics_exporter' && rootModel.roleName === 'readall_and_monitor' -} + function onInputChange( + { getValue, discriminator, watchDependency, commit, model }, + modelPath, + field, + subfield, + discriminatorName, + ) { + const value = getValue(discriminator, `/${discriminatorName}`) + const backends = getValue(model, modelPath) || [] + if (field !== 'encryptionSecret') backends[0][field][subfield] = value + else backends[0]['repositories'][0][field][subfield] = value + commit('wizard/model$update', { + path: modelPath, + value: backends, + }) + } -// ************************* Kernel Settings ********************************* + function setFileValueFromStash({ getValue, commit, model }, modelPath, field, subfield, value) { + const backends = getValue(model, modelPath) + if (field !== 'encryptionSecret') backends[0][field][subfield] = value + else backends[0]['repositories'][0][field][subfield] = value + commit('wizard/model$update', { + path: modelPath, + value: backends, + }) + } -function onCustomizeKernelSettingChange({ discriminator, getValue, commit }) { - const customizeKernelSettings = getValue(discriminator, '/customizeKernelSettings') + 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, + force: true, + }) + } + } - if (customizeKernelSettings === 'no') { - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/kernelSettings') - } else if (customizeKernelSettings === 'disable') { + function setInitSchedule( + { getValue, discriminator, watchDependency, commit, model }, + modelPath, + value, + ) { + const session = getValue(model, modelPath) + session[0].scheduler.schedule = value commit('wizard/model$update', { - path: '/resources/kubedbComDruid/spec/kernelSettings', - value: {}, - force: true, + path: modelPath, + value: session, }) } -} -// ************************** TLS ******************************************* + function getDefault({ getValue, model }, modelPath, field, subfield) { + const backends = getValue(model, modelPath) + if (field !== 'encryptionSecret') return backends[0][field][subfield] + else { + return backends[0]['repositories'][0][field][subfield] + } + } -function setApiGroup() { - return 'cert-manager.io' -} + 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 setApiGroupEdit({ model, getValue }) { - const kind = getValue(model, '/resources/kubedbComDruid/spec/tls/issuerRef/kind') - const name = getValue(model, '/resources/kubedbComDruid/spec/tls/issuerRef/name') - return kind && name ? 'cert-manager.io' : '' -} + async function fetchNamespaces({ axios, storeGet }) { + const username = storeGet('/route/params/user') + const clusterName = storeGet('/route/params/cluster') + const group = storeGet('/route/params/group') + const version = storeGet('/route/params/version') + const resource = storeGet('/route/params/resource') -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - watchDependency('model#/resources/kubedbComDruid/spec/tls/issuerRef/apiGroup') - watchDependency('model#/resources/kubedbComDruid/spec/tls/issuerRef/kind') - watchDependency('model#/metadata/release/namespace') - const apiGroup = getValue(model, '/resources/kubedbComDruid/spec/tls/issuerRef/apiGroup') - const kind = getValue(model, '/resources/kubedbComDruid/spec/tls/issuerRef/kind') - const namespace = getValue(model, '/metadata/release/namespace') + const url = `clusters/${username}/${clusterName}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews` - let url - if (kind === 'Issuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/namespaces/${namespace}/issuers` - } else if (kind === 'ClusterIssuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/clusterissuers` + try { + const resp = await axios.post(url, { + _recurringCall: false, + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, + }) + if (resp.data?.status?.projects) { + const projects = resp.data?.status?.projects + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } + } catch (e) { + console.log(e) + } + return [] } - 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) + async function fetchNames( + { getValue, axios, storeGet, watchDependency, discriminator }, + version, + type, + discriminatorName, + ) { + watchDependency(`discriminator#/${discriminatorName}`) + const username = storeGet('/route/params/user') + const clusterName = storeGet('/route/params/cluster') + const namespace = getValue(discriminator, `${discriminatorName}`) + const url = + type !== 'secrets' + ? `clusters/${username}/${clusterName}/proxy/storage.kubestash.com/${version}/namespaces/${namespace}/${type}` + : `clusters/${username}/${clusterName}/proxy/core/${version}/namespaces/${namespace}/${type}` + try { + if (namespace) { + const resp = await axios.get(url) + let data = resp.data.items + if (type === 'secrets') data = data.filter((ele) => !!ele.data['RESTIC_PASSWORD']) + data = data.map((ele) => ele.metadata.name) + return data + } + } catch (e) { + console.log(e) + } return [] } -} -async function hasIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await getIssuerRefsName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) + async function getBlueprints( + { getValue, model, setDiscriminatorValue, axios, storeGet }, + backup, + ) { + const username = storeGet('/route/params/user') + const clusterName = storeGet('/route/params/cluster') + const url = `clusters/${username}/${clusterName}/proxy/core.kubestash.com/v1alpha1/backupblueprints` - return !!(resp && resp.length) -} + try { + const resp = await axios.get(url) + let data = resp.data.items + return data + } catch (e) { + console.log(e) + } + } -async function hasNoIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await hasIssuerRefName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) + function isBlueprintOption({ discriminator, getValue, watchDependency }, value) { + watchDependency('discriminator#/blueprintOptions') + const blueprintOptions = getValue(discriminator, '/blueprintOptions') + return blueprintOptions === value + } - return !resp -} + function ifUsagePolicy({ discriminator, getValue, watchDependency, model }, value) { + watchDependency( + 'model#/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', + ) + const usagePolicy = getValue( + model, + '/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', + ) + return usagePolicy === value + } -function setClusterAuthMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComDruid/spec/clusterAuthMode') - return val || 'x509' -} + function showBackupOptions({ discriminator, getValue, watchDependency }, backup) { + const backupEnabled = getValue(discriminator, '/backupEnabled') + if (backupEnabled) { + if (backup === 'alert') return true + else return false + } else { + if (backup === 'alert') return false + else return true + } + } -function setSSLMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComDruid/spec/sslMode') - return val || 'requireSSL' -} + // ************************* Monitoring Functions ********************************************** -function showTlsConfigureSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configureTLS') - const configureStatus = getValue(discriminator, '/configureTLS') - return configureStatus -} + /** + * Determines whether to show the monitoring configuration section + * @returns {boolean} True if monitoring is enabled + */ + function showMonitoringSection() { + // watchDependency('discriminator#/enableMonitoring') + const configureStatus = getValue(discriminator, '/enableMonitoring') + return configureStatus + } + + /** + * Handles changes to the monitoring enable/disable toggle + * Updates the monitor spec and alert configuration accordingly + */ + function onEnableMonitoringChange() { + const configureStatus = getValue(discriminator, '/enableMonitoring') + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComDruid/spec/monitor', + value: {}, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/kubedbComDruid/spec/monitor') + } -function onTlsConfigureChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/configureTLS') - if (configureStatus) { + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: '/resources/kubedbComDruid/spec/tls', - value: { issuerRef: {}, certificates: [] }, + path: '/form/alert/enabled', + value: configureStatus ? 'warning' : 'none', force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/tls') - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/clusterAuthMode') - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/sslMode') } -} -async function showTlsRecommendation({ axios, storeGet }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const url = `/clusters/${owner}/${cluster}/proxy/cert-manager.io/v1/issuers` - - try { - await axios.get(url, { - params: { filter: { items: { metadata: { name: null } } } }, - }) - return false - } catch (err) { - // if any error response status is 404 or not - if (err.response && err.response.status === 404) { - resp = false - } - console.log(err) - return true - } -} - -async function getAliasOptions({ - model, - getValue, - watchDependency, - axios, - storeGet, - setDiscriminatorValue, -}) { - watchDependency('model#/resources/kubedbComDruid/spec/enableSSL') - watchDependency('model#/resources/kubedbComDruid/spec/monitor') - - const enableSSL = getValue(model, '/resources/kubedbComDruid/spec/enableSSL') - const monitor = getValue(model, '/resources/kubedbComDruid/spec/monitor') - const authPlugin = await getSelectedVersionAuthPlugin({ - model, - getValue, - watchDependency, - axios, - storeGet, - setDiscriminatorValue, - }) - - // always include transport cert alias - const aliases = ['transport'] - - if (authPlugin !== 'X-Pack') { - aliases.push('admin') - } - - if (enableSSL) { - aliases.push('http') - aliases.push('archiver') - if (monitor) { - aliases.push('metrics-exporter') - } - } - - return aliases -} - -/****** Monitoring *********/ - -function showMonitoringSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/enableMonitoring') - const configureStatus = getValue(discriminator, '/enableMonitoring') - return configureStatus -} - -function onEnableMonitoringChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/enableMonitoring') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComDruid/spec/monitor', - value: {}, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComDruid/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, getValue }) { - watchDependency('discriminator#/customizeExporter') - const configureStatus = getValue(discriminator, '/customizeExporter') - return configureStatus -} - -function onCustomizeExporterChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/customizeExporter') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComDruid/spec/monitor/prometheus/exporter', - value: {}, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/monitor/prometheus/exporter') - } -} - -// ********************************* Initialization & Backup ************************************* -const stashAppscodeComRestoreSession_init = { - spec: { - repository: { - name: '', - }, - rules: [ - { - snapshots: ['latest'], - }, - ], - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} -const initScript = { - scriptPath: '', - secret: { - secretName: '', - }, -} -const stashAppscodeComRepository_init_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const stashAppscodeComRepository_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const restoreSessionInitRunTimeSettings = { - container: { - resources: { - requests: { - cpu: '', - memory: '', - }, - limits: { - cpu: '', - memory: '', - }, - }, - nice: { - adjustment: null, - }, - ionice: { - class: null, - classData: null, - }, - securityContext: { - privileged: false, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - env: [], - envFrom: [], - }, - pod: { - serviceAccountName: '', - imagePullSecrets: [], - securityContext: { - fsGroup: null, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - }, -} - -const stashAppscodeComBackupConfiguration = { - spec: { - repository: { - name: '', - }, - retentionPolicy: { - keepLast: 5, - name: 'keep-last-5', - prune: true, - }, - schedule: '*/5 * * * *', - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} - -function disableInitializationSection({ model, getValue, watchDependency }) { - const initialized = getValue(model, '/resources/kubedbComDruid/spec/init/initialized') - watchDependency('model#/resources/kubedbComDruid/spec/init/initialized') - return !!initialized -} - -function valueExists(value, getValue, path) { - const val = getValue(value, path) - if (val) return true - else return false -} - -function initPrePopulateDatabase({ getValue, model }) { - const waitForInitialRestore = getValue( - model, - '/resources/kubedbComDruid/spec/init/waitForInitialRestore', - ) - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - const script = getValue(model, '/resources/kubedbComDruid/spec/init/script') - - return waitForInitialRestore || !!stashAppscodeComRestoreSession_init || !!script ? 'yes' : 'no' -} - -function onPrePopulateDatabaseChange({ commit, getValue, discriminator, model }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - if (prePopulateDatabase === 'no') { - // delete related properties - commit('wizard/model$update', { - path: '/resources/kubedbComDruid/spec/init/waitForInitialRestore', - value: false, - }) - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/init/script') - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else { - const dbName = getValue(model, '/metadata/release/name') - // set stashAppscodeComRestoreSession_init if it doesn't exist - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - force: true, - }) + /** + * Determines whether to show the exporter customization section + * @returns {boolean} True if exporter customization is enabled + */ + function showCustomizeExporterSection() { + // watchDependency('discriminator#/customizeExporter') + const configureStatus = getValue(discriminator, '/customizeExporter') + return configureStatus + } + /** + * Handles changes to the exporter customization toggle + * Creates or removes the prometheus exporter configuration + */ + function onCustomizeExporterChange() { + const configureStatus = getValue(discriminator, '/customizeExporter') + if (configureStatus) { commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - } - } -} - -function initDataSource({ getValue, model }) { - const script = getValue(model, '/resources/kubedbComDruid/spec/init/script') - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - - if (script) return 'script' - else if (stashAppscodeComRestoreSession_init) return 'stashBackup' - else return undefined -} - -function onDataSourceChange({ commit, getValue, discriminator, model }) { - const dataSource = getValue(discriminator, '/dataSource') - - commit('wizard/model$update', { - path: '/resources/kubedbComDruid/spec/init/waitForInitialRestore', - value: dataSource === 'stashBackup', - force: true, - }) - - if (dataSource === 'script') { - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - - // create a new script if there is no script property - if (!valueExists(model, getValue, '/resources/kubedbComDruid/spec/init/script')) - commit('wizard/model$update', { - path: '/resources/kubedbComDruid/spec/init/script', - value: initScript, - }) - } else if (dataSource === 'stashBackup') { - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/init/script') - - // create a new stashAppscodeComRestoreSession_init if there is no stashAppscodeComRestoreSession_init property - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - const dbName = getValue(model, '/metadata/release/name') - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - }) - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - } - } -} - -// // for script -function initVolumeType({ getValue, model }) { - const configMap = getValue(model, '/resources/kubedbComDruid/spec/init/script/configMap/name') - const secret = getValue(model, '/resources/kubedbComDruid/spec/init/script/secret/secretName') - - if (configMap) return 'configMap' - else if (secret) return 'secret' - else return undefined -} - -function onVolumeTypeChange({ commit, getValue, discriminator, model }) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - if (sourceVolumeType === 'configMap') { - // add configMap object and delete secret object - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/init/script/secret') - - if (!valueExists(model, getValue, '/resources/kubedbComDruid/spec/init/script/configMap')) { - commit('wizard/model$update', { - path: '/resources/kubedbComDruid/spec/init/script/configMap', - value: { - name: '', - }, - }) - } - } else if (sourceVolumeType === 'secret') { - // delete configMap object and add secret object - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/init/script/configMap') - - if (!valueExists(model, getValue, '/resources/kubedbComDruid/spec/init/script/secret')) { - commit('wizard/model$update', { - path: '/resources/kubedbComDruid/spec/init/script/secret', - value: { - secretName: '', - }, - }) - } - } -} - -function showInitializationForm({ getValue, discriminator, watchDependency }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - watchDependency('discriminator#/prePopulateDatabase') - return prePopulateDatabase === 'yes' -} - -function showScriptOrStashForm({ getValue, discriminator, watchDependency }, value) { - const dataSource = getValue(discriminator, '/dataSource') - watchDependency('discriminator#/dataSource') - return dataSource === value -} - -function showConfigMapOrSecretName({ getValue, discriminator, watchDependency }, value) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - watchDependency('discriminator#/sourceVolumeType') - return sourceVolumeType === value -} - -// for stash backup -function initializeNamespace({ getValue, model }) { - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} - -function showRepositorySelectOrCreate({ getValue, discriminator, watchDependency }, value) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - return repositoryChoise === value -} - -function onInitRepositoryChoiseChange({ getValue, discriminator, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - if (repositoryChoise === 'select') { - // delete stashAppscodeComRepository_init_repo from model - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else if (repositoryChoise === 'create') { - // add stashAppscodeComRepository_init_repo to model - commit('wizard/model$update', { - path: 'resources/stashAppscodeComRepository_init_repo', - value: stashAppscodeComRepository_init_repo, - }) - - const repositoryName = `${getValue(model, '/metadata/release/name')}-init-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: repositoryName, - }) - } -} - -function initCustomizeRestoreJobRuntimeSettings({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function initCustomizeRestoreJobRuntimeSettingsForBackup({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function onCustomizeRestoreJobRuntimeSettingsChange({ commit, getValue, discriminator, model }) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - value: restoreSessionInitRunTimeSettings, - }) - } - } -} - -function onCustomizeRestoreJobRuntimeSettingsChangeForBackup({ - commit, - getValue, - discriminator, - model, -}) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', + path: '/resources/kubedbComDruid/spec/monitor/prometheus/exporter', value: {}, force: true, }) + } else { + commit('wizard/model$delete', '/resources/kubedbComDruid/spec/monitor/prometheus/exporter') } } -} - -function showRuntimeForm({ discriminator, getValue, watchDependency }, value) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - watchDependency('discriminator#/customizeRestoreJobRuntimeSettings') - return customizeRestoreJobRuntimeSettings === value -} - -async function getImagePullSecrets({ getValue, model, watchDependency, axios, storeGet }) { - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - - let resources = await getNamespacedResourceList(axios, storeGet, { - namespace, - group: 'core', - version: 'v1', - resource: 'secrets', - }) - - resources = resources.filter((item) => { - const validType = ['kubernetes.io/dockerconfigjson'] - return validType.includes(item.type) - }) - - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: { name: name }, - } - }) -} - -// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// FOR Backup Configuration - -// schedule bakcup - -function getBackupConfigsAndAnnotations(getValue, model) { - const stashAppscodeComBackupConfiguration = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration', - ) - const kubedbComDruidAnnotations = - getValue(model, '/resources/kubedbComDruid/metadata/annotations') || {} - - const isBluePrint = Object.keys(kubedbComDruidAnnotations).some( - (k) => - k === 'stash.appscode.com/backup-blueprint' || - k === 'stash.appscode.com/schedule' || - k.startsWith('params.stash.appscode.com/'), - ) - - return { - stashAppscodeComBackupConfiguration, - isBluePrint, - } -} - -function deleteKubedbComDruidDbAnnotation(getValue, model, commit) { - const annotations = getValue(model, '/resources/kubedbComDruid/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/kubedbComDruid/metadata/annotations', - value: filteredAnnotations, - }) -} - -function addKubedbComDruidDbAnnotation(getValue, model, commit, key, value, force) { - const annotations = getValue(model, '/resources/kubedbComDruid/metadata/annotations') || {} - - if (annotations[key] === undefined) { - annotations[key] = value - } else if (force) { - annotations[key] = value - } - - commit('wizard/model$update', { - path: '/resources/kubedbComDruid/metadata/annotations', - value: annotations, - force: true, - }) -} - -function initScheduleBackupForEdit({ getValue, model, setDiscriminatorValue }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function initScheduleBackup({ getValue, model }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function onScheduleBackupChange({ commit, getValue, discriminator, model }) { - 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 kubedbComDruid annotation - deleteKubedbComDruidDbAnnotation(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, - }) - } - } -} - -// backup form -function showBackupForm({ getValue, discriminator, watchDependency }) { - const scheduleBackup = getValue(discriminator, '/scheduleBackup') - watchDependency('discriminator#/scheduleBackup') - - if (scheduleBackup === 'yes') return true - else return false -} - -// invoker form -async function initBackupInvoker({ getValue, model, storeGet, commit, axios }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - const apiGroup = getValue(model, '/metadata/resource/group') - let kind = getValue(model, '/metadata/resource/kind') - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const name = storeGet('/route/params/name') - const namespace = storeGet('/route/query/namespace') - const group = storeGet('/route/params/group') - const version = storeGet('/route/params/version') - const resource = storeGet('/route/params/resource') - let labels = {} - - const sessions = getValue(model, '/resources/coreKubestashComBackupConfiguration/spec/sessions') - sessions[0].repositories[0].name = name - sessions[0].repositories[0].directory = `/${name}` - - commit('wizard/model$update', { - path: '/resources/coreKubestashComBackupConfiguration/spec/sessions', - value: sessions, - force: true, - }) - - const url = `clusters/${username}/${clusterName}/proxy/${group}/${version}/namespaces/${namespace}/${resource}/${name}` - - try { - const resp = await axios.get(url) - labels = resp.data.metadata.labels - kind = resp.data.kind - } catch (e) { - console.log(e) - } - - commit('wizard/model$update', { - path: '/metadata/release', - value: { - labels: labels, - name: name, - namespace: namespace, - }, - force: true, - }) - - commit('wizard/model$update', { - path: '/resources/coreKubestashComBackupConfiguration/metadata', - value: { - labels: labels, - name: name, - namespace: namespace, - }, - force: true, - }) - - commit('wizard/model$update', { - path: '/resources/coreKubestashComBackupConfiguration/spec/target', - value: { - apiGroup: apiGroup, - kind: kind, - name: name, - namespace: namespace, - }, - force: true, - }) - - let isStashPresetEnable = false - try { - const url = `/clusters/${username}/${clusterName}/proxy/ui.k8s.appscode.com/v1alpha1/features` - const resp = await axios.get(url) - const stashFeature = resp.data.items.filter((item) => { - return item.metadata.name === 'stash-presets' - }) - if (stashFeature[0].status?.enabled) { - isStashPresetEnable = true - } - } catch (e) { - console.log(e) - } - let schedule = '' - let storageRefName = '' - let storageRefNamespace = '' - let retentionPolicyName = '' - let retentionPolicyNamespace = '' - let encryptionSecretName = '' - let encryptionSecretNamespace = '' - - if (isStashPresetEnable) { - try { - const url = `clusters/${username}/${clusterName}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/stash-presets` - const resp = await axios.get(url) - schedule = resp.data.spec.values.spec.backup.kubestash.schedule - storageRefName = resp.data.spec.values.spec.backup.kubestash.storageRef.name - storageRefNamespace = resp.data.spec.values.spec.backup.kubestash.storageRef.namespace - retentionPolicyName = resp.data.spec.values.spec.backup.kubestash.retentionPolicy.name - retentionPolicyNamespace = - resp.data.spec.values.spec.backup.kubestash.retentionPolicy.namespace - encryptionSecretName = resp.data.spec.values.spec.backup.kubestash.encryptionSecret.name - encryptionSecretNamespace = - resp.data.spec.values.spec.backup.kubestash.encryptionSecret.namespace - } catch (e) { - console.log(e) - } - } - setInitSchedule( - { getValue, commit, model }, - 'resources/coreKubestashComBackupConfiguration/spec/sessions/', - schedule, - ) - setFileValueFromStash( - { getValue, commit, model }, - 'resources/coreKubestashComBackupConfiguration/spec/backends', - 'storageRef', - 'namespace', - storageRefNamespace, - ) - setFileValueFromStash( - { getValue, commit, model }, - 'resources/coreKubestashComBackupConfiguration/spec/backends', - 'storageRef', - 'name', - storageRefName, - ) - setFileValueFromStash( - { getValue, commit, model }, - 'resources/coreKubestashComBackupConfiguration/spec/backends', - 'retentionPolicy', - 'namespace', - retentionPolicyNamespace, - ) - setFileValueFromStash( - { getValue, commit, model }, - 'resources/coreKubestashComBackupConfiguration/spec/backends', - 'retentionPolicy', - 'name', - retentionPolicyName, - ) - setFileValueFromStash( - { getValue, commit, model }, - 'resources/coreKubestashComBackupConfiguration/spec/sessions', - 'encryptionSecret', - 'namespace', - encryptionSecretNamespace, - ) - setFileValueFromStash( - { getValue, commit, model }, - 'resources/coreKubestashComBackupConfiguration/spec/sessions', - 'encryptionSecret', - 'name', - encryptionSecretName, - ) - - if (stashAppscodeComBackupConfiguration) return 'backupConfiguration' - else if (isBluePrint) return 'backupBlueprint' - else return undefined -} - -function onBackupInvokerChange({ getValue, discriminator, commit, model }) { - const backupInvoker = getValue(discriminator, '/backupInvoker') - - if (backupInvoker === 'backupConfiguration') { - // delete annotation and create backup config object - deleteKubedbComDruidDbAnnotation(getValue, model, commit) - const dbName = getValue(model, '/metadata/release/name') - - if (!valueExists(model, getValue, '/resources/stashAppscodeComBackupConfiguration')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration', - value: stashAppscodeComBackupConfiguration, - }) - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, - force: true, - }) - } - } else if (backupInvoker === 'backupBlueprint') { - // delete backup configuration object and create the annotation - commit('wizard/model$delete', '/resources/stashAppscodeComBackupConfiguration') - addKubedbComDruidDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/backup-blueprint', - '', - ) - } -} - -function showInvokerForm({ getValue, discriminator, watchDependency }, value) { - const backupInvoker = getValue(discriminator, '/backupInvoker') - watchDependency('discriminator#/backupInvoker') - - return backupInvoker === value -} - -// backup configuration form -function initalizeTargetReferenceName({ getValue, model, watchDependency }) { - const databaseName = getValue(model, '/metadata/release/name') - watchDependency('model#/metadata/release/name') - - return databaseName -} - -// restore session repository -function setInitialRestoreSessionRepo({ getValue, model }) { - const value = getValue(model, 'resources/stashAppscodeComRepository_init_repo') - return value ? 'create' : 'select' -} - -// backup config repository -function initRepositoryChoise({ getValue, model }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - - if (stashAppscodeComRepository_repo) return 'create' - else return 'select' -} - -function initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' - setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) - - return repoInitialSelectionStatus -} - -function onRepositoryChoiseChange({ getValue, discriminator, watchDependency, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - if (repositoryChoise === 'select') { - // delete the stashAppscodeComRepository_repo - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') - } else if (repositoryChoise === 'create') { - // create new stashAppscodeComRepository_repo - if (!valueExists(model, getValue, '/resources/stashAppscodeComRepository_repo')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRepository_repo', - value: stashAppscodeComRepository_repo, - }) - const repositoryName = `${getValue(model, '/metadata/release/name')}-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) - } - } -} - -function onRepositoryNameChange({ getValue, model, commit }) { - const repositoryName = getValue(model, 'resources/stashAppscodeComRepository_repo/metadata/name') - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) -} - -// backup blueprint form -function getMongoAnnotations(getValue, model) { - const annotations = getValue(model, '/resources/kubedbComDruid/metadata/annotations') - return { ...annotations } || {} -} - -function initFromAnnotationValue({ getValue, model }, key) { - const annotations = getMongoAnnotations(getValue, model) - return annotations[key] -} - -function onBackupBlueprintNameChange({ getValue, discriminator, commit, model }) { - const backupBlueprintName = getValue(discriminator, '/backupBlueprintName') - addKubedbComDruidDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/backup-blueprint', - backupBlueprintName, - true, - ) -} - -function onBackupBlueprintScheduleChange({ getValue, discriminator, commit, model }) { - const backupBlueprintSchedule = getValue(discriminator, '/schedule') - addKubedbComDruidDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/schedule', - backupBlueprintSchedule, - true, - ) -} - -function initFromAnnotationKeyValue({ getValue, model }, prefix) { - const annotations = getMongoAnnotations(getValue, model) - const newOb = {} - Object.keys(annotations).forEach((key) => { - if (key.startsWith(prefix)) { - const newKey = key.replace(prefix, '') - newOb[newKey] = annotations[key] - } - }) - return newOb -} - -function onTaskParametersChange({ getValue, discriminator, model, commit }) { - const taskParameters = getValue(discriminator, '/taskParameters') - - const taskParamterKeys = Object.keys(taskParameters).map( - (tp) => `params.stash.appscode.com/${tp}`, - ) - const oldAnnotations = getValue(model, '/resources/kubedbComDruid/metadata/annotations') || {} - const newAnnotations = {} - - const filteredAnnotationKeys = Object.keys(oldAnnotations).filter( - (key) => !taskParamterKeys.includes(key) && !key.startsWith('params.stash.appscode.com/'), - ) - - filteredAnnotationKeys.forEach((key) => { - newAnnotations[key] = oldAnnotations[key] - }) - - Object.keys(taskParameters).forEach((tpk) => { - newAnnotations[`params.stash.appscode.com/${tpk}`] = taskParameters[tpk] - }) - - commit('wizard/model$update', { - path: '/resources/kubedbComDruid/metadata/annotations', - value: newAnnotations, - }) -} - -function isValueExistInModel({ model, getValue }, path) { - const modelValue = getValue(model, path) - return !!modelValue -} - -function onNamespaceChange({ commit, model, getValue }) { - const namespace = getValue(model, '/metadata/release/namespace') - const agent = getValue(model, '/resources/kubedbComDruid/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', - value: [namespace], - force: true, - }) - } -} -function onLabelChange({ commit, model, getValue }) { - const labels = getValue(model, '/resources/kubedbComDruid/spec/metadata/labels') - - const agent = getValue(model, '/resources/kubedbComDruid/spec/monitor/agent') - - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) - } -} - -function onNameChange({ commit, model, getValue }) { - const dbName = getValue(model, '/metadata/release/name') - - const agent = getValue(model, '/resources/kubedbComDruid/spec/monitor/agent') - - const labels = getValue(model, '/resources/kubedbComDruid/spec/metadata/labels') - - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) + /** + * Checks if a value exists in the model at the specified path + * @param {string} path - The model path to check + * @returns {boolean} True if value exists and is truthy + */ + function isValueExistInModel(path) { + const modelValue = getValue(model, path) + return !!modelValue } - const scheduleBackup = getValue(model, '/resources/stashAppscodeComBackupConfiguration') - - if (scheduleBackup) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_repo') - if (creatingNewRepo) { + function onNamespaceChange({ commit, model, getValue }) { + const namespace = getValue(model, '/metadata/release/namespace') + const agent = getValue(model, '/resources/kubedbComDruid/spec/monitor/agent') + if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: `${dbName}-repo`, + path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + value: [namespace], force: true, }) } } - const prePopulateDatabase = getValue(model, '/resources/stashAppscodeComRestoreSession_init') + function onLabelChange({ commit, model, getValue }) { + const labels = getValue(model, '/resources/kubedbComDruid/spec/metadata/labels') - if (prePopulateDatabase) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_init_repo') - if (creatingNewRepo) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: `${dbName}-init-repo`, - force: true, - }) - } - } + const agent = getValue(model, '/resources/kubedbComDruid/spec/monitor/agent') - // to reset configSecret name field - const hasSecretConfig = getValue(model, '/resources/secret_user_config') - if (hasSecretConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComDruid/spec/configSecret/name', - value: `${dbName}-config`, - force: true, - }) - } -} - -function returnFalse() { - return false -} - -function onAgentChange({ commit, model, getValue }) { - const agent = getValue(model, '/resources/kubedbComDruid/spec/monitor/agent') - - if (!agent) { - removeCertificatesOfAliases({ model, getValue, commit }, ['metrics-exporter']) - } - - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', - value: [], - force: true, - }) - - onNamespaceChange({ commit, model, getValue }) - onLabelChange({ commit, model, getValue }) - } else { - commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') - } -} - -//////////////////// service monitor /////////////////// - -function isEqualToServiceMonitorType({ rootModel, watchDependency }, value) { - watchDependency('rootModel#/spec/type') - return rootModel && rootModel.spec && rootModel.spec.type === value -} - -//////////////////// custom config ///////////////// -function onConfigurationSourceChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSource') - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_user_config') - commit('wizard/model$delete', '/resources/config_secret') - } else { - const value = getValue(model, '/resources/secret_user_config') - if (!value) { + if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: '/resources/secret_user_config', - value: {}, + path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', + value: labels, force: true, }) } - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComDruid/spec/configSecret/name', - value: configSecretName, - force: true, - }) - } -} - -function setConfigurationSource({ model, getValue }) { - const modelValue = getValue(model, '/resources/secret_user_config') - if (modelValue) { - return 'create-new-config' - } - return 'use-existing-config' -} - -function setConfigFiles({ model, getValue, watchDependency, setDiscriminatorValue }) { - watchDependency('model#/resources/secret_user_config/stringData') - const configFiles = getValue(model, '/resources/secret_user_config/stringData') - - const files = [] - - for (const item in configFiles) { - const obj = {} - obj.key = item - obj.value = configFiles[item] - files.push(obj) } - setDiscriminatorValue('/configFiles', files) - - return files -} - -function onConfigFilesChange({ discriminator, getValue, commit }) { - const files = getValue(discriminator, '/configFiles') - - const configFiles = {} - - if (files) { - files.forEach((item) => { - const { key, value } = item - configFiles[key] = value - }) - } - - commit('wizard/model$update', { - path: '/resources/secret_user_config/stringData', - value: configFiles, - force: true, - }) -} - -function onSetCustomConfigChange({ discriminator, getValue, commit }) { - const value = getValue(discriminator, '/setCustomConfig') - - if (value === 'no') { - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/configSecret') - commit('wizard/model$delete', '/resources/secret_user_config') - } -} - -function initSetCustomConfig({ model, getValue }) { - const configSecret = getValue(model, '/resources/kubedbComDruid/spec/configSecret/name') - - if (configSecret) return 'yes' - else return 'no' -} - -//////////////////// secret custom config ///////////////// -function onSecretConfigurationSourceChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSource') - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_secure_config') - } else { - const value = getValue(model, '/resources/secret_secure_config') - if (!value) { + function onAgentChange() { + const agent = getValue(model, '/resources/kubedbComDruid/spec/monitor/agent') + if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: '/resources/secret_secure_config', - value: {}, + path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', + value: [], force: true, }) - } - const configSecretName = `${getValue(model, '/metadata/release/name')}-secure-config` - commit('wizard/model$update', { - path: '/resources/kubedbComDruid/spec/secureConfigSecret/name', - value: configSecretName, - force: true, - }) - } -} - -function setSecretConfigurationSource({ model, getValue }) { - const modelValue = getValue(model, '/resources/secret_secure_config') - if (modelValue) { - return 'create-new-config' - } - return 'use-existing-config' -} - -function setSecretConfigFiles({ model, getValue, watchDependency, setDiscriminatorValue }) { - watchDependency('model#/resources/secret_secure_config/stringData') - const configFiles = getValue(model, '/resources/secret_secure_config/stringData') - - const files = [] - - for (const item in configFiles) { - const obj = {} - obj.key = item - obj.value = configFiles[item] - files.push(obj) - } - - setDiscriminatorValue('/configFiles', files) - - return files -} - -function onSecretConfigFilesChange({ discriminator, getValue, commit }) { - const files = getValue(discriminator, '/configFiles') - const configFiles = {} - - if (files) { - files.forEach((item) => { - const { key, value } = item - configFiles[key] = value - }) - } - - commit('wizard/model$update', { - path: '/resources/secret_secure_config/stringData', - value: configFiles, - force: true, - }) -} - -function onSetSecretCustomConfigChange({ discriminator, getValue, commit }) { - const value = getValue(discriminator, '/setSecretCustomConfig') - - if (value === 'no') { - commit('wizard/model$delete', '/resources/kubedbComDruid/spec/secureConfigSecret') - commit('wizard/model$delete', '/resources/secret_secure_config') - } -} - -function initSetSecureCustomConfig({ model, getValue }) { - const configSecret = getValue(model, '/resources/kubedbComDruid/spec/secureConfigSecret/name') - - if (configSecret) return 'yes' - else return 'no' -} - -function getOpsRequestUrl({ storeGet, model, getValue, mode }, 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 + `/create-opsrequest-${reqType.toLowerCase()}?namespace=${namespace}` - - if (mode === 'standalone-step') return pathConstructedForKubedb - else - return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/druidopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=${reqType}` -} - -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } -} - -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} - -function showScheduleBackup({ storeGet }) { - const operationQuery = storeGet('/route/params/actions') || '' - const isBackupOperation = operationQuery === 'edit-self-backupconfiguration' ? true : false - return !isBackupOperation -} - -function showBackupOptions({ discriminator, getValue, watchDependency }, backup) { - const backupEnabled = getValue(discriminator, '/backupEnabled') - if (backupEnabled) { - if (backup === 'alert') return true - else return false - } else { - if (backup === 'alert') return false - else return true - } -} - -function isBlueprintOption({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/blueprintOptions') - const blueprintOptions = getValue(discriminator, '/blueprintOptions') - return blueprintOptions === value -} - -function ifUsagePolicy({ discriminator, getValue, watchDependency, model }, value) { - watchDependency( - 'model#/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', - ) - const usagePolicy = getValue( - model, - '/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', - ) - return usagePolicy === value -} - -async function getBlueprints({ getValue, model, setDiscriminatorValue, axios, storeGet }, backup) { - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const url = `clusters/${username}/${clusterName}/proxy/core.kubestash.com/v1alpha1/backupblueprints` - - try { - const resp = await axios.get(url) - let data = resp.data.items - return data - } catch (e) { - console.log(e) - } -} - -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} - -async function fetchNamespaces({ axios, storeGet }) { - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const group = storeGet('/route/params/group') - const version = storeGet('/route/params/version') - const resource = storeGet('/route/params/resource') - - const url = `clusters/${username}/${clusterName}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews` - - try { - const resp = await axios.post(url, { - _recurringCall: false, - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], - }, - }) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] - } - } catch (e) { - console.log(e) - } - return [] -} - -async function fetchNames( - { getValue, axios, storeGet, watchDependency, discriminator }, - version, - type, - discriminatorName, -) { - watchDependency(`discriminator#/${discriminatorName}`) - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const namespace = getValue(discriminator, `${discriminatorName}`) - const url = - type !== 'secrets' - ? `clusters/${username}/${clusterName}/proxy/storage.kubestash.com/${version}/namespaces/${namespace}/${type}` - : `clusters/${username}/${clusterName}/proxy/core/${version}/namespaces/${namespace}/${type}` - try { - if (namespace) { - const resp = await axios.get(url) - let data = resp.data.items - data = data.map((ele) => ele.metadata.name) - return data - } - } catch (e) { - console.log(e) - } - return [] -} - -function initBlueprint() { - return 'create' -} -function initUsagePolicy() { - return 'Same' -} - -function onInputChange( - { getValue, discriminator, commit, model }, - modelPath, - field, - subfield, - discriminatorName, -) { - const value = getValue(discriminator, `/${discriminatorName}`) - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') backends[0][field][subfield] = value - else backends[0]['repositories'][0][field][subfield] = value - commit('wizard/model$update', { - path: modelPath, - value: backends, - }) -} -function setFileValueFromStash({ getValue, commit, model }, modelPath, field, subfield, value) { - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') backends[0][field][subfield] = value - else backends[0]['repositories'][0][field][subfield] = value - commit('wizard/model$update', { - path: modelPath, - value: backends, - }) -} - -function onInputChangeSchedule( - { getValue, discriminator, watchDependency, commit, model }, - modelPath, - discriminatorName, -) { - watchDependency(`discriminator#/${discriminatorName}`) - const value = getValue(discriminator, `/${discriminatorName}`) - const session = getValue(model, modelPath) - session[0].scheduler.schedule = value - commit('wizard/model$update', { - path: modelPath, - value: session, - }) -} + onNamespaceChange({ commit, model, getValue }) + onLabelChange({ commit, model, getValue }) + } else { + commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') + } + } -function setInitSchedule( - { getValue, discriminator, watchDependency, commit, model }, - modelPath, - value, -) { - const session = getValue(model, modelPath) - session[0].scheduler.schedule = value - commit('wizard/model$update', { - path: modelPath, - value: session, - }) -} + function setMetadata() { + const namespace = getValue(model, '/metadata/release/namespace') + const labels = getValue(model, '/resources/kubedbComDruid/spec/metadata/labels') + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + value: [namespace], + force: true, + }) + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', + value: labels, + force: true, + }) + } -function getDefault({ getValue, model }, modelPath, field, subfield) { - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') return backends[0][field][subfield] - else { - return backends[0]['repositories'][0][field][subfield] + // ************************* Autoscaling Functions (Storage) ********************************************** + + /** + * Handles unit conversion for storage autoscaling configuration + * Ensures values have proper units (Gi for storage, pc for percentage) + * @param {string} path - The model path to the value + * @param {string} type - Type of value ('bound' or 'scalingRules') + */ + 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 getDefaultSchedule( - { getValue, discriminator, watchDependency, commit, model }, - modelPath, - discriminatorName, -) { - watchDependency(`model#/${modelPath}`) - const session = getValue(model, modelPath) - return session[0].scheduler.schedule -} + // ************************* Autoscaling Functions (Compute) ********************************************** -////////////////// auto scaler ////////////// -let autoscaleType = '' -let dbDetails = {} + let autoscaleType = '' + let dbDetails = {} -function isConsole({ storeGet, commit }) { - const isKube = isKubedb({ storeGet }) + /** + * Fetches database details for autoscaling configuration + * Retrieves the Druid database resource to determine topology and settings + */ + let instance = {} + async function getDbDetails() { + const annotations = getValue( + model, + '/resources/autoscalingKubedbComDruidAutoscaler/metadata/annotations', + ) + instance = annotations?.['kubernetes.io/instance-type'] + 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, '/resources/autoscalingKubedbComDruidAutoscaler/spec/databaseRef/name') || + '' + + if (namespace && name) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/druids/${name}`, + ) + dbDetails = resp.data || {} + setDiscriminatorValue('/dbDetails', true) + } catch (e) { + console.log(e) + } + } - if (isKube) { - const dbName = storeGet('/route/params/name') || '' commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComDruidAutoscaler/spec/databaseRef/name', - value: dbName, + path: `/metadata/release/name`, + value: name, + force: true, + }) + commit('wizard/model$update', { + path: `/metadata/release/namespace`, + value: namespace, 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: '/metadata/name', - value: modifiedName, + path: `/resources/autoscalingKubedbComDruidAutoscaler/spec/databaseRef/name`, + value: name, + force: true, + }) + commit('wizard/model$update', { + path: `/resources/autoscalingKubedbComDruidAutoscaler/metadata/labels`, + value: dbDetails.metadata?.labels, force: true, }) - const namespace = storeGet('/route/query/namespace') || '' - if (namespace) { + } + + /** + * Checks if a specific node type exists in the database topology + * Used for conditional rendering of autoscaling sections + * @param {string} value - The node type to check (e.g., 'coordinators', 'brokers') + * @param {string} section - The section type ('compute' or 'storage') + * @returns {boolean} True if the node type exists in topology for the given section + */ + function dbTypeEqualsTo(value, section) { + // watchDependency('discriminator#/dbDetails') + const dbDetailsLoaded = getValue(discriminator, '/dbDetails') + if (!dbDetailsLoaded) return false + + const topology = dbDetails?.spec?.topology + if (!topology) return false + + // For compute section, check if node type exists in topology + if (section === 'compute') { + return !!topology[value] + } + + // For storage section, check if node type is historicals or middleManagers + if (section === 'storage') { + const storageNodeTypes = ['historicals', 'middleManagers'] + return storageNodeTypes.includes(value) && !!topology[value] + } + + return false + } + + /** + * Gets the current trigger state for autoscaling + * @param {string} path - The model path to the trigger + * @returns {string} 'On' or 'Off' + */ + function setTrigger(path) { + let value = getValue(model, `/resources/${path}`) + if (value) return value + return 'On' + } + + /** + * Toggles the autoscaling trigger between On and Off + * @param {string} path - The model path to the trigger + */ + function onTriggerChange(path) { + const value = getValue(model, `/resources/${path}`) + if (value === 'On') { + commit('wizard/model$update', { + path: `/resources/${path}`, + value: 'Off', + force: true, + }) + } else { commit('wizard/model$update', { - path: '/metadata/namespace', - value: namespace, + path: `/resources/${path}`, + value: 'On', force: true, }) } } - return !isKube -} - -function isKubedb({ storeGet }) { - return !!storeGet('/route/params/actions') -} - -function showOpsRequestOptions({ model, getValue, watchDependency, storeGet, discriminator }) { - if (isKubedb({ storeGet }) === true) return true - watchDependency('model#/resources/autoscalingKubedbComDruidAutoscaler/spec/databaseRef/name') - watchDependency('discriminator#/autoscalingType') - return ( - !!getValue(model, '/resources/autoscalingKubedbComDruidAutoscaler/spec/databaseRef/name') && - !!getValue(discriminator, '/autoscalingType') - ) -} + /** + * Fetches available machine profiles from node topology + * Used for machine-based autoscaling configuration + * @returns {Array} List of available machine profiles with their specifications + */ + async function fetchTopologyMachines() { + const annotations = getValue( + model, + '/resources/autoscalingKubedbComDruidAutoscaler/metadata/annotations', + ) + const 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 [] + setDiscriminatorValue('/topologyMachines', []) + } + } + } -async function getNamespaces({ axios, storeGet }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + /** + * Gets available machine options for autoscaling configuration + * Filters machines based on min/max constraints to ensure valid ranges + * @param {string} nodeType - The type of Druid node (e.g., 'coordinators', 'brokers') + * @param {string} minmax - Either 'min' or 'max' to indicate which constraint to get + * @returns {Array} Filtered list of machine profiles with CPU and memory specifications + */ + function getMachines(type, minmax) { + // watchDependency('discriminator#/topologyMachines') + const depends = minmax === 'min' ? 'max' : 'min' + const dependantPath = `/allowedMachine-${type}-${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 resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + const filteredMachine = machines?.filter((item, ind) => + minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, + ) - const resources = (resp && resp.data && resp.data.items) || [] + return dependantIndex === -1 ? machines : filteredMachine + } - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, + function setAllowedMachine(type, minmax) { + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = {} } - }) -} - -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - watchDependency('model#/metadata/namespace') - const namespace = getValue(model, '/metadata/namespace') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/druids`, - { - 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) || '' + const machine = parsedInstance[type] || '' + const mx = machine?.includes(',') ? machine.split(',')[1] : '' + const mn = machine?.includes(',') ? machine.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 { - text: name, - value: name, + machine: machineName || '', + cpu: '', + memory: '', } - }) -} + } -async function getDbDetails({ setDiscriminatorValue, commit, axios, storeGet, getValue, model }) { - 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, '/resources/autoscalingKubedbComDruidAutoscaler/spec/databaseRef/name') || - '' - - if (namespace && name) { + function onMachineChange(nodeType) { + const annoPath = '/resources/autoscalingKubedbComDruidAutoscaler/metadata/annotations' + const annotations = getValue(model, annoPath) || {} + const instance = annotations['kubernetes.io/instance-type'] + let parsedInstance = {} try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/druids/${name}`, - ) - dbDetails = resp.data || {} - setDiscriminatorValue('/dbDetails', true) + if (instance) parsedInstance = JSON.parse(instance) } catch (e) { console.log(e) + parsedInstance = {} } - } - commit('wizard/model$update', { - path: `/metadata/release/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/metadata/release/namespace`, - value: namespace, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComRedisAutoscaler/spec/databaseRef/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComRedisAutoscaler/metadata/labels`, - value: dbDetails.metadata.labels, - force: true, - }) -} - -async function dbTypeEqualsTo({ axios, storeGet, watchDependency, model, getValue, commit }, type) { - watchDependency('discriminator#/dbDetails') - - const { spec } = dbDetails || {} - const { topology } = spec || {} - let verd = '' - if (topology) verd = 'topology' - else verd = 'standalone' - clearSpecModel({ commit }, verd) - return type === verd && spec -} - -function clearSpecModel({ commit }, dbtype) { - if (dbtype === 'node') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComDruidAutoscaler/spec/${autoscaleType}/data`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComDruidAutoscaler/spec/${autoscaleType}/ingest`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComDruidAutoscaler/spec/${autoscaleType}/master`, - ) - } else if (dbtype === 'topology') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComDruidAutoscaler/spec/${autoscaleType}/node`, - ) + // Now discriminator values are objects with { machine, cpu, memory } + const minMachineObj = getValue(discriminator, `/allowedMachine-${nodeType}-min`) + const maxMachineObj = getValue(discriminator, `/allowedMachine-${nodeType}-max`) + const minMachine = minMachineObj?.machine || '' + const maxMachine = maxMachineObj?.machine || '' + const minMaxMachine = `${minMachine},${maxMachine}` + + parsedInstance[nodeType] = minMaxMachine + const instanceString = JSON.stringify(parsedInstance) + annotations['kubernetes.io/instance-type'] = instanceString + + // 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/autoscalingKubedbComDruidAutoscaler/spec/compute/${nodeType}` + + if (minMachine && maxMachine && instance !== instanceString) { + 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 initMetadata({ getValue, discriminator, model, commit, storeGet }) { - const dbName = - getValue(model, '/resources/autoscalingKubedbComDruidAutoscaler/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) + function setControlledResources(type) { + const list = ['cpu', 'memory'] + const path = `/resources/autoscalingKubedbComDruidAutoscaler/spec/${type}/controlledResources` commit('wizard/model$update', { - path: '/metadata/name', - value: modifiedName, + path: path, + value: list, force: true, }) + return list + } - // delete the other type object from model - if (type === 'compute') - commit('wizard/model$delete', '/resources/autoscalingKubedbComDruidAutoscaler/spec/storage') - if (type === 'storage') - commit('wizard/model$delete', '/resources/autoscalingKubedbComDruidAutoscaler/spec/compute') -} + function hasAnnotations() { + const annotations = + getValue(model, '/resources/autoscalingKubedbComDruidAutoscaler/metadata/annotations') || {} + const instance = annotations['kubernetes.io/instance-type'] -function onNamespaceChange({ model, getValue, commit }) { - const namespace = getValue(model, '/metadata/namespace') - if (!namespace) { - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComDruidAutoscaler/spec/databaseRef/name', - ) + return !!instance } -} -function ifScalingTypeEqualsTo( - { storeGet, watchDependency, getValue, discriminator, model }, - type, -) { - watchDependency('discriminator#/autoscalingType') - watchDependency('model#/resources/autoscalingKubedbComDruidAutoscaler/spec/databaseRef/name') - - const operation = storeGet('/route/params/actions') || '' - if (operation.length) { - const splitOp = operation.split('-') - if (splitOp.length > 2) autoscaleType = splitOp[2] - } else autoscaleType = getValue(discriminator, '/autoscalingType') || '' - const isDatabaseSelected = !!getValue( - model, - '/resources/autoscalingKubedbComDruidAutoscaler/spec/databaseRef/name', - ) - return autoscaleType === type && isDatabaseSelected -} + function hasNoAnnotations() { + return !hasAnnotations() + } -async function fetchNodeTopology({ axios, storeGet }) { - 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) + 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 [] } - return [] -} -function isNodeTopologySelected({ watchDependency, model, getValue }) { - watchDependency( - 'model#/resources/autoscalingKubedbComDruidAutoscaler/spec/compute/nodeTopology/name', - ) - const nodeTopologyName = - getValue( - model, - '/resources/autoscalingKubedbComDruidAutoscaler/spec/compute/nodeTopology/name', - ) || '' - return !!nodeTopologyName.length -} + function isNodeTopologySelected() { + // watchDependency( + // 'model#/resources/autoscalingKubedbComDruidAutoscaler/spec/compute/nodeTopology/name', + // ) + const nodeTopologyName = + getValue( + model, + '/resources/autoscalingKubedbComDruidAutoscaler/spec/compute/nodeTopology/name', + ) || '' + return !!nodeTopologyName.length + } -function setControlledResources({ commit }, type) { - const list = ['cpu', 'memory'] - const path = `/resources/autoscalingKubedbComDruidAutoscaler/spec/compute/${type}/controlledResources` - commit('wizard/model$update', { - path: path, - value: list, - force: true, - }) - return list -} + function showOpsRequestOptions() { + if (isKubedb() === true) return true + // watchDependency('model#/resources/autoscalingKubedbComDruidAutoscaler/spec/databaseRef/name') + // watchDependency('discriminator#/autoscalingType') + return ( + !!getValue(model, '/resources/autoscalingKubedbComDruidAutoscaler/spec/databaseRef/name') && + !!getValue(discriminator, '/autoscalingType') + ) + } -function setTrigger({ model, getValue }, path) { - let value = getValue(model, `/resources/${path}`) - if (value) return value - return 'On' -} + function setApplyToIfReady() { + return 'IfReady' + } -function setApplyToIfReady() { - return 'IfReady' -} + function setValueFromDbDetails(path) { + const value = getValue(model, path) + return value + } -function handleUnit({ commit, model, getValue }, 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, - }) + // ************************* ConfigMap/Secret Functions ********************************************** + + /** + * Determines the source type for environment variable values + * @returns {string} 'configMap', 'secret', or 'input' + */ + function setValueFrom() { + if (isConfigMapTypeValueFrom()) { + return 'configMap' + } else if (isSecretTypeValueFrom()) { + return 'secret' + } else { + return 'input' } } -} -function isBindingAlreadyOn({ model, getValue }) { - const value = getValue(model, '/resources') - const keys = Object.keys(value) - isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComDruidBinding') - return isExposeBinding -} + /** + * Fetches keys from a specified ConfigMap + * Used to populate dropdown options for ConfigMap key selection + * @returns {Array} List of ConfigMap keys with text/value pairs + */ + async function getConfigMapKeys(index) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + const configMapName = getValue( + model, + `/resources/kubedbComDruid/spec/monitor/prometheus/exporter/env/${index}/valueFrom/configMapKeyRef/name`, + ) -async function addOrRemoveBinding({ commit, model, getValue, discriminator }) { - const value = getValue(discriminator, `/binding`) - const dbName = getValue(model, '/metadata/release/name') - const dbNamespace = getValue(model, '/metadata/release/namespace') - const labels = getValue(model, '/resources/kubedbComDruid/metadata/labels') - const bindingValues = { - apiVersion: 'catalog.appscode.com/v1alpha1', - kind: 'DruidBinding', - metadata: { - labels, - name: dbName, - namespace: dbNamespace, - }, - spec: { - sourceRef: { - name: dbName, - namespace: dbNamespace, - }, - }, - } + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/configMapKeyRef/name') - if (value) { - await commit('wizard/model$update', { - path: '/resources/catalogAppscodeComDruidBinding', - value: bindingValues, - force: true, - }) - } else { - await commit('wizard/model$delete', '/resources/catalogAppscodeComDruidBinding') - } -} + if (!configMapName) return [] -function setMetadata({ storeGet, mode, commit }) { - const dbname = storeGet('/route/params/name') || '' - const namespace = storeGet('/route/query/namespace') || '' - if (mode === 'standalone-step') { - commit('wizard/model$update', { - path: '/metadata/release/name', - value: dbname, - force: true, - }) - commit('wizard/model$update', { - path: '/metadata/release/namespace', - value: namespace, - force: true, - }) + 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 fetchTopologyMachines({ axios, getValue, storeGet, model, setDiscriminatorValue }) { - const instance = hasAnnotations({ model, getValue }) + 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') - 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 resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }, + ) - const nodeGroups = resp.data?.spec?.nodeGroups || [] - setDiscriminatorValue('/topologyMachines', nodeGroups) - return nodeGroups + 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 [] } } -} -function setAllowedMachine({ model, getValue }, type, minmax) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComDruidAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - let parsedInstance = {} - try { - if (instance) parsedInstance = JSON.parse(instance) - } catch (e) { - console.log(e) - parsedInstance = {} - } + async function getSecretKeys(index) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + const secretName = getValue( + model, + `/resources/kubedbComDruid/spec/monitor/prometheus/exporter/env/${index}/valueFrom/secretKeyRef/name`, + ) - const machine = parsedInstance[type] || '' - const mx = machine?.includes(',') ? machine.split(',')[1] : '' - const mn = machine?.includes(',') ? machine.split(',')[0] : '' + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/secretKeyRef/name') - if (minmax === 'min') return mn - else return mx -} + if (!secretName) return [] -async function getMachines({ getValue, watchDependency, discriminator }, type, minmax) { - watchDependency('discriminator#/topologyMachines') - const depends = minmax === 'min' ? 'max' : 'min' - const dependantPath = `/allowedMachine-${type}-${depends}` + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets/${secretName}`, + ) - watchDependency(`discriminator#${dependantPath}`) - const dependantMachine = getValue(discriminator, dependantPath) + const secret = (resp && resp.data && resp.data.data) || {} - const nodeGroups = getValue(discriminator, '/topologyMachines') || [] + const secretKeys = Object.keys(secret).map((item) => ({ + text: item, + value: item, + })) - const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) + return secretKeys + } catch (e) { + console.log(e) + return [] + } + } - const machines = nodeGroups?.map((item) => { - const subText = `CPU: ${item.allocatable.cpu}, Memory: ${item.allocatable.memory}` - const text = item.topologyValue - return { text, subText, value: item.topologyValue } - }) + // ************************* Gateway Binding Functions ********************************************** - const filteredMachine = machines?.filter((item, ind) => - minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, - ) + /** + * Checks if gateway binding is currently enabled + * @returns {boolean} True if binding is enabled + */ + function isBindingAlreadyOn() { + const binding = getValue(discriminator, '/binding') + return !!binding + } - return dependantIndex === -1 ? machines : filteredMachine -} + /** + * Adds or removes gateway binding configuration + * Creates or deletes the DruidBinding resource based on toggle state + */ + function addOrRemoveBinding() { + const binding = getValue(discriminator, '/binding') + if (binding) { + commit('wizard/model$update', { + path: '/resources/gatewayVoyagerAppscodeComDruidBinding', + value: {}, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/gatewayVoyagerAppscodeComDruidBinding') + } + } -function hasAnnotations({ model, getValue }, type) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComDruidAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] + // ************************* Ops Request Functions ********************************************** + + /** + * Generates the URL for creating a Druid ops request + * Constructs different URLs based on whether running in KubeDB console or standalone + * @param {string} reqType - The type of ops request (e.g., 'Upgrade', 'HorizontalScaling') + * @returns {string} The constructed URL for the ops request creation page + */ + 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/druidopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=${reqType}` + } + + 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 + }) - return !!instance -} + if (filteredEnv.length) + commit('wizard/model$update', { + path: '/resources/kubedbComDruid/spec/monitor/prometheus/exporter/env', + value: filteredEnv, + force: true, + }) + } -function hasNoAnnotations({ model, getValue }) { - return !hasAnnotations({ model, getValue }) -} + function initEnvArray() { + const env = getValue(model, '/resources/kubedbComDruid/spec/monitor/prometheus/exporter/env') -function onMachineChange({ model, getValue, discriminator, commit }, type) { - const annoPath = '/resources/autoscalingKubedbComDruidAutoscaler/metadata/annotations' - const annotations = getValue(model, annoPath) - const instance = annotations['kubernetes.io/instance-type'] - let parsedInstance = {} - try { - if (instance) parsedInstance = JSON.parse(instance) - } catch (e) { - console.log(e) - parsedInstance = {} - } - - const minMachine = getValue(discriminator, `/allowedMachine-${type}-min`) - const maxMachine = getValue(discriminator, `/allowedMachine-${type}-max`) - const minMaxMachine = `${minMachine},${maxMachine}` - - parsedInstance[type] = minMaxMachine - const instanceString = JSON.stringify(parsedInstance) - annotations['kubernetes.io/instance-type'] = instanceString - - const machines = getValue(discriminator, `/topologyMachines`) || [] - const minMachineObj = machines.find((item) => item.topologyValue === minMachine) - const maxMachineObj = machines.find((item) => item.topologyValue === maxMachine) - const minMachineAllocatable = minMachineObj?.allocatable - const maxMachineAllocatable = maxMachineObj?.allocatable - const allowedPath = `/resources/autoscalingKubedbComDruidAutoscaler/spec/compute/${type}` - - if (minMachine && maxMachine && instance !== instanceString) { - 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, + 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/kubedbComDruid/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 { - setMetadata, - handleUnit, - isConsole, - getNamespaces, - getDbs, - isKubedb, - getDbDetails, - dbTypeEqualsTo, - clearSpecModel, - initMetadata, - onNamespaceChange, - ifScalingTypeEqualsTo, - fetchNodeTopology, - isNodeTopologySelected, - setControlledResources, - setTrigger, - setApplyToIfReady, - showOpsRequestOptions, - setInitSchedule, - fetchNames, - fetchNamespaces, - isRancherManaged, - onInputChangeSchedule, - getDefaultSchedule, - getBlueprints, - ifUsagePolicy, - initUsagePolicy, - isBlueprintOption, - initBlueprint, - getDefault, - onInputChange, - showBackupOptions, - showScheduleBackup, - fetchJsons, - disableLableChecker, - isEqualToModelPathValue, - getResources, - isEqualToDiscriminatorPath, - setValueFromModel, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - returnTrue, - returnStringYes, - isDedicatedModeSelected, - isCombinedModeSelected, - isDiscriminatorEqualTo, - isAuthPluginNotSearchGuard, - showInternalUsersAndRolesMapping, - showSecureCustomConfig, - getDruidVersions, - isSecurityEnabled, - onDisableSecurityChange, - onVersionChange, - onEnableSSLChange, - removeCertificatesOfAliases, - setDatabaseMode, - getStorageClassNames, - getStorageClassNamesFromDiscriminator, - deleteDatabaseModePath, - isEqualToDatabaseMode, - getSelectedVersionAuthPlugin, - onNodeSwitchFalse, - hasTopologyNode, - hideNode, - disableNode, - setInitialStatusFalse, - onInternalUsersChange, - disableRoleDeletion, - setInternalUsers, - validateNewUser, - disableUsername, - disableUserEdit, - isAuthPluginEqualTo, - showExistingCredSection, - showPasswordCredSection, - onRolesMappingChange, - setRolesMapping, - disableRolesEdit, - disableRoleName, - validateNewRole, - disableUserDeletion, - onCustomizeKernelSettingChange, - getInternalUsers, - setApiGroup, - setApiGroupEdit, - getIssuerRefsName, - hasIssuerRefName, - hasNoIssuerRefName, - setClusterAuthMode, - setSSLMode, - showTlsConfigureSection, - onTlsConfigureChange, - showTlsRecommendation, - getAliasOptions, - showMonitoringSection, - onEnableMonitoringChange, - showCustomizeExporterSection, - onCustomizeExporterChange, - disableInitializationSection, - valueExists, - initPrePopulateDatabase, - onPrePopulateDatabaseChange, - initDataSource, - onDataSourceChange, - initVolumeType, - onVolumeTypeChange, - showInitializationForm, - showScriptOrStashForm, - showConfigMapOrSecretName, - initializeNamespace, - showRepositorySelectOrCreate, - onInitRepositoryChoiseChange, - initCustomizeRestoreJobRuntimeSettings, - initCustomizeRestoreJobRuntimeSettingsForBackup, - onCustomizeRestoreJobRuntimeSettingsChange, - onCustomizeRestoreJobRuntimeSettingsChangeForBackup, - showRuntimeForm, - getImagePullSecrets, - getBackupConfigsAndAnnotations, - deleteKubedbComDruidDbAnnotation, - addKubedbComDruidDbAnnotation, - initScheduleBackup, - initScheduleBackupForEdit, - onScheduleBackupChange, - showBackupForm, - initBackupInvoker, - onBackupInvokerChange, - showInvokerForm, - initalizeTargetReferenceName, - setInitialRestoreSessionRepo, - initRepositoryChoise, - initRepositoryChoiseForEdit, - onRepositoryChoiseChange, - onRepositoryNameChange, - getMongoAnnotations, - initFromAnnotationValue, - onBackupBlueprintNameChange, - onBackupBlueprintScheduleChange, - initFromAnnotationKeyValue, - onTaskParametersChange, - isValueExistInModel, - onNamespaceChange, - onLabelChange, - onNameChange, - returnFalse, - onAgentChange, - getCreateAuthSecret, - showExistingSecretSection, - showPasswordSection, - encodePassword, - decodePassword, - onCreateAuthSecretChange, - setAuthSecretPassword, - onAuthSecretPasswordChange, - showSecretSection, - getSecrets, - isEqualToServiceMonitorType, - onConfigurationSourceChange, - setConfigurationSource, - getMaxUnavailableOptions, - setConfigFiles, - onConfigFilesChange, - onSetCustomConfigChange, - onSecretConfigurationSourceChange, - setSecretConfigurationSource, - setSecretConfigFiles, - onSecretConfigFilesChange, - onSetSecretCustomConfigChange, - initSetCustomConfig, - initSetSecureCustomConfig, - getOpsRequestUrl, - getCreateNameSpaceUrl, - isVariantAvailable, - setStorageClass, - isBindingAlreadyOn, - addOrRemoveBinding, - getMachines, - setAllowedMachine, - hasAnnotations, - hasNoAnnotations, - fetchTopologyMachines, - onMachineChange, + return { + // Common Helper Functions + fetchJsons, + disableLableChecker, + isEqualToModelPathValue, + getResources, + isEqualToDiscriminatorPath, + setValueFromModel, + getNamespacedResourceList, + getResourceList, + resourceNames, + unNamespacedResourceNames, + returnTrue, + returnFalse, + returnStringYes, + + // Helper Functions + objectCopy, + valueExists, + encodePassword, + decodePassword, + clearSpecModel, + getCreateNameSpaceUrl, + isRancherManaged, + isKubedb, + getNamespaces, + + // Backup & Restore Functions + getBackupConfigsAndAnnotations, + deleteKubeDbComDruidAnnotation, + addKubeDbComDruidAnnotation, + initScheduleBackup, + initScheduleBackupForEdit, + onScheduleBackupChange, + showBackupForm, + showScheduleBackup, + initalizeTargetReferenceName, + setInitialRestoreSessionRepo, + initRepositoryChoise, + initRepositoryChoiseForEdit, + onRepositoryChoiseChange, + onRepositoryNameChange, + + // KubeStash Backup Functions + initBackupData, + isBackupDataLoadedTrue, + setBackupType, + getTypes, + onBackupTypeChange, + isBackupType, + setBlueprintSwitch, + onBlueprintChange, + setArchiverSwitch, + onArchiverChange, + addLabelAnnotation, + deleteLabelAnnotation, + getContext, + onContextChange, + getConfigList, + onConfigChange, + showPause, + showConfigList, + showSchedule, + getNamespaceArray, + onInputChange, + setFileValueFromStash, + onInputChangeSchedule, + setInitSchedule, + getDefault, + getDefaultSchedule, + fetchNamespaces, + fetchNames, + getBlueprints, + isBlueprintOption, + ifUsagePolicy, + showBackupOptions, + + // Monitoring Functions + showMonitoringSection, + onEnableMonitoringChange, + showCustomizeExporterSection, + onCustomizeExporterChange, + isValueExistInModel, + onNamespaceChange, + onLabelChange, + onAgentChange, + setMetadata, + + // Autoscaling Functions - Storage + handleUnit, + + // Autoscaling Functions - Compute + getDbDetails, + dbTypeEqualsTo, + setTrigger, + onTriggerChange, + fetchTopologyMachines, + getMachines, + setAllowedMachine, + onMachineChange, + setControlledResources, + hasAnnotations, + hasNoAnnotations, + fetchNodeTopology, + isNodeTopologySelected, + showOpsRequestOptions, + setApplyToIfReady, + setValueFromDbDetails, + + // ConfigMap/Secret Functions + setValueFrom, + isConfigMapTypeValueFrom, + isSecretTypeValueFrom, + isInputTypeValueFrom, + onValueFromChange, + getConfigMapKeys, + getSecrets, + getSecretKeys, + onEnvArrayChange, + initEnvArray, + isEqualToTemp, + initMonitoring, + + // Gateway Binding Functions + isBindingAlreadyOn, + addOrRemoveBinding, + + // Ops Request Functions + getOpsRequestUrl, + } } diff --git a/charts/kubedbcom-elasticsearch-editor-options/ui/create-ui.yaml b/charts/kubedbcom-elasticsearch-editor-options/ui/create-ui.yaml index 9fc3d274cf..683ac16b33 100644 --- a/charts/kubedbcom-elasticsearch-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-elasticsearch-editor-options/ui/create-ui.yaml @@ -1,485 +1,506 @@ -steps: -- form: - discriminator: - bundleApiLoaded: - default: false - type: boolean - elements: - - computed: initBundle - if: returnFalse - type: label-element - - disableUnselect: true - fetch: getAdminOptions|databases/Elasticsearch/versions - if: isToggleOn|databases/Elasticsearch/versions - label: - text: labels.database.version - schema: - $ref: schema#/properties/spec/properties/admin/properties/databases/properties/Elasticsearch/properties/versions/properties/default - type: select - - computed: getDefault|databases/Elasticsearch/mode - fetch: getAdminOptions|databases/Elasticsearch/mode - hasDescription: true - if: isToggleOn|databases/Elasticsearch/mode - label: - text: labels.database.mode - schema: - $ref: schema#/properties/spec/properties/mode - type: radio - - elements: - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/replicas - type: input - if: isEqualToModelPathValue|Combined|/spec/mode - type: single-step-form +step: +- type: single-step-form + loader: initBundle + elements: + - type: label-element + label: '' + subtitle: Select the Elasticsearch version you want to deploy on Kubernetes. The chosen version determines the Elasticsearch engine features, compatibility, and runtime behavior of your analytics database. + - disableUnselect: true + loader: getAdminOptions|databases/Elasticsearch/versions + if: + type: function + name: isToggleOn|databases/Elasticsearch/versions + label: Database version + schema: schema/properties/spec/properties/admin/properties/databases/properties/Elasticsearch/properties/versions/properties/default + type: select + - init: + type: func + value: getDefault|databases/Elasticsearch/mode + loader: getAdminOptions|databases/Elasticsearch/mode + if: + type: function + name: isToggleOn|databases/Elasticsearch/mode + label: Database mode + isHorizontal: true + schema: schema/properties/spec/properties/mode + type: radio + - elements: + - label: Replicaset number + schema: schema/properties/spec/properties/replicas + type: input + customClass: mb-20 + if: + type: function + name: isEqualToModelPathValue|Combined|/spec/mode + type: block-layout + - elements: - elements: - - elements: - - label: - text: labels.master_nodes - type: label-element - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/topology/properties/master/properties/replicas - type: input - - elements: - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/topology/properties/master/properties/persistence/properties/size + - type: label-element + label: '' + subtitle: Master nodes manage cluster state and coordinate operations. Configure replicas, storage, and resource allocation for reliable cluster management. + - type: horizontal-layout + showLabels: true + elements: + - label: Replicaset number + schema: schema/properties/spec/properties/topology/properties/master/properties/replicas + type: input + - label: Storage size + schema: schema/properties/spec/properties/topology/properties/master/properties/persistence/properties/size type: input - schema: - $ref: schema#/properties/spec/properties/topology/properties/master/properties/persistence - type: single-step-form - - elements: - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/topology/properties/master/properties/podResources/properties/machine + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/topology/properties/master/properties/podResources/properties/machine type: select - - computed: setLimits|cpu|topology/master - disabled: isMachineNotCustom|topology/master - if: isMachineCustom|topology/master - label: - text: labels.cpu - onChange: setRequests|cpu|topology/master - schema: - $ref: schema#/properties/spec/properties/topology/properties/master/properties/podResources/properties/resources/properties/requests/properties/cpu + - init: + type: func + value: setLimits|cpu|topology/master + disable: isMachineNotCustom|topology/master + if: + type: function + name: isMachineCustom|topology/master + label: cpu + loader: setLimits|cpu|topology/master + watcher: + func: setRequests|cpu|topology/master + paths: + - schema/properties/spec/properties/topology/properties/master/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/topology/properties/master/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/master/properties/podResources/properties/resources/properties/requests/properties/cpu type: input - - computed: setLimits|memory|topology/master - disabled: isMachineNotCustom|topology/master - if: isMachineCustom|topology/master - label: - text: labels.memory - onChange: setRequests|memory|topology/master - schema: - $ref: schema#/properties/spec/properties/topology/properties/master/properties/podResources/properties/resources/properties/requests/properties/memory + - init: + type: func + value: setLimits|memory|topology/master + disable: isMachineNotCustom|topology/master + if: + type: function + name: isMachineCustom|topology/master + label: memory + loader: setLimits|memory|topology/master + watcher: + func: setRequests|memory|topology/master + paths: + - schema/properties/spec/properties/topology/properties/master/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/topology/properties/master/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/master/properties/podResources/properties/resources/properties/requests/properties/memory type: input - label: - text: labels.machine_profile - show_label: true - type: single-step-form - schema: - $ref: schema#/properties/spec/properties/topology/properties/master - type: single-step-form - - elements: - - label: - text: labels.data_nodes - type: label-element - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/topology/properties/data/properties/replicas - type: input - - elements: - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/topology/properties/data/properties/persistence/properties/size + label: Master nodes + showLabels: true + type: block-layout + - elements: + - type: label-element + label: '' + subtitle: Data nodes store and index documents. Configure replicas, storage capacity, and resource allocation to handle your data ingestion and query workload. + - type: horizontal-layout + showLabels: true + elements: + - label: Replicaset number + schema: schema/properties/spec/properties/topology/properties/data/properties/replicas + type: input + - label: Storage size + schema: schema/properties/spec/properties/topology/properties/data/properties/persistence/properties/size type: input - schema: - $ref: schema#/properties/spec/properties/topology/properties/data/properties/persistence - type: single-step-form - - elements: - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/topology/properties/data/properties/podResources/properties/machine + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/topology/properties/data/properties/podResources/properties/machine type: select - - computed: setLimits|cpu|topology/data - disabled: isMachineNotCustom|topology/data - if: isMachineCustom|topology/data - label: - text: labels.cpu - onChange: setRequests|cpu|topology/data - schema: - $ref: schema#/properties/spec/properties/topology/properties/data/properties/podResources/properties/resources/properties/requests/properties/cpu + - init: + type: func + value: setLimits|cpu|topology/data + disable: isMachineNotCustom|topology/data + if: + type: function + name: isMachineCustom|topology/data + label: cpu + loader: setLimits|cpu|topology/data + watcher: + func: setRequests|cpu|topology/data + paths: + - schema/properties/spec/properties/topology/properties/data/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/topology/properties/data/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/data/properties/podResources/properties/resources/properties/requests/properties/cpu type: input - - computed: setLimits|memory|topology/data - disabled: isMachineNotCustom|topology/data - if: isMachineCustom|topology/data - label: - text: labels.memory - onChange: setRequests|memory|topology/data - schema: - $ref: schema#/properties/spec/properties/topology/properties/data/properties/podResources/properties/resources/properties/requests/properties/memory + - init: + type: func + value: setLimits|memory|topology/data + disable: isMachineNotCustom|topology/data + if: + type: function + name: isMachineCustom|topology/data + label: memory + loader: setLimits|memory|topology/data + watcher: + func: setRequests|memory|topology/data + paths: + - schema/properties/spec/properties/topology/properties/data/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/topology/properties/data/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/data/properties/podResources/properties/resources/properties/requests/properties/memory type: input - label: - text: labels.machine_profile - show_label: true - type: single-step-form - schema: - $ref: schema#/properties/spec/properties/topology/properties/data - type: single-step-form - - elements: - - label: - text: labels.ingest_nodes - type: label-element - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/topology/properties/ingest/properties/replicas - type: input - - elements: - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/topology/properties/ingest/properties/persistence/properties/size + label: Data nodes + showLabels: true + type: block-layout + - elements: + - type: label-element + label: '' + subtitle: Ingest nodes preprocess documents before indexing using pipelines. Configure replicas, storage, and resources for data transformation and enrichment workloads. + - type: horizontal-layout + showLabels: true + elements: + - label: Replicaset number + schema: schema/properties/spec/properties/topology/properties/ingest/properties/replicas type: input - schema: - $ref: schema#/properties/spec/properties/topology/properties/ingest/properties/persistence - type: single-step-form - - elements: - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/topology/properties/ingest/properties/podResources/properties/machine + - label: Storage size + schema: schema/properties/spec/properties/topology/properties/ingest/properties/persistence/properties/size + type: input + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/topology/properties/ingest/properties/podResources/properties/machine type: select - - computed: setLimits|cpu|topology/ingest - disabled: isMachineNotCustom|topology/ingest - if: isMachineCustom|topology/ingest - label: - text: labels.cpu - onChange: setRequests|cpu|topology/ingest - schema: - $ref: schema#/properties/spec/properties/topology/properties/ingest/properties/podResources/properties/resources/properties/requests/properties/cpu + - init: + type: func + value: setLimits|cpu|topology/ingest + disable: isMachineNotCustom|topology/ingest + if: + type: function + name: isMachineCustom|topology/ingest + label: cpu + loader: setLimits|cpu|topology/ingest + watcher: + func: setRequests|cpu|topology/ingest + paths: + - schema/properties/spec/properties/topology/properties/ingest/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/topology/properties/ingest/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/ingest/properties/podResources/properties/resources/properties/requests/properties/cpu type: input - - computed: setLimits|memory|topology/ingest - disabled: isMachineNotCustom|topology/ingest - if: isMachineCustom|topology/ingest - label: - text: labels.memory - onChange: setRequests|memory|topology/ingest - schema: - $ref: schema#/properties/spec/properties/topology/properties/ingest/properties/podResources/properties/resources/properties/requests/properties/memory + - init: + type: func + value: setLimits|memory|topology/ingest + disable: isMachineNotCustom|topology/ingest + if: + type: function + name: isMachineCustom|topology/ingest + label: memory + loader: setLimits|memory|topology/ingest + watcher: + func: setRequests|memory|topology/ingest + paths: + - schema/properties/spec/properties/topology/properties/ingest/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/topology/properties/ingest/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/ingest/properties/podResources/properties/resources/properties/requests/properties/memory type: input - label: - text: labels.machine_profile - show_label: true - type: single-step-form - schema: - $ref: schema#/properties/spec/properties/topology/properties/ingest - type: single-step-form - if: isEqualToModelPathValue|Topology|/spec/mode - schema: - $ref: schema#/properties/spec/properties/topology - type: single-step-form + label: Ingest nodes + showLabels: true + type: block-layout + if: + type: function + name: isEqualToModelPathValue|Topology|/spec/mode + type: block-layout + - elements: + - type: label-element + label: '' + subtitle: Select a machine profile to allocate CPU and memory resources for your database. Choose 'custom' to manually specify resource requirements or select a predefined profile. + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: cpu + loader: setLimits|cpu + watcher: + func: setRequests|cpu + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory + disable: isMachineNotCustom|schema/properties/spec/properties/podResources/properties/machine + label: memory + loader: setLimits|memory + watcher: + func: setRequests|memory + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + if: + type: function + name: isEqualToModelPathValue|Combined|/spec/mode + label: Machine_profile + showLabels: true + type: block-layout + - elements: + - type: horizontal-layout + showLabels: true + elements: + - loader: getAdminOptions|storageClasses + label: Storage class + schema: schema/properties/spec/properties/admin/properties/storageClasses/properties/default + type: select + - if: + type: function + name: isEqualToModelPathValue|Combined|/spec/mode + label: Storage size + schema: schema/properties/spec/properties/persistence/properties/size + type: input + if: + type: function + name: isEqualToModelPathValue|Combined|/spec/mode + type: block-layout + - description: Configure Credentials, Deployment Mode etc. + elements: - elements: - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.cpu - onChange: setRequests|cpu - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.cpu - onChange: setRequests|memory - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - if: isEqualToModelPathValue|Combined|/spec/mode - label: - text: labels.machine_profile - show_label: true - type: single-step-form - - fetch: getAdminOptions|storageClasses - label: - text: labels.storage.class - schema: - $ref: schema#/properties/spec/properties/admin/properties/storageClasses/properties/default + - type: label-element + label: '' + subtitle: Add custom labels and annotations to your database resources for organization, monitoring, and integration with other Kubernetes tools and services. + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/annotations + label: Labels & Annotations + showLabels: true + hideBlock: true + type: block-layout + - init: + type: func + value: getDefault|deletionPolicy + customClass: mt-20 + if: + type: function + name: isToggleOn|deletionPolicy + label: Deletion Policy + watcher: + func: setStorageClass + paths: + - schema/properties/spec/properties/deletionPolicy + options: + - description: options.deletionPolicy.delete.description + text: Delete + value: Delete + - description: options.deletionPolicy.halt.description + text: Halt + value: Halt + - description: options.deletionPolicy.wipeOut.description + text: WipeOut + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: DoNotTerminate + value: DoNotTerminate + schema: schema/properties/spec/properties/deletionPolicy type: select - - if: isEqualToModelPathValue|Combined|/spec/mode - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/persistence/properties/size + - if: + type: function + name: getDefaultValue|spec/admin/authCredential/customize + label: Provide Authentication Credentials? + watcher: + func: onAuthChange + paths: + - temp/createAuthSecret + schema: temp/createAuthSecret + type: switch + - if: + type: function + name: showReferSecretSwitch + label: Refer existing Secret? + watcher: + func: onReferSecretChange + paths: + - temp/referSecret + schema: temp/referSecret + type: switch + - loader: getReferSecrets + if: + type: function + name: showSecretDropdown + label: Secret + schema: schema/properties/spec/properties/authSecret/properties/name + type: select + - if: + type: function + name: showReferSecret + label: password + schema: schema/properties/spec/properties/authSecret/properties/password type: input - - accordion: true - description: - text: Configure Credentials, Deployment Mode etc. - discriminator: - configDatabase: - default: false - type: boolean - createAuthSecret: - default: false - type: boolean - referSecret: - default: false - type: boolean - elements: - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties - type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties - type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - computed: getDefault|deletionPolicy - customClass: mt-20 - if: isToggleOn|deletionPolicy - label: - text: labels.deletionPolicy - onChange: setStorageClass + - if: + type: function + name: getDefaultValue|spec/admin/customConfiguration + label: Configure Database? + watcher: + func: clearConfiguration + paths: + - temp/configDatabase + schema: temp/configDatabase + type: switch + - if: + type: function + name: isConfigDatabaseOn + label: Configuration + # hasCopy: true + schema: schema/properties/spec/properties/configuration + type: textarea + - if: + type: function + name: isToggleOn|deployment + label: Deployment name + options: + - description: labels.deployment.shared + text: Shared + value: Shared + - description: labels.deployment.dedicated + text: Dedicated + value: Dedicated + schema: schema/properties/spec/properties/admin/properties/deployment/properties/default + type: radio + - if: + type: function + name: isToggleOn|clusterTier + isHorizontal: true + label: Cluster Tier + options: + - text: General Purpose + value: GeneralPurpose + - text: Memory Optimized + value: MemoryOptimized + - text: CPU Optimized + value: CPUOptimized + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/default + type: radio + - disableUnselect: true + loader: getAdminOptions|clusterTier/placement + if: + type: function + name: isToggleOn|clusterTier/placement + label: Placement + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + type: select + - disableUnselect: true + loader: getNodeTopology + if: + type: function + name: isToggleOn|clusterTier/nodeTopology + label: Node Topology + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + type: select + label: Advanced Configuration + showLabels: true + type: block-layout + - description: Enable Backup, Monitoring, TLS etc. + elements: + - elements: + - init: + type: func + value: setMonitoring + if: + type: function + name: isToggleOn|monitoring + label: Enable Monitoring? + watcher: + func: updateAlertValue + paths: + - temp/monitoring + schema: temp/monitoring + type: switch + - customClass: mt-10 + if: + type: function + name: showAlerts + label: Alert Options 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/spec/properties/deletionPolicy + - text: None + value: none + - text: Critical + value: critical + - text: Warning + value: warning + - text: Info + value: info + schema: schema/properties/form/properties/alert/properties/enabled type: select - - if: getDefaultValue|spec/admin/authCredential/customize - label: - text: Provide Authentication Credentials? - onChange: onAuthChange - schema: - $ref: discriminator#/createAuthSecret - type: switch - - if: showReferSecretSwitch - label: - text: Refer existing Secret? - onChange: onReferSecretChange - schema: - $ref: discriminator#/referSecret + type: block-layout + - init: + type: func + value: setBackup + if: + type: function + name: isToggleOn|backup + label: Enable Backup? + watcher: + func: onBackupSwitch + paths: + - temp/backup + schema: temp/backup + type: switch + - elements: + - if: + type: function + name: isToggleOn|tls + label: Enable TLS? + schema: schema/properties/spec/properties/admin/properties/tls/properties/default type: switch - - fetch: getReferSecrets - if: showSecretDropdown - label: - text: Secret - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/name + - loader: getAdminOptions|clusterIssuers + if: + type: function + name: showIssuer + label: Cluster Issuers + validation: + type: required + schema: schema/properties/spec/properties/admin/properties/clusterIssuers/properties/default type: select - - if: showReferSecret - label: - text: labels.password - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/password - type: input - - computed: isConfigAvailable - if: getDefaultValue|spec/admin/customConfiguration - label: - text: Configure Database? - onChange: clearConfiguration - schema: - $ref: discriminator#/configDatabase + type: block-layout + - elements: + - if: + type: function + name: isToggleOn|expose + label: Expose via Gateway? + schema: schema/properties/spec/properties/admin/properties/expose/properties/default type: switch - - if: isConfigDatabaseOn - label: - text: Configuration - schema: - $ref: schema#/properties/spec/properties/configuration - type: editor - - hasDescription: true - if: isToggleOn|deployment - label: - text: labels.deployment.name - options: - - description: labels.deployment.shared - text: Shared - value: Shared - - description: labels.deployment.dedicated - text: Dedicated - value: Dedicated - schema: - $ref: schema#/properties/spec/properties/admin/properties/deployment/properties/default - type: radio - - if: isToggleOn|clusterTier - isHorizontal: true - label: - text: labels.clusterTier - options: - - text: General Purpose - value: GeneralPurpose - - text: Memory Optimized - value: MemoryOptimized - - text: CPU Optimized - value: CPUOptimized - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/default - type: radio - - disableUnselect: true - fetch: getAdminOptions|clusterTier/placement - if: isToggleOn|clusterTier/placement - label: - text: labels.placement - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default - type: select - - disableUnselect: true - fetch: getNodeTopology - if: isToggleOn|clusterTier/nodeTopology - label: - text: labels.nodeTopology - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default - type: select - hideForm: true - label: - text: Advanced Configuration - show_label: true - type: single-step-form - - accordion: true - description: - text: Enable Backup, Monitoring, TLS etc. - discriminator: - backup: - default: false - type: boolean - elements: - - discriminator: - monitoring: - default: false - type: boolean - elements: - - computed: setMonitoring - if: isToggleOn|monitoring - label: - text: labels.enable_monitoring - onChange: updateAlertValue - schema: - $ref: discriminator#/monitoring - type: switch - - customClass: mt-10 - if: showAlerts - label: - text: labels.alert.options - options: - - text: None - value: none - - text: Critical - value: critical - - text: Warning - value: warning - - text: Info - value: info - schema: - $ref: schema#/properties/form/properties/alert/properties/enabled - sortable: true - type: select - type: single-step-form - - computed: setBackup - if: isToggleOn|backup - label: - text: Enable Backup? - onChange: onBackupSwitch - schema: - $ref: discriminator#/backup + type: block-layout + - elements: + - label: Disable Defaults + schema: schema/properties/spec/properties/kernelSettings/properties/disableDefaults type: switch - - elements: - - if: isToggleOn|tls - label: - text: Enable TLS? - schema: - $ref: schema#/properties/spec/properties/admin/properties/tls/properties/default - type: switch - - fetch: getAdminOptions|clusterIssuers - if: showIssuer - label: - text: labels.clusterIssuers - required: true - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterIssuers/properties/default - type: select - type: single-step-form - - elements: - - if: isToggleOn|expose - label: - text: Expose via Gateway? - schema: - $ref: schema#/properties/spec/properties/admin/properties/expose/properties/default - type: switch - type: single-step-form - - elements: - - label: - text: labels.disableDefaults - schema: - $ref: schema#/properties/spec/properties/kernelSettings/properties/disableDefaults - type: switch - type: single-step-form - if: showAdditionalSettings - label: - text: Additional Options - show_label: true - type: single-step-form - type: single-step-form + type: block-layout + if: + type: function + name: showAdditionalSettings + label: Additional Options + showLabels: true + type: block-layout id: options - title: steps.0.label type: multi-step-form diff --git a/charts/kubedbcom-elasticsearch-editor-options/ui/functions.js b/charts/kubedbcom-elasticsearch-editor-options/ui/functions.js index 659cc5ccff..1809b653d0 100644 --- a/charts/kubedbcom-elasticsearch-editor-options/ui/functions.js +++ b/charts/kubedbcom-elasticsearch-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -315,829 +317,879 @@ const modeDetails = { }, } -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) -function showStorageSizeField({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - const validType = ['Standalone', 'Replicaset'] - return validType.includes(modelPathValue) -} + setDiscriminatorValue('bundleApiLoaded', false) + setDiscriminatorValue('configDatabase', false) + setDiscriminatorValue('createAuthSecret', false) + setDiscriminatorValue('referSecret', false) + setDiscriminatorValue('backup', false) + setDiscriminatorValue('monitoring', false) + + let placement = [] + let versions = [] + let storageClass = [] + let clusterIssuers = [] + let nodetopologiesShared = [] + let nodetopologiesDedicated = [] + let features = [] + + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } -function setMachineToCustom({ getValue, model }) { - const machine = getValue(model, '/spec/admin/machineProfiles/default') - return machine || 'custom' -} + function showStorageSizeField() { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + const validType = ['Standalone', 'Replicaset'] + return validType.includes(modelPathValue) + } -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function setMachineToCustom() { + const machine = getValue(model, '/spec/admin/machineProfiles/default') + return machine || 'custom' + } - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + function getCreateNameSpaceUrl() { + 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } } -} -const ifCapiProviderIsNotEmpty = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/provider') - const val = getValue(model, '/form/capi/provider') - if (val) return true -} + const ifCapiProviderIsNotEmpty = () => { + // watchDependency('model#/form/capi/provider') + const val = getValue(model, '/form/capi/provider') + if (val) return true + } -const showMultiselectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') + const showMultiselectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') - if (val === 'capz' && ifDedicated({ model, getValue })) return true -} + if (val === 'capz' && ifDedicated()) return true + } -const showSelectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') - if (val !== 'capz' && ifDedicated({ model, getValue })) return true -} + const showSelectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') + if (val !== 'capz' && ifDedicated()) return true + } -const ifDedicated = ({ model, getValue }) => { - const val = getValue(model, 'form/capi/dedicated') - if (val) return true -} + const ifDedicated = () => { + const val = getValue(model, 'form/capi/dedicated') + if (val) return true + } -const dedicatedOnChange = ({ model, getValue, commit }) => { - const val = getValue(model, 'form/capi/dedicated') - if (!val) { - commit('wizard/model$delete', 'form/capi/zones') - commit('wizard/model$delete', 'form/capi/sku') + const dedicatedOnChange = () => { + const val = getValue(model, 'form/capi/dedicated') + if (!val) { + commit('wizard/model$delete', 'form/capi/zones') + commit('wizard/model$delete', 'form/capi/sku') + } } -} -const ifZones = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/zones') - watchDependency('model#/form/capi/dedicated') - const zones = getValue(model, 'form/capi/zones') || [] - const isDedicated = getValue(model, 'form/capi/dedicated') - if (zones.length && isDedicated) return true -} + const ifZones = () => { + // watchDependency('model#/form/capi/zones') + // watchDependency('model#/form/capi/dedicated') + const zones = getValue(model, 'form/capi/zones') || [] + const isDedicated = getValue(model, 'form/capi/dedicated') + if (zones.length && isDedicated) return true + } -const zonesOnChange = ({ model, getValue, commit }) => { - const zones = getValue(model, 'form/capi/zones') || [] - if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') -} + const zonesOnChange = () => { + const zones = getValue(model, 'form/capi/zones') || [] + if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') + } -async function getZones({ storeGet, axios, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const isDedicated = getValue(model, 'form/capi/dedicated') - if (isDedicated) { - try { - const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) - const val = resp.data.map((item) => { - return { value: item, text: item } - }) - return val - } catch (e) { - console.log(e) - return [] + async function getZones() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const isDedicated = getValue(model, 'form/capi/dedicated') + if (isDedicated) { + try { + const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) + const val = resp.data.map((item) => { + return { value: item, text: item } + }) + return val + } catch (e) { + console.log(e) + return [] + } } } -} -async function getSKU({ storeGet, axios, model, getValue, watchDependency }) { - watchDependency('model#/form/capi/zones') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const zones = getValue(model, 'form/capi/zones') || [] - if (zones.length) { - try { - let url = `clustersv2/${owner}/${cluster}/vms?` - if (typeof zones === 'string') { - url += `zones=${encodeURIComponent(zones)}` - } else { - zones.forEach((item) => { - url += `zones=${encodeURIComponent(item)}&` + async function getSKU() { + // watchDependency('model#/form/capi/zones') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const zones = getValue(model, 'form/capi/zones') || [] + if (zones.length) { + try { + let url = `clustersv2/${owner}/${cluster}/vms?` + if (typeof zones === 'string') { + url += `zones=${encodeURIComponent(zones)}` + } else { + zones.forEach((item) => { + url += `zones=${encodeURIComponent(item)}&` + }) + url = url.slice(0, -1) + } + const resp = await axios.get(url) + const val = resp.data.map((item) => { + return { + value: item.name, + text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, + } }) - url = url.slice(0, -1) + return val + } catch (e) { + console.log(e) + return [] } - const resp = await axios.get(url) - const val = resp.data.map((item) => { - return { - value: item.name, - text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, - } - }) - return val - } catch (e) { - console.log(e) - return [] } } -} - -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} -function setStorageClass({ model, getValue, commit, discriminator, watchDependency }) { - const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' - let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' - const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] - const suffix = '-retain' - - const simpleClassList = storageClassList.filter((item) => { - return !item.endsWith(suffix) - }) - const retainClassList = storageClassList.filter((item) => { - return item.endsWith(suffix) - }) - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] - } else { - storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false } - const isChangeable = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'storageClasses', - ) - if (isChangeable && storageClass) { - commit('wizard/model$update', { - path: '/spec/admin/storageClasses/default', - value: storageClass, - force: true, - }) - } -} + function setStorageClass() { + const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' + let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' + const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] + const suffix = '-retain' -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], - }, - }, - ) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace + const simpleClassList = storageClassList.filter((item) => { + return !item.endsWith(suffix) + }) + const retainClassList = storageClassList.filter((item) => { + return item.endsWith(suffix) + }) + if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { + storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] } else { - return resp.data?.status?.namespaces || [] + storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] } - } catch (e) { - console.log(e) - } - return [] -} - -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} -let placement = [] -let versions = [] -let storageClass = [] -let clusterIssuers = [] -let nodetopologiesShared = [] -let nodetopologiesDedicated = [] -let features = [] -async function initBundle({ commit, model, getValue, axios, storeGet, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - - let db = getValue(model, '/metadata/resource/kind') - db = db.toLowerCase() - let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` - const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - try { - const resp = await axios.get(url) - features = resp.data.features || [] - placement = resp.data.placementpolicies || [] - versions = resp.data.versions || [] - storageClass = resp.data.storageclasses || [] - clusterIssuers = resp.data.clusterissuers || [] - nodetopologiesDedicated = resp.data.dedicated || [] - nodetopologiesShared = resp.data.shared || [] - - const response = await axios.get(annotationUrl) - const annotations = response.data?.metadata?.annotations || {} - const uidRange = annotations['openshift.io/sa.scc.uid-range'] - if (uidRange) { - const val = uidRange.split('/')[0] + const isChangeable = isToggleOn('storageClasses') + if (isChangeable && storageClass) { commit('wizard/model$update', { - path: '/spec/openshift/securityContext/runAsUser', - value: val, + path: '/spec/admin/storageClasses/default', + value: storageClass, force: true, }) } - } catch (e) { - console.log(e) } - commit('wizard/model$update', { - path: '/spec/deletionPolicy', - value: getDefault({ getValue, model }, 'deletionPolicy'), - force: true, - }) - - if (!getValue(model, `/spec/admin/databases/Elasticsearch/mode/toggle`)) { - let defMode = getDefault({ getValue, model }, 'databases/Elasticsearch/mode') || '' - if (defMode === '') { - const arr = getValue(model, '/spec/databases/Elasticsearch/mode/available') || [] - if (arr.length) defMode = arr[0] + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, + }, + ) + if (resp.data?.status?.projects) { + const projects = resp.data?.status?.projects + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } + } catch (e) { + console.log(e) } - commit('wizard/model$update', { - path: '/spec/mode', - value: defMode, - force: true, - }) + return [] } - if (!features.includes('tls')) { - commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: false, - force: true, - }) - } - if (!features.includes('binding')) { - commit('wizard/model$update', { - path: '/spec/admin/expose/default', - value: false, - force: true, - }) - } - if (!features.includes('monitoring')) { - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: 'none', - force: true, - }) - } - if (!features.includes('backup')) { - commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, - force: true, - }) - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: '', - force: true, - }) + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found } - setDiscriminatorValue('/bundleApiLoaded', true) -} + async function initBundle() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') -function fetchOptions({ model, getValue, commit }, type) { - let kind = getValue(model, '/metadata/resource/kind') - - let returnArray = [] - if (type === 'clusterTier/placement') { - returnArray = placement - } else if (type === `databases/${kind}/versions`) { - returnArray = versions - } else if (type === 'storageClasses') { - returnArray = storageClass - } else if (type === 'clusterIssuers') { - returnArray = clusterIssuers - } + let db = getValue(model, '/metadata/resource/kind') + db = db.toLowerCase() + let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` + const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` + try { + const resp = await axios.get(url) + features = resp.data.features || [] + placement = resp.data.placementpolicies || [] + versions = resp.data.versions || [] + storageClass = resp.data.storageclasses || [] + clusterIssuers = resp.data.clusterissuers || [] + nodetopologiesDedicated = resp.data.dedicated || [] + nodetopologiesShared = resp.data.shared || [] + + const response = await axios.get(annotationUrl) + const annotations = response.data?.metadata?.annotations || {} + const uidRange = annotations['openshift.io/sa.scc.uid-range'] + if (uidRange) { + const val = uidRange.split('/')[0] + commit('wizard/model$update', { + path: '/spec/openshift/securityContext/runAsUser', + value: val, + force: true, + }) + } + } catch (e) { + console.log(e) + } - if (returnArray.length === 1) { - const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: path, - value: returnArray[0], + path: '/spec/deletionPolicy', + value: getDefault('deletionPolicy'), force: true, }) - } - return returnArray -} - -function getAdminOptions({ getValue, model, watchDependency, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') - const options = getValue(model, `/spec/admin/${type}/available`) || [] + if (!getValue(model, `/spec/admin/databases/Elasticsearch/mode/toggle`)) { + let defMode = getDefault('databases/Elasticsearch/mode') || '' + if (defMode === '') { + const arr = getValue(model, '/spec/databases/Elasticsearch/mode/available') || [] + if (arr.length) defMode = arr[0] + } + commit('wizard/model$update', { + path: '/spec/mode', + value: defMode, + force: true, + }) + } - if (options.length === 0) { - return fetchOptions({ model, getValue, commit }, type) - } - if (type.endsWith('/mode')) { - return ( - options?.map((item) => ({ - description: modeDetails[item]?.description || '', - text: modeDetails[item]?.text || '', - value: item, - })) || [] - ) - } - return options -} + if (!features.includes('tls')) { + commit('wizard/model$update', { + path: '/spec/admin/tls/default', + value: false, + force: true, + }) + } + if (!features.includes('binding')) { + commit('wizard/model$update', { + path: '/spec/admin/expose/default', + value: false, + force: true, + }) + } + if (!features.includes('monitoring')) { + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: 'none', + force: true, + }) + } + if (!features.includes('backup')) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: '', + force: true, + }) + } -function checkIfFeatureOn({ getValue, model }, type) { - let val = getValue(model, `/spec/admin/${type}/toggle`) - if (type === 'backup' || type === 'archiver') { - val = getValue(model, `/spec/admin/${type}/enable/toggle`) + setDiscriminatorValue('/bundleApiLoaded', true) } - const backupVal = getValue(model, '/spec/backup/tool') - - if (type === 'backup') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } else if (type === 'tls') { - return features.includes('tls') && val - } else if (type === 'expose') { - return features.includes('binding') && val - } else if (type === 'monitoring') { - return features.includes('monitoring') && val - } else if (type === 'archiver') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } -} + function fetchOptions(type) { + let kind = getValue(model, '/metadata/resource/kind') + + let returnArray = [] + if (type === 'clusterTier/placement') { + returnArray = placement + } else if (type === `databases/${kind}/versions`) { + returnArray = versions + } else if (type === 'storageClasses') { + returnArray = storageClass + } else if (type === 'clusterIssuers') { + returnArray = clusterIssuers + } -function isToggleOn({ getValue, model, discriminator, watchDependency }, type) { - watchDependency('discriminator#/bundleApiLoaded') - watchDependency('model#/spec/admin/deployment/default') - const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') - let deploymentType = getValue(model, `/spec/admin/deployment/default`) - if ( - type === 'tls' || - type === 'backup' || - type === 'expose' || - type === 'monitoring' || - type === 'archiver' - ) { - return checkIfFeatureOn({ getValue, model }, type) - } else if ( - type === 'clusterTier' || - type === 'clusterTier/placement' || - type === 'clusterTier/nodeTopology' - ) { - if (deploymentType === 'Dedicated' && bundleApiLoaded) return true - else return false - } else if (type === 'deployment') { - const deploymentType = getValue(model, '/spec/admin/deployment/default') - if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + if (returnArray.length === 1) { + const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: '/spec/admin/deployment/default', - value: 'Shared', + path: path, + value: returnArray[0], force: true, }) } - return ( - getValue(model, `/spec/admin/${type}/toggle`) && - nodetopologiesDedicated.length && - bundleApiLoaded - ) - } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded -} -async function getNodeTopology({ model, getValue, axios, storeGet, watchDependency }) { - watchDependency('model#/spec/admin/deployment/default') - watchDependency('model#/spec/admin/clusterTier/default') - const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' - const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' - let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + return returnArray + } - const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + function getAdminOptions(type) { + // watchDependency('discriminator#/bundleApiLoaded') + const options = getValue(model, `/spec/admin/${type}/available`) || [] - if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared - else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + if (options.length === 0) { + return fetchOptions(type) + } + if (type.endsWith('/mode')) { + return ( + options?.map((item) => ({ + description: modeDetails[item]?.description || '', + text: modeDetails[item]?.text || '', + value: item, + })) || [] + ) + } + return options + } - const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) - return filteredList -} + let backupToolInitialValue = '' + function checkIfFeatureOn(type) { + let val = getValue(model, `/spec/admin/${type}/toggle`) + if (type === 'backup' || type === 'archiver') { + val = getValue(model, `/spec/admin/${type}/enable/toggle`) + } + const backupVal = getValue(model, '/spec/backup/tool') + if (type === 'backup') { + if (backupToolInitialValue === '') { + backupToolInitialValue = + features.includes('backup') && backupVal === 'KubeStash' && val ? 'on' : 'off' + return features.includes('backup') && backupVal === 'KubeStash' && val + } else { + if (backupToolInitialValue === 'on') { + return true + } else { + return false + } + } + } else if (type === 'tls') { + return features.includes('tls') && val + } else if (type === 'expose') { + return features.includes('binding') && val + } else if (type === 'monitoring') { + return features.includes('monitoring') && val + } else if (type === 'archiver') { + return features.includes('backup') && val + } + } -function filterNodeTopology(list, tier, provider) { - // first filter the list from value that exists from the filtered list got from API - const filteredlist = list + function isToggleOn(type) { + // watchDependency('discriminator#/bundleApiLoaded') + // watchDependency('model#/spec/admin/deployment/default') + const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') + let deploymentType = getValue(model, `/spec/admin/deployment/default`) + if ( + type === 'tls' || + type === 'backup' || + type === 'expose' || + type === 'monitoring' || + type === 'archiver' + ) { + return checkIfFeatureOn(type) + } else if ( + type === 'clusterTier' || + type === 'clusterTier/placement' || + type === 'clusterTier/nodeTopology' + ) { + if (deploymentType === 'Dedicated' && bundleApiLoaded) return true + else return false + } else if (type === 'deployment') { + const deploymentType = getValue(model, '/spec/admin/deployment/default') + if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + commit('wizard/model$update', { + path: '/spec/admin/deployment/default', + value: 'Shared', + force: true, + }) + } + return ( + getValue(model, `/spec/admin/${type}/toggle`) && + nodetopologiesDedicated.length && + bundleApiLoaded + ) + } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded + } - // filter the list based on clusterTier - if (provider === 'EKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('c') - else if (tier === 'MemoryOptimized') return item.startsWith('r') - else return !item.startsWith('c') && !item.startsWith('r') - }) - } else if (provider === 'AKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - else - return ( - !(item.startsWith('f') || item.startsWith('fx')) && - !( + async function getNodeTopology() { + // watchDependency('model#/spec/admin/deployment/default') + // watchDependency('model#/spec/admin/clusterTier/default') + const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' + const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' + let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + + const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + + if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared + else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + + const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) + return filteredList + } + + function filterNodeTopology(list, tier, provider) { + // first filter the list from value that exists from the filtered list got from API + const filteredlist = list + + // filter the list based on clusterTier + if (provider === 'EKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('c') + else if (tier === 'MemoryOptimized') return item.startsWith('r') + else return !item.startsWith('c') && !item.startsWith('r') + }) + } else if (provider === 'AKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('e') || item.startsWith('eb') || item.startsWith('ec') || item.startsWith('m') || item.startsWith('d') ) - ) - }) - } else if (provider === 'GKE') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') - return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - else - return ( - !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && - !( + else + return ( + !(item.startsWith('f') || item.startsWith('fx')) && + !( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + ) + }) + } else if (provider === 'GKE') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') + return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('x4') || item.startsWith('m1') || item.startsWith('m2') || item.startsWith('m3') ) - ) - }) - } else return filteredlist -} + else + return ( + !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && + !( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + ) + }) + } else return filteredlist + } -function returnFalse() { - return false -} + function returnFalse() { + return false + } -function getMachineListForOptions({ model, getValue }) { - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') let array = [] + function getMachineListForOptions() { + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') - if (available.length) { - array = available.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - else { - let subText = '', - text = '' - const machineData = machinesFromPreset.find((val) => val.id === machine) - if (machineData) { - subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` - text = machineData.name ? machineData.name : machineData.id - } - return { text, subText, value: machine } - } - }) - } else { - array = machineList - .map((machine) => { + if (available.length) { + array = available.map((machine) => { if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + else { + let subText = '', + text = '' + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + text = machineData.name ? machineData.name : machineData.id + } + return { text, subText, value: machine } + } }) - .filter((val) => !!val) + } else { + array = machineList + .map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { text, subText, value: machine } + }) + .filter((val) => !!val) + } + return array } - return array -} -function setLimits({ model, getValue, commit, watchDependency }, resource, type) { - const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' - watchDependency(`model#${path}`) - const selectedMachine = getValue(model, path) || 'custom' - const reqCommitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - const comparePath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - - const resourceValue = getValue(model, comparePath) - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - - let cpu = '', - memory = '' - if (available.length && selectedMachine !== 'custom') { - const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) - if (machineData) { - cpu = machineData.limits.cpu - memory = machineData.limits.memory + function setLimits(resource, type) { + const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' + // watchDependency(`model#${path}`) + const selectedMachine = getValue(model, path) || 'custom' + const reqCommitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + const comparePath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + + const resourceValue = getValue(model, comparePath) + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + let cpu = '', + memory = '' + if (available.length && selectedMachine !== 'custom') { + const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) + if (machineData) { + cpu = machineData.limits.cpu + memory = machineData.limits.memory + } + } else { + if (selectedMachine === 'custom') { + cpu = resourceValue + memory = resourceValue + } else { + cpu = machines[selectedMachine].resources.limits.cpu + memory = machines[selectedMachine].resources.limits.memory + } } - } else { - if (selectedMachine === 'custom') { - cpu = resourceValue - memory = resourceValue + + if (resource === 'memory') { + commit('wizard/model$update', { + path: reqCommitPath, + value: memory, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: memory, + force: true, + }) + return memory } else { - cpu = machines[selectedMachine].resources.limits.cpu - memory = machines[selectedMachine].resources.limits.memory + commit('wizard/model$update', { + path: reqCommitPath, + value: cpu, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: cpu, + force: true, + }) + return cpu } } - if (resource === 'memory') { + function setRequests(resource, type) { + const modelPath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + + const fullpath = `/spec/podResources/machine` + const modelPathValue = getValue(model, fullpath) + commit('wizard/model$update', { - path: reqCommitPath, - value: memory, + path: commitPath, + value: val, force: true, }) + + if (modelPathValue === 'custom') { + return + } + let commitCpuMemory, ModelPathValue + if (resource && type) { + const fullPath = `/spec/${type}/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/${type}/podResources/resources/requests/${resource}` + } else { + const fullPath = `/spec/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/podResources/resources/requests/${resource}` + } + let cpuMemoryValue + array.forEach((item) => { + if (item.value === ModelPathValue) { + // Parse subText like "CPU: 2, Memory: 2Gi" + const subText = item.subText || '' + if (resource === 'cpu') { + // Extract CPU value + const cpuMatch = subText.match(/CPU:\s*([^,]+)/) + cpuMemoryValue = cpuMatch ? cpuMatch[1].trim() : '' + } else if (resource === 'memory') { + // Extract Memory value + const memoryMatch = subText.match(/Memory:\s*(.+)/) + cpuMemoryValue = memoryMatch ? memoryMatch[1].trim() : '' + } + } + }) commit('wizard/model$update', { - path: comparePath, - value: memory, + path: commitCpuMemory, + value: cpuMemoryValue, force: true, }) - return memory - } else { + return cpuMemoryValue + } + + function isMachineCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue === 'custom' + } + + function isMachineNotCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue !== 'custom' && !!modelPathValue + } + + function notEqualToDatabaseMode(mode) { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + return modelPathValue && modelPathValue !== mode + } + + function onAuthChange() { commit('wizard/model$update', { - path: reqCommitPath, - value: cpu, + path: '/spec/authSecret/name', + value: '', force: true, }) commit('wizard/model$update', { - path: comparePath, - value: cpu, + path: '/spec/authSecret/password', + value: '', force: true, }) - return cpu } -} -function setRequests({ getValue, model, commit }, resource, type) { - const modelPath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - const val = getValue(model, modelPath) - commitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - commit('wizard/model$update', { - path: commitPath, - value: val, - force: true, - }) -} - -function isMachineCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue === 'custom' -} - -function isMachineNotCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue !== 'custom' && !!modelPathValue -} - -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} - -function onAuthChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/authSecret/password', - value: '', - force: true, - }) -} + function clearConfiguration() { + const configOn = getValue(discriminator, '/configDatabase') -function clearConfiguration({ discriminator, getValue, commit }) { - const configOn = getValue(discriminator, '/configDatabase') + if (!configOn) { + commit('wizard/model$delete', '/spec/configuration') + } + } - if (!configOn) { - commit('wizard/model$delete', '/spec/configuration') + function isConfigDatabaseOn() { + // watchDependency('discriminator#/configDatabase') + return getValue(discriminator, '/configDatabase') } -} -function isConfigDatabaseOn({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configDatabase') - return getValue(discriminator, '/configDatabase') -} + function showIssuer() { + // watchDependency('model#/spec/admin/tls/default') + const isTlsEnabled = getValue(model, '/spec/admin/tls/default') + const isIssuerToggleEnabled = isToggleOn('clusterIssuers') + return isTlsEnabled && isIssuerToggleEnabled + } -function showIssuer({ model, getValue, watchDependency, discriminator }) { - watchDependency('model#/spec/admin/tls/default') - const isTlsEnabled = getValue(model, '/spec/admin/tls/default') - const isIssuerToggleEnabled = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'clusterIssuers', - ) - return isTlsEnabled && isIssuerToggleEnabled -} + function setMonitoring() { + const agent = getValue(model, '/spec/admin/monitoring/agent') || '' + return !!agent + } -function setMonitoring({ getValue, model }) { - const agent = getValue(model, '/spec/admin/monitoring/agent') || '' - return !!agent -} + function updateAlertValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const alert = isMonitorEnabled ? 'warning' : 'none' + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: alert, + force: true, + }) + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: agent, + force: true, + }) + } -function updateAlertValue({ commit, model, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const alert = isMonitorEnabled ? 'warning' : 'none' - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: alert, - force: true, - }) - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} + function setBackup() { + const backup = getValue(model, '/spec/backup/tool') + const val = getValue(model, '/spec/admin/backup/enable/default') + return backup === 'KubeStash' && features.includes('backup') && val + } -function setBackup({ model, getValue }) { - const backup = getValue(model, '/spec/backup/tool') - const val = getValue(model, '/spec/admin/backup/enable/default') - return backup === 'KubeStash' && features.includes('backup') && val -} + function showAlerts() { + // watchDependency('discriminator#/monitoring') + const isMonitorEnabled = getValue(discriminator, '/monitoring') + return isMonitorEnabled && isToggleOn('alert') + } -function showAlerts({ watchDependency, model, getValue, discriminator }) { - watchDependency('discriminator#/monitoring') - const isMonitorEnabled = getValue(discriminator, '/monitoring') - return ( - isMonitorEnabled && isToggleOn({ getValue, model, discriminator, watchDependency }, 'alert') - ) -} + function onBackupSwitch() { + const isBackupOn = getValue(discriminator, '/backup') + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: isBackupOn ? 'KubeStash' : '', + force: true, + }) + } -function onBackupSwitch({ discriminator, getValue, commit }) { - const isBackupOn = getValue(discriminator, '/backup') - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: isBackupOn ? 'KubeStash' : '', - force: true, - }) -} + function showAdditionalSettings() { + // watchDependency('discriminator#/bundleApiLoaded') + return features.length + } -function showAdditionalSettings({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return features.length -} + function getDefault(type) { + const val = getValue(model, `/spec/admin/${type}/default`) || '' + return val + } -function getDefault({ getValue, model }, type) { - const val = getValue(model, `/spec/admin/${type}/default`) || '' - return val -} + async function getReferSecrets() { + const referSecret = getValue(discriminator, '/referSecret') + if (!referSecret) { + return [] + } -function isConfigAvailable({ getValue, model }) { - const val = getValue(model, '/spec/configuration') - return val !== '' -} + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/metadata/release/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` -async function getReferSecrets({ getValue, model, storeGet, axios, discriminator }) { - const referSecret = getValue(discriminator, '/referSecret') - if (!referSecret) { - return [] + const options = [] + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + return options } - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/metadata/release/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - - const options = [] - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) - } catch (e) { - console.log(e) + function showAuthPasswordField() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !modelPathValue && showReferSecret() } - return options -} - -function showAuthPasswordField({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} -function showSecretDropdown({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showSecretDropdown() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !!modelPathValue && showReferSecret() + } -function showReferSecret({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/createAuthSecret') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue -} + function showReferSecret() { + const modelPathValue = getValue(discriminator, '/createAuthSecret') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue + } -function getDefaultValue({ getValue, model }, path) { - const val = getValue(model, `/${path}`) || '' - return val -} + function getDefaultValue(path) { + const val = getValue(model, `/${path}`) || '' + return val + } -function showReferSecretSwitch({ model, getValue, watchDependency, discriminator }) { - const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showReferSecretSwitch() { + const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue && showReferSecret() + } -function onReferSecretChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) -} + function onReferSecretChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + } -return { - showReferSecretSwitch, - onReferSecretChange, - getDefaultValue, - isRancherManaged, - showSecretDropdown, - showReferSecret, - getReferSecrets, - isConfigAvailable, - showAdditionalSettings, - returnFalse, - initBundle, - isVariantAvailable, - showAuthPasswordField, - isEqualToModelPathValue, - showStorageSizeField, - setMachineToCustom, - getCreateNameSpaceUrl, - ifCapiProviderIsNotEmpty, - ifDedicated, - dedicatedOnChange, - ifZones, - zonesOnChange, - getZones, - getSKU, - showMultiselectZone, - showSelectZone, - setStorageClass, - getNamespaces, - isToggleOn, - getAdminOptions, - getNodeTopology, - filterNodeTopology, - getMachineListForOptions, - setLimits, - setRequests, - isMachineNotCustom, - isMachineCustom, - notEqualToDatabaseMode, - onAuthChange, - clearConfiguration, - isConfigDatabaseOn, - showIssuer, - setMonitoring, - updateAlertValue, - showAlerts, - onBackupSwitch, - setBackup, - getDefault, + return { + showReferSecretSwitch, + onReferSecretChange, + getDefaultValue, + isRancherManaged, + showSecretDropdown, + showReferSecret, + getReferSecrets, + showAdditionalSettings, + returnFalse, + initBundle, + isVariantAvailable, + showAuthPasswordField, + isEqualToModelPathValue, + showStorageSizeField, + setMachineToCustom, + getCreateNameSpaceUrl, + ifCapiProviderIsNotEmpty, + ifDedicated, + dedicatedOnChange, + ifZones, + zonesOnChange, + getZones, + getSKU, + showMultiselectZone, + showSelectZone, + setStorageClass, + getNamespaces, + isToggleOn, + getAdminOptions, + getNodeTopology, + filterNodeTopology, + getMachineListForOptions, + setLimits, + setRequests, + isMachineNotCustom, + isMachineCustom, + notEqualToDatabaseMode, + onAuthChange, + clearConfiguration, + isConfigDatabaseOn, + showIssuer, + setMonitoring, + updateAlertValue, + showAlerts, + onBackupSwitch, + setBackup, + getDefault, + } } diff --git a/charts/kubedbcom-elasticsearch-editor/ui/edit-ui.yaml b/charts/kubedbcom-elasticsearch-editor/ui/edit-ui.yaml index 8142984be7..36f8901901 100644 --- a/charts/kubedbcom-elasticsearch-editor/ui/edit-ui.yaml +++ b/charts/kubedbcom-elasticsearch-editor/ui/edit-ui.yaml @@ -1,2349 +1,1169 @@ -steps: -- form: - discriminator: - createAuthSecret: - type: boolean - elements: - - disabled: true - label: - text: labels.database.name - onChange: onNameChange - schema: - $ref: schema#/properties/metadata/properties/release/properties/name - type: input - - disabled: true - fetch: getResources|core|v1|namespaces - label: - text: labels.namespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/metadata/properties/release/properties/namespace - type: select - - disableUnselect: true - disabled: true - fetch: getElasticSearchVersions|catalog.kubedb.com|v1alpha1|elasticsearchversions - label: - text: labels.database.version - onChange: onVersionChange - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/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/kubedbComElasticsearch/properties/metadata/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/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/kubedbComElasticsearch/properties/metadata/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/metadata/properties/annotations/additionalProperties - type: input - - hasDescription: true - label: - text: labels.deletionPolicy - 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/kubedbComElasticsearch/properties/spec/properties/deletionPolicy - type: radio - - disabled: true - label: - text: labels.disable_security_question - onChange: onDisableSecurityChange - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/disableSecurity - type: switch - - elements: - - label: - text: labels.database.admin_secret - type: label-element - - disabled: true - label: - text: labels.secret - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/authSecret/properties/name - type: input - if: isSecurityEnabled - type: single-step-form - type: single-step-form - id: basic - title: steps.0.label -- form: - elements: - - alias: reusable_alert - chart: - name: uibytebuildersdev-component-alert - version: v0.29.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: - type: string +type: multi-step-form +step: + - type: single-step-form + id: backupconfiguration + # label: Backup + schema: schema/ elements: - - label: - text: labels.to_update_disabled_section - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - params: - cluster: - $ref: store#/route/params/cluster - dbname: - $ref: model#/metadata/release/name - domain: - $ref: store#/domain - group: - $ref: model#/metadata/resource/group - kind: - $ref: model#/metadata/resource/kind - namespace: - $ref: model#/metadata/release/namespace - owner: - $ref: store#/route/params/user - resource: - $ref: model#/metadata/resource/name - version: - $ref: model#/metadata/resource/version - path: ${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/elasticsearchopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations - - computed: setDatabaseMode - disabled: true - hasDescription: true - label: - text: labels.database.mode - onChange: deleteDatabaseModePath + - type: radio + label: Schedule a Backup? + schema: temp/properties/scheduleBackup + isHorizontal: true options: - - description: options.database.mode.Combined.description - text: options.database.mode.Combined.label - value: Combined - - description: options.database.mode.Dedicated.description - text: options.database.mode.Dedicated.label - value: Dedicated - schema: - $ref: discriminator#/activeDatabaseMode - type: radio - - elements: - - disabled: true - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/replicas - type: input - - fetch: getMaxUnavailableOptions|/resources/kubedbComElasticsearch/spec - label: - text: labels.max_unavailable - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/maxUnavailable - type: select - - disabled: true - label: - text: labels.storage.size - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/storage/properties/resources/properties/requests/properties/storage - type: input - - disabled: true - label: - text: labels.storage.class - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/storage/properties/storageClassName - type: input - if: isEqualToDatabaseMode|Combined - type: single-step-form - - element: - elements: - - disabled: true - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/topology/properties/$dyn/properties/replicas - type: input - - fetch: getMaxUnavailableOptions - label: - text: labels.max_unavailable - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/topology/properties/$dyn/properties/maxUnavailable - type: select - - disabled: true - elements: - - elements: - - elements: - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/topology/properties/$dyn/properties/storage/properties/resources/properties/requests/properties/storage - type: input - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/topology/properties/$dyn/properties/storage/properties/resources/properties/requests - type: single-step-form - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/topology/properties/$dyn/properties/storage/properties/resources - type: single-step-form - - label: - text: labels.storage.class - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/topology/properties/$dyn/properties/storage/properties/storageClassName - type: input - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/topology/properties/$dyn/properties/storage - type: single-step-form - - disabled: true - label: - text: labels.suffix - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/topology/properties/$dyn/properties/suffix - type: input - - disabled: true - label: - text: labels.resources - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/topology/properties/$dyn/properties/resources - type: resource-input-form - hideForm: true - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/topology/properties/$dyn - show_label: true - type: single-step-form - individualItemVisibilityCheck: hasTopologyNode - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/topology - type: array-input-form - type: single-step-form - id: topology - title: steps.1.label -- form: - discriminator: - internalUsers: - type: array - elements: - - addFormLabel: labels.user - computed: setInternalUsers - disabled: true - element: - discriminator: - users: - emitAs: internalUsers - type: array - elements: - - disabled: disableUsername - label: - text: labels.username - required: true - schema: - $ref: discriminator#/properties/users/items/properties/username - type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.attributes - schema: - $ref: discriminator#/properties/users/items/properties/attributes - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: discriminator#/properties/users/items/properties/attributes/additionalProperties - type: input - - element: - label: - text: labels.role - schema: - $ref: discriminator#/properties/users/items/properties/backendRoles/items - type: input - label: - text: labels.backendRoles - schema: - $ref: discriminator#/properties/users/items/properties/backendRoles - type: list-input-form - - label: - text: labels.description - schema: - $ref: discriminator#/properties/users/items/properties/description - type: textarea - - label: - text: labels.hidden - schema: - $ref: discriminator#/properties/users/items/properties/hidden - type: switch - - element: - label: - text: labels.role - schema: - $ref: discriminator#/properties/users/items/properties/opendistroSecurityRoles/items - type: input - if: isAuthPluginEqualTo|OpenDistro - label: - text: labels.opendistro_security_roles - schema: - $ref: discriminator#/properties/users/items/properties/opendistroSecurityRoles - type: list-input-form - - label: - text: labels.reserved - schema: - $ref: discriminator#/properties/users/items/properties/reserved - type: switch - - element: - label: - text: labels.role - schema: - $ref: discriminator#/properties/users/items/properties/searchGuardRoles/items - type: input - if: isAuthPluginEqualTo|SearchGuard - label: - text: labels.search_guard_roles - schema: - $ref: discriminator#/properties/users/items/properties/searchGuardRoles - type: list-input-form - - allowUserDefinedOption: true - fetch: getSecrets - label: - text: labels.secret_name - schema: - $ref: discriminator#/properties/users/items/properties/secretName - type: select - type: single-step-form - individualItemDisabilityCheck: disableUserEdit - label: - text: labels.internal_users - newItemValidator: validateNewUser - onChange: onInternalUsersChange - schema: - $ref: discriminator#/properties/internalUsers - tableContents: - - inTableColumn: true - label: - text: labels.username - path: username - type: value - typeOfValue: string - - label: - text: labels.attributes - path: attributes - type: value - typeOfValue: key-value - - inTableColumn: true - label: - isSubsection: true - text: labels.backendRoles - path: backendRoles - type: value - typeOfValue: array - - label: - text: labels.description - path: description - type: value - typeOfValue: string - - label: - text: labels.hidden - path: hidden - type: value - typeOfValue: string - - label: - isSubsection: true - text: labels.opendistro_security_roles - path: opendistroSecurityRoles - type: value - typeOfValue: array - - inTableColumn: true - label: - text: labels.reserved - path: reserved - type: value - typeOfValue: string - - label: - isSubsection: true - text: labels.search_guard_roles - path: searchGuardRoles - type: value - typeOfValue: array - - inTableColumn: true - label: - text: labels.secret_name - path: secretName - type: value - typeOfValue: string - type: single-step-form-array - type: single-step-form - id: internal-users - if: showInternalUsersAndRolesMapping - title: steps.2.label -- form: - discriminator: - rolesMapping: - type: array - elements: - - addFormLabel: labels.role - computed: setRolesMapping - disabled: true - element: - discriminator: - roles: - emitAs: rolesMapping - type: array - elements: - - label: - text: labels.role_name - required: true - schema: - $ref: discriminator#/properties/roles/items/properties/roleName - type: input - - element: - label: - text: labels.role - schema: - $ref: discriminator#/properties/roles/items/properties/andBackendRoles/items - type: input - label: - text: labels.andBackendRoles - schema: - $ref: discriminator#/properties/roles/items/properties/andBackendRoles - type: list-input-form - - element: - label: - text: labels.role - schema: - $ref: discriminator#/properties/roles/items/properties/backendRoles/items - type: input - label: - text: labels.backendRoles - schema: - $ref: discriminator#/properties/roles/items/properties/backendRoles - type: list-input-form - - label: - text: labels.hidden - schema: - $ref: discriminator#/properties/roles/items/properties/hidden - type: switch - - element: - label: - text: labels.host - schema: - $ref: discriminator#/properties/roles/items/properties/hosts/items - type: input - label: - text: labels.hosts - schema: - $ref: discriminator#/properties/roles/items/properties/hosts - type: list-input-form - - label: - text: labels.reserved - schema: - $ref: discriminator#/properties/roles/items/properties/reserved - type: switch - - allowUserDefinedOption: true - fetch: getInternalUsers - label: - text: labels.users - schema: - $ref: discriminator#/properties/roles/items/properties/users - type: multiselect - type: single-step-form - label: - text: labels.roles_mapping - onChange: onRolesMappingChange - schema: - $ref: discriminator#/properties/rolesMapping - tableContents: - - inTableColumn: true - label: - text: labels.role_name - path: roleName - type: value - typeOfValue: string - - inTableColumn: true - label: - isSubsection: true - text: labels.backendRoles - path: backendRoles - type: value - typeOfValue: array - - inTableColumn: true - label: - text: labels.hidden - path: hidden - type: value - typeOfValue: string - - label: - isSubsection: true - text: labels.andBackendRoles - path: andBackendRoles - type: value - typeOfValue: array - - label: - isSubsection: true - text: labels.hosts - path: hosts - type: value - typeOfValue: array - - inTableColumn: true - label: - isSubsection: true - text: labels.users - path: users - type: value - typeOfValue: array - - label: - text: labels.reserved - path: reserved - type: value - typeOfValue: string - type: single-step-form-array - type: single-step-form - id: roles-mapping - if: showInternalUsersAndRolesMapping - title: steps.11.label -- form: - elements: - - discriminator: - customizeKernelSettings: - type: string - elements: - - computed: returnStringYes - label: - text: labels.customizeKernelSettings - onChange: onCustomizeKernelSettingChange - options: - - text: options.yesOrNo.yes.text - value: "yes" - - text: options.kernelSettings.no - value: "no" - - text: options.kernelSettings.disable - value: disable - schema: - $ref: discriminator#/properties/customizeKernelSettings - type: radio - - if: isDiscriminatorEqualTo|/customizeKernelSettings|yes - label: - text: labels.privileged_question - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/kernelSettings/properties/privileged - type: switch - - addFormLabel: labels.sysctl - element: - elements: - - label: - text: labels.name - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/kernelSettings/properties/sysctls/items/properties/name - type: input - - label: - text: labels.value - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/kernelSettings/properties/sysctls/items/properties/value - type: input - type: single-step-form - if: isDiscriminatorEqualTo|/customizeKernelSettings|yes - label: - text: labels.sysctls - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/kernelSettings/properties/sysctls - tableContents: - - inTableColumn: true - label: - text: labels.name - path: name - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.value - path: value - type: value - typeOfValue: string - type: single-step-form-array - keepEmpty: true - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/kernelSettings - type: single-step-form - type: single-step-form - id: kernel-settings - title: steps.10.label -- form: - discriminator: - configureTLS: - default: true - type: boolean - elements: - - if: showTlsRecommendation - label: - text: labels.tls_recommended_text - type: label-element - - label: - text: labels.to_update_tls - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - params: - cluster: - $ref: store#/route/params/cluster - dbname: - $ref: model#/metadata/release/name - domain: - $ref: store#/domain - group: - $ref: model#/metadata/resource/group - kind: - $ref: model#/metadata/resource/kind - namespace: - $ref: model#/metadata/release/namespace - owner: - $ref: store#/route/params/user - resource: - $ref: model#/metadata/resource/name - version: - $ref: model#/metadata/resource/version - path: ${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/elasticsearchopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=ReconfigureTLS - - computed: isValueExistInModel|/resources/kubedbComMariaDB/spec/tls - disabled: true - label: - text: labels.enable_tls - onChange: onTlsConfigureChange - schema: - $ref: discriminator#/configureTLS - type: switch - - disabled: true + - text: 'Yes' + value: 'yes' + - text: 'No' + value: 'no' + if: + type: function + name: showScheduleBackup + init: + type: func + value: initScheduleBackupForEdit + watcher: + func: onScheduleBackupChange + paths: + - temp/properties/scheduleBackup + - type: block-layout + label: Backup Form + showLabels: false + loader: initBackupData + if: + type: function + name: showBackupForm elements: - - label: - text: labels.enable_ssl_question - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/enableSSL - type: switch - - elements: - - computed: setApiGroupEdit - disabled: true - label: - text: labels.api_group - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup - type: input - - label: - text: labels.kind + - type: radio + label: Select Backup Type + schema: temp/properties/backupType + isHorizontal: true options: - - text: Issuer - value: Issuer - - text: ClusterIssuer - value: ClusterIssuer - required: returnFalse - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/tls/properties/issuerRef/properties/kind - type: select - - allowUserDefinedOption: true - fetch: getIssuerRefsName - label: - text: labels.name - required: returnFalse - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/tls/properties/issuerRef/properties/name - type: select - label: - text: labels.issuer_ref - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/tls/properties/issuerRef - type: single-step-form - - alias: reusable_certificates - chart: - name: uibytebuildersdev-component-certificates - version: v0.29.0 - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/tls/properties/certificates - type: reusable-element - if: showTlsConfigureSection - type: single-step-form - type: single-step-form - id: tls - if: isSecurityEnabled - title: steps.3.label -- form: + - text: BackupConfig + value: BackupConfig + description: 'Create, Delete or Modify BackupConfig' + - text: BackupBlueprint + value: BackupBlueprint + description: Enable/Disable BackupBlueprint + if: + type: function + name: isBackupDataLoadedTrue + init: + type: func + value: setBackupType + loader: getTypes + watcher: + func: onBackupTypeChange + paths: + - temp/properties/backupType + - type: block-layout + label: Config + if: + type: function + name: isBackupType|BackupConfig + elements: + - type: select + label: Select Context + schema: temp/properties/backupConfigContext + validation: + type: required + loader: getContext + watcher: + func: onContextChange + paths: + - temp/properties/backupConfigContext + - type: select + label: Select BackupConfig + schema: temp/properties/config + validation: + type: required + if: + type: function + name: showConfigList + loader: getConfigList + watcher: + func: onConfigChange + paths: + - temp/properties/config + - type: input + label: Schedule + schema: temp/properties/schedule + validation: + type: required + if: + type: function + name: showSchedule + loader: + name: getDefaultSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions + watchPaths: + - temp/properties/config + watcher: + func: onInputChangeSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions|schedule + paths: + - temp/properties/schedule + - type: switch + label: Paused + fullwidth: true + schema: schema/properties/resources/properties/coreKubestashComBackupConfiguration/properties/spec/properties/paused + if: + type: function + name: showPause + watcher: + func: setPausedValue + paths: + - temp/properties/config + init: + type: func + value: setPausedValue + - type: block-layout + label: Blueprint + if: + type: function + name: isBackupType|BackupBlueprint + elements: + - type: switch + label: Enable Backup Blueprint + fullwidth: true + subtitle: Use a backup blueprint template to automatically configure backups for similar databases + schema: temp/properties/blueprintEnabled + init: + type: func + value: setBlueprintSwitch + watcher: + func: onBlueprintChange + paths: + - temp/properties/blueprintEnabled + - type: block-layout + label: Archiver + if: + type: function + name: isBackupType|Archiver + elements: + - type: switch + label: Enable Archiver + fullwidth: true + schema: temp/properties/archiverEnabled + init: + type: func + value: setArchiverSwitch + watcher: + func: onArchiverChange + paths: + - temp/properties/archiverEnabled + + - type: single-step-form + id: monitoring + loader: initMonitoring elements: - - disabled: disableInitializationSection - discriminator: - prePopulateDatabase: - type: string + - type: label-element + label: To update Exporter Resource section click on Create OpsRequest + - type: anchor + label: Create OpsRequest + schema: temp/properties/opsRequestUrl + init: + type: func + value: getOpsRequestUrl|scale-vertically + - type: switch + label: Enable Monitoring + fullwidth: true + schema: temp/properties/enableMonitoring + init: + type: func + value: isValueExistInModel|/resources/kubedbComElasticsearch/spec/monitor + watcher: + func: onEnableMonitoringChange + paths: + - temp/properties/enableMonitoring + - type: block-layout + if: + type: function + name: showMonitoringSection elements: - - computed: initPrePopulateDatabase - 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 + - type: radio + label: Select a Monitoring Method + schema: schema/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/monitor/properties/agent + isHorizontal: true 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 + - text: Prometheus Operator + value: prometheus.io/operator + description: Inject metric exporter sidecar and creates a ServiceMonitor + - text: Custom ServiceMonitor + value: prometheus.io + description: Injects the metric exporter sidecar and let you customize ServiceMonitor + - text: Custom Scrapper + value: prometheus.io/builtin + description: Inject metric exporter sidecar and add Prometheus annotations to the stats Service + init: + type: static + value: prometheus.io/operator + watcher: + func: onAgentChange + paths: + - schema/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/monitor/properties/agent + - type: block-layout + label: ServiceMonitor Configuration + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComElasticsearch/spec/monitor/agent elements: - - label: - text: labels.script.path - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/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/kubedbComElasticsearch/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/kubedbComElasticsearch/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 + - label: Scrapping Interval + schema: schema/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval + type: input + - type: block-layout + label: Service Monitor + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComElasticsearch/spec/monitor/agent + elements: + - type: array-object-form + label: Endpoints + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/endpoints 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.29.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 + - type: switch + label: Honor labels + fullwidth: true + schema: honorLabels + - type: input + label: Interval + schema: interval + validation: + type: required + - type: input + label: Path + schema: path + validation: + type: required + - type: input + label: Port + schema: port + validation: + type: required + - type: select + multiple: true + label: Match Namespaces + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/namespaceSelector/properties/matchNames + loader: getResources|core|v1|namespaces + if: + type: function + name: returnFalse + - type: block-layout + showLabels: false + # schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector + if: + type: function + name: returnFalse 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.29.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/kubedbComElasticsearch/properties/spec/properties/init/properties/waitForInitialRestore - type: switch - if: showInitializationForm - type: single-step-form - type: single-step-form - type: single-step-form - id: initialization - title: steps.4.label -- form: - discriminator: - repoInitialSelectionStatus: - type: string - scheduleBackup: - default: "yes" - type: string - elements: - - computed: initScheduleBackupForEdit - if: showScheduleBackup - 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: - backupType: - type: string - isBackupDataLoaded: - default: false - type: boolean - elements: - - computed: initBackupData - if: returnFalse - type: input - - computed: setBackupType - fetch: getTypes - hasDescription: true - if: isBackupDataLoadedTrue - label: - text: Select Backup Type - onChange: onBackupTypeChange - schema: - $ref: discriminator#/backupType - type: radio - - discriminator: - backupConfigContext: - type: string - config: - type: string - paused: - default: false - type: boolean - schedule: - type: string - elements: - - fetch: getContext - label: - text: Select Context - onChange: onContextChange - required: true - schema: - $ref: discriminator#/backupConfigContext - type: select - - fetch: getConfigList - if: showConfigList - label: - text: Select BackupConfig - onChange: onConfigChange - required: true - schema: - $ref: discriminator#/config - type: select - - computed: getDefaultSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions - if: showSchedule - label: - text: Schedule - onChange: onInputChangeSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions|schedule - required: true - schema: - $ref: discriminator#/schedule - type: input - - if: showPause - label: - text: Paused - schema: - $ref: schema#/properties/resources/properties/coreKubestashComBackupConfiguration/properties/spec/properties/paused - type: switch - if: isBackupType|BackupConfig - type: single-step-form - - discriminator: - blueprintEnabled: - default: false - type: boolean - elements: - - computed: setBlueprintSwitch - label: - text: Enable Backup Blueprint - onChange: onBlueprintChange - schema: - $ref: discriminator#/blueprintEnabled - type: switch - if: isBackupType|BackupBlueprint - type: single-step-form - - discriminator: - archiverEnabled: - default: false - type: boolean - elements: - - computed: setArchiverSwitch - label: - text: Enable Archiver - onChange: onArchiverChange - schema: - $ref: discriminator#/archiverEnabled - type: switch - if: isBackupType|Archiver - type: single-step-form - if: showBackupForm - label: - text: Backup Form - type: single-step-form - type: single-step-form - id: backupconfiguration - title: steps.5.label -- form: - discriminator: - enableMonitoring: - default: true - type: boolean - elements: - - label: - text: labels.to_update_exporter_resources - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - function: getOpsRequestUrl|VerticalScaling - - computed: isValueExistInModel|/resources/kubedbComElasticsearch/spec/monitor - 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/kubedbComElasticsearch/properties/spec/properties/monitor/properties/agent - type: radio - - elements: - - label: - text: labels.scrapping_interval - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval - type: input - if: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComElasticsearch/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: object-item + label: Labels + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector/properties/matchLabels + - type: object-item + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/metadata/properties/labels + label : Labels + buttonClass: is-light is-outlined + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComElasticsearch/spec/monitor/agent + # individualItemDisabilityCheck: disableLableChecker + - type: label-element + label: Exporter Configuration + schema: '' + - type: switch + label: Customize Exporter Sidecar + fullwidth: true + schema: temp/properties/customizeExporter + init: + type: static + value: true + watcher: + func: onCustomizeExporterChange + paths: + - temp/properties/customizeExporter + - type: block-layout + label: Customer Exporter Section + showLabels: false + loader: setMetadata + if: + type: function + name: showCustomizeExporterSection + elements: + - type: machine-compare + label: Resources + schema: schema/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/resources + if: + type: function + name: returnFalse + - type: label-element + label: Security Context + schema: '' + - type: input + schema: schema/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsUser + label: Run as User + - type: input + schema: schema/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup + label: Run as Group + - type: input + schema: schema/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/port + label: Port + - type: array-item-form + label: Args + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args + init: + type: static + value: ['--compatible-mode'] + element: 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/kubedbComElasticsearch/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/kubedbComElasticsearch/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: - - if: returnFalse - label: - text: labels.resources - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/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/kubedbComElasticsearch/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/kubedbComElasticsearch/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup - type: input - - label: - text: labels.port - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/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/kubedbComElasticsearch/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args/items - type: input - label: - text: labels.args - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args - type: list-input-form - - alias: reusable_env - chart: - name: uibytebuildersdev-component-env - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/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.6.label -- form: - elements: - - alias: pod_template_standalone - chart: - name: uibytebuildersdev-component-pod-template - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - topology: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/topology - functionCallbacks: - isEditWizard: - $ref: functions#/returnTrue - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/podTemplate - type: reusable-element - type: single-step-form - id: pod-template - title: steps.7.label -- form: - elements: - - alias: reusable_service_templates - chart: - name: uibytebuildersdev-component-service-templates - version: v0.29.0 - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/serviceTemplates - type: reusable-element - type: single-step-form - id: networking - title: steps.8.label -- form: - elements: - - discriminator: - setCustomConfig: - type: string - elements: - - computed: initSetCustomConfig - 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: - configFiles: - type: string - configurationSource: - default: use-existing-config - type: string - elements: - - computed: setConfigurationSource - label: - text: labels.custom_config_type - 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/kubedbComElasticsearch/properties/spec/properties/configSecret/properties/name - type: select - - addFormLabel: labels.config_file - computed: setConfigFiles - element: - discriminator: - files: - emitAs: configFiles - type: array - elements: - - label: - text: labels.filename - required: true - schema: - $ref: discriminator#/properties/files/items/properties/key - type: input - - label: - text: labels.labels.value - required: true - schema: - $ref: discriminator#/properties/files/items/properties/value - type: editor - type: single-step-form - if: isEqualToDiscriminatorPath|create-new-config|/configurationSource - label: - text: labels.config_files - onChange: onConfigFilesChange - schema: - $ref: discriminator#/properties/configFiles - tableContents: - - inTableColumn: true - label: - text: labels.filename - path: key - type: value - typeOfValue: string - - label: - text: labels.labels.value - path: value - type: value - typeOfValue: code - type: single-step-form-array - if: isDiscriminatorEqualTo|/setCustomConfig|yes - type: single-step-form - type: single-step-form - type: single-step-form - id: custom-config - title: steps.9.label -- form: + label: Args + # isSubsection: true + - type: block-layout + label: Metadata + showLabels: false + elements: + - type: array-object-form + init: + type: func + value: initEnvArray + label: Environment Variables + buttonClass: is-light is-outlined + watcher: + func: onEnvArrayChange + paths: + - temp/properties/env + schema: temp/properties/env + elements: + - type: input + label: Name + schema: name + validation: + type: required + - type: radio + label: Value From + schema: temp/properties/valueFromType + validation: + type: required + init: + type: func + value: setValueFrom + options: + - text: Input + value: input + - text: Secret + value: secret + - text: ConfigMap + value: configMap + watcher: + func: onValueFromChange + paths: + - temp/properties/valueFromType + - type: input + label: Value + schema: value + validation: + type: required + if: + name: isEqualToTemp|input + type: function + - type: select + if: + type: function + name: isEqualToTemp|configMap + label: ConfigMap Name + schema: valueFrom/properties/configMapKeyRef/properties/name + loader: + name: resourceNames|core|v1|configmaps + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: ConfigMap Key + schema: valueFrom/properties/configMapKeyRef/properties/key + if: + type: function + name: isEqualToTemp|configMap + loader: + name: getConfigMapKeys + watchPaths: + - schema/resources/kubedbComElasticsearch/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/configMapKeyRef/name + - schema/metadata/release/namespace + - type: select + label: Secret Name + schema: valueFrom/properties/secretKeyRef/properties/name + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecrets + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: Secret Key + schema: valueFrom/properties/secretKeyRef/properties/key + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecretKeys + watchPaths: + - schema/resources/kubedbComElasticsearch/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/secretKeyRef/name + - schema/metadata/release/namespace + + + - type: single-step-form + id: compute-autoscaler + loader: getDbDetails elements: - - discriminator: - setSecretCustomConfig: - type: string + - type: block-layout + showLabels: false + loader: fetchTopologyMachines elements: - - computed: initSetSecureCustomConfig - label: - text: labels.setSecretCustomConfig - onChange: onSetSecretCustomConfigChange - options: - - text: options.yesOrNo.yes.text - value: "yes" - - text: options.yesOrNo.no.text - value: "no" - schema: - $ref: discriminator#/properties/setSecretCustomConfig - type: radio - - discriminator: - configFiles: - type: string - configurationSource: - default: use-existing-config - type: string - elements: - - computed: setSecretConfigurationSource - label: - text: labels.secret_custom_config_type - onChange: onSecretConfigurationSourceChange - 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/kubedbComElasticsearch/properties/spec/properties/secureConfigSecret/properties/name - type: select - - addFormLabel: labels.config_file - computed: setSecretConfigFiles - element: - discriminator: - files: - emitAs: configFiles - type: array - elements: - - label: - text: labels.settings_key - required: true - schema: - $ref: discriminator#/properties/files/items/properties/key - type: input - - label: - text: labels.settings_value - required: true - schema: - $ref: discriminator#/properties/files/items/properties/value - type: editor - type: single-step-form - if: isEqualToDiscriminatorPath|create-new-config|/configurationSource - label: - text: labels.config_files - onChange: onSecretConfigFilesChange - schema: - $ref: discriminator#/properties/configFiles - tableContents: - - inTableColumn: true - label: - text: labels.settings_key - path: key - type: value - typeOfValue: string - - label: - text: labels.settings_value - path: value - type: value - typeOfValue: code - type: single-step-form-array - if: isDiscriminatorEqualTo|/setSecretCustomConfig|yes - type: single-step-form - type: single-step-form - type: single-step-form - id: secure-custom-config - if: showSecureCustomConfig - title: steps.12.label -- form: - discriminator: - dbDetails: - default: false - type: boolean + # Node mode (Combined) + - type: switch + label: Trigger + fullwidth: true + if: + type: function + name: dbTypeEqualsTo|node + init: + type: func + value: setTrigger|autoscalingKubedbComElasticsearchAutoscaler/spec/compute/node/trigger + schema: temp/properties/compute/properties/node/properties/trigger + watcher: + func: onTriggerChange|compute/node + paths: + - temp/properties/compute/properties/node/properties/trigger + - type: label-element + label: Pod lifetime threshold + subtitle: Specifies the duration a pod can exist before using considered for scaling decisions, ensuring resource optimization and workload stability + if: + type: function + name: dbTypeEqualsTo|node + - type: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/node/properties/podLifeTimeThreshold + customClass: width-300 + if: + type: function + name: dbTypeEqualsTo|node + - type: block-layout + label: Node + if: + type: function + name: dbTypeEqualsTo|node + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/node + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/node/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-node-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|node|min + loader: + name: getMachines|node|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-node-max + watcher: + func: onMachineChange|node + paths: + - temp/properties/allowedMachine-node-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/node/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/node/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-node-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|node|max + loader: + name: getMachines|node|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-node-min + watcher: + func: onMachineChange|node + paths: + - temp/properties/allowedMachine-node-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/node/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/node/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|compute/node + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/node/properties/controlledResources + + # Topology mode + - type: block-layout + showLabels: false + if: + type: function + name: dbTypeEqualsTo|topology + elements: + # Data + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComElasticsearchAutoscaler/spec/compute/data/trigger + schema: temp/properties/compute/properties/data/properties/trigger + watcher: + func: onTriggerChange|compute/data + paths: + - temp/properties/compute/properties/data/properties/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/data/properties/podLifeTimeThreshold + customClass: width-300 + - type: block-layout + label: Data + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/data + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/data/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-data-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|data|min + loader: + name: getMachines|data|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-data-max + watcher: + func: onMachineChange|data + paths: + - temp/properties/allowedMachine-data-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/data/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/data/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-data-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|data|max + loader: + name: getMachines|data|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-data-min + watcher: + func: onMachineChange|data + paths: + - temp/properties/allowedMachine-data-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/data/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/data/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|compute/data + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/data/properties/controlledResources + + # Ingest + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComElasticsearchAutoscaler/spec/compute/ingest/trigger + schema: temp/properties/compute/properties/ingest/properties/trigger + watcher: + func: onTriggerChange|compute/ingest + paths: + - temp/properties/compute/properties/ingest/properties/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/ingest/properties/podLifeTimeThreshold + customClass: width-300 + - type: block-layout + label: Ingest + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/ingest + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/ingest/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-ingest-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|ingest|min + loader: + name: getMachines|ingest|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-ingest-max + watcher: + func: onMachineChange|ingest + paths: + - temp/properties/allowedMachine-ingest-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/ingest/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/ingest/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-ingest-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|ingest|max + loader: + name: getMachines|ingest|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-ingest-min + watcher: + func: onMachineChange|ingest + paths: + - temp/properties/allowedMachine-ingest-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/ingest/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/ingest/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|compute/ingest + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/ingest/properties/controlledResources + + # Master + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComElasticsearchAutoscaler/spec/compute/master/trigger + schema: temp/properties/compute/properties/master/properties/trigger + watcher: + func: onTriggerChange|compute/master + paths: + - temp/properties/compute/properties/master/properties/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/master/properties/podLifeTimeThreshold + customClass: width-300 + - type: block-layout + label: Master + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/master + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/master/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-master-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|master|min + loader: + name: getMachines|master|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-master-max + watcher: + func: onMachineChange|master + paths: + - temp/properties/allowedMachine-master-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/master/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/master/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-master-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|master|max + loader: + name: getMachines|master|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-master-min + watcher: + func: onMachineChange|master + paths: + - temp/properties/allowedMachine-master-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/master/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/master/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|compute/master + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/master/properties/controlledResources + + - type: block-layout + label: NodeTopology + if: + type: function + name: hasNoAnnotations + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/nodeTopology + elements: + - type: select + label: Select NodeTopology + loader: fetchNodeTopology + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name + - type: threshold-input + label: Scale Up DiffPercentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage + - type: threshold-input + label: Scale Down DiffPercentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + # schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/opsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: storage-autoscaler + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: SelectDb - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: SelectType - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - discriminator: - topologyMachines: - default: [] - type: array + - type: block-layout + showLabels: false elements: - - fetch: fetchTopologyMachines - if: returnFalse - schema: - $ref: discriminator#/topologyMachines - type: input - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComElasticsearchAutoscaler/spec/compute/node/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/node/properties/trigger - type: select - - label: - text: PodLifeTimeThreshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/node/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/node/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-node-max: - type: string - allowedMachine-node-min: - type: string - elements: - - computed: setAllowedMachine|node|min - disableUnselect: true - fetch: getMachines|node|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|node - schema: - $ref: discriminator#/properties/allowedMachine-node-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/node/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/node/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/node/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|node|max - disableUnselect: true - fetch: getMachines|node|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|node - schema: - $ref: discriminator#/properties/allowedMachine-node-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/node/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/node/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/node/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|node - label: - text: controlledResources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/node/properties/controlledResources - type: multiselect - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/node - type: single-step-form - if: dbTypeEqualsTo|node - label: - text: Node - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/node - show_label: true - type: single-step-form - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComElasticsearchAutoscaler/spec/compute/data/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/data/properties/trigger - type: select - - label: - text: PodLifeTimeThreshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/data/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/data/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-data-max: - type: string - allowedMachine-data-min: - type: string - elements: - - computed: setAllowedMachine|data|min - disableUnselect: true - fetch: getMachines|data|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|data - schema: - $ref: discriminator#/properties/allowedMachine-data-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/data/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/data/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/data/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|data|max - disableUnselect: true - fetch: getMachines|data|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|data - schema: - $ref: discriminator#/properties/allowedMachine-data-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/data/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/data/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/data/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|data - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/data/properties/controlledResources - type: multiselect - label: - text: Data - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/data - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComElasticsearchAutoscaler/spec/compute/ingest/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/ingest/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/ingest/properties/podLifeTimeThreshold - type: input - - label: - text: ResourceDiffPercentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/ingest/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-ingest-max: - type: string - allowedMachine-ingest-min: - type: string - elements: - - computed: setAllowedMachine|ingest|min - disableUnselect: true - fetch: getMachines|ingest|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|ingest - schema: - $ref: discriminator#/properties/allowedMachine-ingest-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/ingest/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/ingest/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/ingest/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|ingest|max - disableUnselect: true - fetch: getMachines|ingest|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|ingest - schema: - $ref: discriminator#/properties/allowedMachine-ingest-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/ingest/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/ingest/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/ingest/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|ingest - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/ingest/properties/controlledResources - type: multiselect - label: - text: Ingest - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/ingest - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComElasticsearchAutoscaler/spec/compute/master/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/master/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/master/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/master/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-master-max: - type: string - allowedMachine-master-min: - type: string - elements: - - computed: setAllowedMachine|master|min - disableUnselect: true - fetch: getMachines|master|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|master - schema: - $ref: discriminator#/properties/allowedMachine-master-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/master/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/master/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/master/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|master|max - disableUnselect: true - fetch: getMachines|master|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|master - schema: - $ref: discriminator#/properties/allowedMachine-master-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/master/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/master/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/master/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|master - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/master/properties/controlledResources - type: multiselect - label: - text: Master - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/master - show_label: true - type: single-step-form - if: dbTypeEqualsTo|topology - type: single-step-form - - elements: - - fetch: fetchNodeTopology - label: - text: Select NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name - type: select - - if: isNodeTopologySelected - label: - text: ScaleUp Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage - type: input - - if: isNodeTopologySelected - label: - text: ScaleDown Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage - type: input - if: hasNoAnnotations - label: - text: nodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/nodeTopology - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: OpsRequest Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: compute-autoscaler - title: steps.13.label -- form: - discriminator: - dbDetails: - default: false - type: boolean - elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: SelectDb - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: SelectType - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComElasticsearchAutoscaler/spec/storage/node/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/node/properties/trigger - type: select - - label: - text: Expansion Mode + # Node mode (Combined) + - type: switch + label: Trigger + fullwidth: true + if: + type: function + name: dbTypeEqualsTo|node + init: + type: func + value: setTrigger|autoscalingKubedbComElasticsearchAutoscaler/spec/storage/node/trigger + schema: temp/properties/storage/properties/node/properties/trigger + watcher: + func: onTriggerChange|storage/node + paths: + - temp/properties/storage/properties/node/properties/trigger + - type: label-element + 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. + if: + type: function + name: dbTypeEqualsTo|node + - type: select + label: Mode + description: Select how the storage expansion should be handled. + if: + type: function + name: dbTypeEqualsTo|node options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/node/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/node/properties/usageThreshold - type: input - - addFormLabel: ScalingRules - element: - elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/node/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/node/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComElasticsearchAutoscaler/spec/storage/node/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/node/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComElasticsearchAutoscaler/spec/storage/node/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/node/properties/upperBound - type: input - if: dbTypeEqualsTo|node - label: - text: Node - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/compute/properties/node - show_label: true - type: single-step-form - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComElasticsearchAutoscaler/spec/storage/data/trigger - label: - text: trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/data/properties/trigger - type: select - - label: - text: Expansion Mode - options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/data/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/data/properties/usageThreshold - type: input - - addFormLabel: ScalingRules - element: + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/node/properties/expansionMode + - type: block-layout + label: Node + if: + type: function + name: dbTypeEqualsTo|node + showLabels: true + elements: + - type: threshold-input + label: UsageThreshold (%) + subtitle: Set the threshold percentage of storage usage to trigger scaling. + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/node/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/node/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComElasticsearch/spec/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComElasticsearchAutoscaler/spec/storage/node/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/node/properties/scalingRules + + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/node/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComElasticsearchAutoscaler/spec/storage/node/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/node/properties/upperBound + + # Topology mode + - type: block-layout + showLabels: false + if: + type: function + name: dbTypeEqualsTo|topology + elements: + # Data + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComElasticsearchAutoscaler/spec/storage/data/trigger + schema: temp/properties/storage/properties/data/properties/trigger + watcher: + func: onTriggerChange|storage/data + paths: + - temp/properties/storage/properties/data/properties/trigger + - type: label-element + 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: select + label: Mode + description: Select how the storage expansion should be handled. + options: + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/data/properties/expansionMode + - type: block-layout + label: Data + showLabels: true elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/data/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/data/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComElasticsearchAutoscaler/spec/storage/data/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/data/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComElasticsearchAutoscaler/spec/storage/data/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/data/properties/upperBound - type: input - label: - text: Data - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/data - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComElasticsearchAutoscaler/spec/storage/ingest/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/ingest/properties/trigger - type: select - - label: - text: Expansion Mode - options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/ingest/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/ingest/properties/usageThreshold - type: input - - addFormLabel: ScalingRules - element: + - type: threshold-input + label: UsageThreshold (%) + subtitle: Set the threshold percentage of storage usage to trigger scaling. + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/data/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/data/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComElasticsearch/spec/topology/data/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComElasticsearchAutoscaler/spec/storage/data/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/data/properties/scalingRules + + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/data/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComElasticsearchAutoscaler/spec/storage/data/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/data/properties/upperBound + + # Ingest + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComElasticsearchAutoscaler/spec/storage/ingest/trigger + schema: temp/properties/storage/properties/ingest/properties/trigger + watcher: + func: onTriggerChange|storage/ingest + paths: + - temp/properties/storage/properties/ingest/properties/trigger + - type: label-element + 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: select + label: Mode + description: Select how the storage expansion should be handled. + options: + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/ingest/properties/expansionMode + - type: block-layout + label: Ingest + showLabels: true elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/ingest/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/ingest/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComElasticsearchAutoscaler/spec/storage/ingest/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/ingest/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComElasticsearchAutoscaler/spec/storage/ingest/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/ingest/properties/upperBound - type: input - label: - text: Ingest - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/ingest - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComElasticsearchAutoscaler/spec/storage/master/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/master/properties/trigger - type: select - - label: - text: Expansion Mode - options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/master/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/master/properties/usageThreshold - type: input - - addFormLabel: ScalingRules - element: + - type: threshold-input + label: UsageThreshold (%) + subtitle: Set the threshold percentage of storage usage to trigger scaling. + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/ingest/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/ingest/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComElasticsearch/spec/topology/ingest/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComElasticsearchAutoscaler/spec/storage/ingest/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/ingest/properties/scalingRules + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/ingest/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComElasticsearchAutoscaler/spec/storage/ingest/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/ingest/properties/upperBound + + # Master + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComElasticsearchAutoscaler/spec/storage/master/trigger + schema: temp/properties/storage/properties/master/properties/trigger + watcher: + func: onTriggerChange|storage/master + paths: + - temp/properties/storage/properties/master/properties/trigger + - type: label-element + 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: select + label: Mode + description: Select how the storage expansion should be handled. + options: + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/master/properties/expansionMode + - type: block-layout + label: Master + showLabels: true elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/master/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/master/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComElasticsearchAutoscaler/spec/storage/master/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/master/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComElasticsearchAutoscaler/spec/storage/master/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/master/properties/upperBound - type: input - label: - text: Master - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/master - show_label: true - type: single-step-form - if: dbTypeEqualsTo|topology - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: OpsRequest Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: storage-autoscaler - title: steps.0.label -- form: - discriminator: - binding: - default: false - type: boolean + - type: threshold-input + label: UsageThreshold (%) + subtitle: Set the threshold percentage of storage usage to trigger scaling. + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/master/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/master/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComElasticsearch/spec/topology/master/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComElasticsearchAutoscaler/spec/storage/master/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/master/properties/scalingRules + + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/master/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComElasticsearchAutoscaler/spec/storage/master/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/storage/properties/master/properties/upperBound + + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComElasticsearchAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: binding elements: - - computed: isBindingAlreadyOn - label: - text: Expose Database - onChange: addOrRemoveBinding - schema: - $ref: discriminator#/properties/binding - type: switch - type: single-step-form - id: binding - title: Gateway Binding -type: multi-step-form + - type: switch + label: Expose Database + schema: temp/properties/binding + fullwidth: true + init: + type: func + value: isBindingAlreadyOn + watcher: + func: addOrRemoveBinding + paths: + - temp/properties/binding diff --git a/charts/kubedbcom-elasticsearch-editor/ui/functions.js b/charts/kubedbcom-elasticsearch-editor/ui/functions.js index 06318c21bc..24cc1f9659 100644 --- a/charts/kubedbcom-elasticsearch-editor/ui/functions.js +++ b/charts/kubedbcom-elasticsearch-editor/ui/functions.js @@ -1,3573 +1,1518 @@ -// ************************* common functions ******************************************** -// eslint-disable-next-line no-empty-pattern -async function fetchJsons({ axios, itemCtx, setDiscriminatorValue }, discriminatorPath) { - 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) - } - - if (discriminatorPath) { - setDiscriminatorValue(discriminatorPath, { - ui: ui.data || {}, - language: language.data || {}, - functions, - }) +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + +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', true) + setDiscriminatorValue('/customizeExporter', true) + setDiscriminatorValue('/valueFromType', 'input') + setDiscriminatorValue('/env', []) + + // Compute Autoscaler Discriminators + setDiscriminatorValue('/dbDetails', false) + setDiscriminatorValue('/topologyMachines', []) + setDiscriminatorValue('/allowedMachine-node-min', '') + setDiscriminatorValue('/allowedMachine-node-max', '') + setDiscriminatorValue('/allowedMachine-master-min', '') + setDiscriminatorValue('/allowedMachine-master-max', '') + setDiscriminatorValue('/allowedMachine-data-min', '') + setDiscriminatorValue('/allowedMachine-data-max', '') + setDiscriminatorValue('/allowedMachine-ingest-min', '') + setDiscriminatorValue('/allowedMachine-ingest-max', '') + + // ************************* Common Helper Functions ******************************************** + + function objectCopy(obj) { + const temp = JSON.stringify(obj) + return JSON.parse(temp) + } + + function valueExists(value, getValue, path) { + const val = getValue(value, path) + if (val) return true + else return false } - return { - ui: ui.data || {}, - language: language.data || {}, - functions, + function returnFalse() { + return false } -} -function disableLableChecker({ itemCtx }) { - const { key } = itemCtx - if (key.startsWith('app.kubernetes.io') || key.includes('helm')) return true - else return false -} + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + return modelPathValue === value + } -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} + function isValueExistInModel(path) { + const modelValue = getValue(model, path) + return !!modelValue + } -async function getResources({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: { filter: { items: { metadata: { name: null } } } }, + // ************************* Backup & Restore Configuration ******************************************** + + const stashAppscodeComBackupConfiguration = { + spec: { + repository: { + name: '', + }, + retentionPolicy: { + keepLast: 5, + name: 'keep-last-5', + prune: true, + }, + schedule: '*/5 * * * *', + target: { + ref: { + apiVersion: 'appcatalog.appscode.com/v1alpha1', + kind: 'AppBinding', + name: '', + }, }, + }, + } + + function getBackupConfigsAndAnnotations(getValue, model) { + const stashAppscodeComBackupConfiguration = getValue( + model, + '/resources/stashAppscodeComBackupConfiguration', ) + const kubedbComElasticsearchAnnotations = + getValue(model, '/resources/kubedbComElasticsearch/metadata/annotations') || {} - const resources = (resp && resp.data && resp.data.items) || [] + const isBluePrint = Object.keys(kubedbComElasticsearchAnnotations).some( + (k) => + k === 'stash.appscode.com/backup-blueprint' || + k === 'stash.appscode.com/schedule' || + k.startsWith('params.stash.appscode.com/'), + ) - 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 [] + return { + stashAppscodeComBackupConfiguration, + isBluePrint, + } } -} -function isEqualToDiscriminatorPath( - { discriminator, getValue, watchDependency }, - value, - discriminatorPath, -) { - watchDependency('discriminator#' + discriminatorPath) - const discriminatorValue = getValue(discriminator, discriminatorPath) - return discriminatorValue === value -} + function deleteKubeDbComElasticsearchDbAnnotation(getValue, model, commit) { + const annotations = + getValue(model, '/resources/kubedbComElasticsearch/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/kubedbComElasticsearch/metadata/annotations', + value: filteredAnnotations, + }) + } -function setValueFromModel({ getValue, model }, path) { - return getValue(model, path) -} + function initScheduleBackupForEdit() { + const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( + getValue, + model, + ) -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + initRepositoryChoiseForEdit() - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' + else return 'no' + } - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }) + function initScheduleBackup() { + const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( + getValue, + model, + ) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' + else return 'no' } - return ans -} + function onScheduleBackupChange() { + const scheduleBackup = getValue(discriminator, '/scheduleBackup') -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + if (scheduleBackup === 'no') { + // delete stashAppscodeComBackupConfiguration + commit('wizard/model$delete', '/resources/stashAppscodeComBackupConfiguration') + commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') + // delete annotation from kubedbComElasticsearch annotation + deleteKubeDbComElasticsearchDbAnnotation(getValue, model, commit) + } else { + const { isBluePrint } = getBackupConfigsAndAnnotations(getValue, model) - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` + // create stashAppscodeComBackupConfiguration and initialize it if not exists - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }) + const dbName = getValue(model, '/metadata/release/name') - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + 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, + }) + } + } } - return ans -} + function showBackupForm() { + const scheduleBackup = getValue(discriminator, '/scheduleBackup') + if (scheduleBackup === 'yes') return true + else return false + } -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - 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) - }) + function showScheduleBackup() { + const operationQuery = storeGet('/route/params/actions') || '' + const isBackupOperation = operationQuery === 'edit-self-backupconfiguration' ? true : false + return !isBackupOperation } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + function initRepositoryChoiseForEdit() { + const stashAppscodeComRepository_repo = getValue( + model, + '/resources/stashAppscodeComRepository_repo', + ) + const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' + setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) - - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) + return repoInitialSelectionStatus } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + function getDefaultSchedule(modelPath) { + const config = getValue(discriminator, '/config') + const session = getValue(model, modelPath) + return session?.length ? session[0]?.scheduler.schedule : '' + } + + 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 returnTrue() { - return true -} + // ************************* New Backup Data Management (KubeStash) ******************************************** + + 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/kubedbComElasticsearch') + initialDbMetadata = objectCopy(dbResource.metadata) + initialArchiver = dbResource.spec?.archiver ? objectCopy(dbResource.spec?.archiver) : undefined -function returnStringYes() { - return 'yes' -} + // 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 -function isDedicatedModeSelected({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComElasticsearch/spec/topology') - isDedicatedSelected = getValue(model, '/resources/kubedbComElasticsearch/spec/topology') + let url = `/clusters/${user}/${cluster}/helm/packageview/values?name=${chartName}&sourceApiGroup=${sourceApiGroup}&sourceKind=${sourceKind}&sourceNamespace=${sourceNamespace}&sourceName=${sourceName}&version=${chartVersion}&format=json` - return !!isDedicatedSelected -} + if (spoke) + url = `/clusters/${user}/${spoke}/helm/packageview/values?name=${chartName}&sourceApiGroup=${sourceApiGroup}&sourceKind=${sourceKind}&sourceNamespace=${sourceNamespace}&sourceName=${sourceName}&version=${chartVersion}&format=json` -function isCombinedModeSelected({ model, getValue, watchDependency }) { - return !isDedicatedSelected({ model, getValue, watchDependency }) -} + const resp = await axios.get(url) + + valuesFromWizard = objectCopy(resp.data?.resources?.coreKubestashComBackupConfiguration) || {} + } catch (e) { + console.log(e) + } -function isDiscriminatorEqualTo( - { discriminator, getValue, watchDependency }, - discriminatorPath, - value, -) { - watchDependency('discriminator#' + discriminatorPath) - const pathValue = getValue(discriminator, discriminatorPath) + // 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) + } + } - return value === pathValue -} + // 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, + ) -function isAuthPluginNotSearchGuard({ discriminator, getValue, watchDependency, commit }) { - watchDependency('discriminator#/selectedVersionAuthPlugin') - const pathValue = getValue(discriminator, '/selectedVersionAuthPlugin') + // 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, + ) - if (!pathValue) return false + // set backup switch here + isBackupOn = !!config - const ret = pathValue !== 'SearchGuard' && pathValue !== '' + // set initial data from stash-presets + const stashPreset = storeGet('/backup/stashPresets') + if (stashPreset) { + const { retentionPolicy, encryptionSecret, schedule, storageRef } = stashPreset - if (!ret) { - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/topology/dataWarm') - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/topology/dataHot') - } - return ret -} + const tempBackends = valuesFromWizard.spec?.backends + tempBackends[0]['storageRef'] = storageRef + tempBackends[0]['retentionPolicy'] = retentionPolicy + valuesFromWizard.spec['backends'] = tempBackends -// required for outer form section. where discriminator can not be saved -async function showInternalUsersAndRolesMapping({ - model, - getValue, - watchDependency, - axios, - storeGet, - setDiscriminatorValue, - commit, -}) { - watchDependency('model#/resources/kubedbComElasticsearch/spec/disableSecurity') - watchDependency('model#/resources/kubedbComElasticsearch/spec/version') - - const dist = await getSelectedVersionAuthPlugin({ - model, - getValue, - watchDependency, - axios, - storeGet, - setDiscriminatorValue, - }) + 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}` - const ret = - (dist === 'OpenDistro' || dist === 'SearchGuard') && - isSecurityEnabled({ model, getValue, watchDependency }) + tempSessions[0]['repositories'] = tempRepositories + tempSessions[0]['scheduler']['schedule'] = schedule + valuesFromWizard.spec['sessions'] = tempSessions + } - if (ret) { - commit('wizard/showSteps$update', { - stepId: 'internal-users', - show: true, - }) + 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, + } - commit('wizard/showSteps$update', { - stepId: 'roles-mapping', - show: true, - }) - } else { - commit('wizard/showSteps$update', { - stepId: 'internal-users', - show: false, - }) + setDiscriminatorValue('isBackupDataLoaded', true) + } - commit('wizard/showSteps$update', { - stepId: 'roles-mapping', - show: false, - }) + function isBackupDataLoadedTrue() { + return !!getValue(discriminator, '/isBackupDataLoaded') } - return ret -} -// required for outer form section. where discriminator can not be saved -async function showSecureCustomConfig({ - model, - getValue, - watchDependency, - axios, - storeGet, - setDiscriminatorValue, - commit, -}) { - watchDependency('model#/resources/kubedbComElasticsearch/spec/version') - - const dist = await getSelectedVersionAuthPlugin({ - model, - getValue, - watchDependency, - axios, - storeGet, - setDiscriminatorValue, - }) + 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', + }, + ] - const ret = dist === 'X-Pack' + if (dbResource?.spec?.topology && isArchiverAvailable) { + arr.push({ + description: 'Enable/Disable Archiver', + text: 'Archiver', + value: 'Archiver', + }) + } + return arr + } - if (ret) { - commit('wizard/showSteps$update', { - stepId: 'secure-custom-config', - show: true, + function onBackupTypeChange() { + const type = getValue(discriminator, '/backupType') + commit('wizard/model$update', { + path: '/backupType', + value: type, + force: true, }) - } else { - commit('wizard/showSteps$update', { - stepId: 'secure-custom-config', - show: false, + 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/kubedbComElasticsearch', + value: objectCopy(dbResource), + force: true, }) - - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/secureConfigSecret') - commit('wizard/model$delete', '/resources/secret_secure_config') } - return ret -} -// ************************* Basic Info ********************************************** + function isBackupType(type) { + const selectedType = getValue(discriminator, '/backupType') + return selectedType === type + } -async function getElasticSearchVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function setBlueprintSwitch() { + const annotations = initialDbMetadata?.annotations - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null, authPlugin: null }, - }, - }, + return !!( + annotations['blueprint.kubestash.com/name'] && + annotations['blueprint.kubestash.com/namespace'] + ) } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) + function onBlueprintChange() { + const blueprintSwitch = getValue(discriminator, '/blueprintEnabled') - const resources = (resp && resp.data && resp.data.items) || [] + if (blueprintSwitch) addLabelAnnotation('annotations') + else deleteLabelAnnotation('annotations') + } - // keep only non deprecated versions - const filteredElasticSearchVersions = resources.filter( - (item) => item.spec && !item.spec.deprecated, - ) + function setArchiverSwitch() { + const archiver = dbResource?.spec?.archiver + return !!archiver + } - filteredElasticSearchVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredElasticSearchVersions -} + function onArchiverChange() { + const archiverSwitch = getValue(discriminator, '/archiverEnabled') + const path = 'resources/kubedbComElasticsearch/spec/archiver' + if (archiverSwitch) { + commit('wizard/model$update', { + path: path, + value: initialArchiver ? initialArchiver : archiverObjectToCommit, + }) + } else { + commit('wizard/model$delete', path) + } + } -function isSecurityEnabled({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComElasticsearch/spec/disableSecurity') - const value = getValue(model, '/resources/kubedbComElasticsearch/spec/disableSecurity') - return !value -} + function addLabelAnnotation(type) { + const obj = objectCopy(initialDbMetadata[type]) -function onDisableSecurityChange({ model, getValue, commit }) { - const disableSecurity = getValue(model, '/resources/kubedbComElasticsearch/spec/disableSecurity') + 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' + } - if (disableSecurity) { - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/authSecret') - commit('wizard/model$delete', '/resources/secret_admin_cred') - commit('wizard/model$delete', '/resources/secret_elastic_cred') - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/internalUsers') - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/rolesMapping') - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/tls') + commit('wizard/model$update', { + path: `/resources/kubedbComElasticsearch/metadata/${type}`, + value: obj, + force: true, + }) } -} -async function onVersionChange({ - model, - getValue, - watchDependency, - axios, - storeGet, - commit, - setDiscriminatorValue, -}) { - const dist = await getSelectedVersionAuthPlugin({ - model, - getValue, - watchDependency, - axios, - storeGet, - setDiscriminatorValue, - }) - - const isOpenDistro = dist === 'OpenDistro' - const isSearchGuard = dist === 'SearchGuard' - const isXpack = dist === 'X-Pack' - - if (!isOpenDistro && !isSearchGuard) { - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/internalUsers') - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/rolesMapping') - if (isXpack) { - removeCertificatesOfAliases({ model, getValue, commit }, ['admin']) - } - } else { - if (!isOpenDistro) { - const internalUsers = getValue(model, '/resources/kubedbComElasticsearch/spec/internalUsers') - - if (internalUsers) { - Object.keys(internalUsers).map((key) => { - if (internalUsers[key]?.opendistroSecurityRoles) - delete internalUsers[key]?.opendistroSecurityRoles - }) - } + function deleteLabelAnnotation(type) { + const obj = initialDbMetadata[type] - commit('wizard/model$update', { - path: '/resources/kubedbComElasticsearch/spec/internalUsers', - value: internalUsers, - force: true, - }) - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/topology/dataHot') - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/topology/dataWarm') - } - if (!isSearchGuard) { - const internalUsers = getValue(model, '/resources/kubedbComElasticsearch/spec/internalUsers') + if (type === 'annotations') { + delete obj['blueprint.kubestash.com/name'] + delete obj['blueprint.kubestash.com/namespace'] + } else delete obj['kubedb.com/archiver'] - if (internalUsers) { - Object.keys(internalUsers).map((key) => { - if (internalUsers[key]?.searchGuardRoles) delete internalUsers[key]?.searchGuardRoles - }) - } + commit('wizard/model$update', { + path: `/resources/kubedbComElasticsearch/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/kubedbComElasticsearch/spec/internalUsers', - value: internalUsers, + path: '/resources/coreKubestashComBackupConfiguration', + value: valuesFromWizard, force: true, }) } - - if (!isXpack) { - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/topology/dataCold') - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/topology/dataContent') - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/topology/dataFrozen') - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/topology/ml') - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/topology/transform') - } + if (context === 'Delete') setDiscriminatorValue('hidePreviewFromWizard', true) + else setDiscriminatorValue('hidePreviewFromWizard', undefined) } -} - -function onEnableSSLChange({ model, getValue, commit }) { - const enabelSSL = getValue(model, '/resources/kubedbComElasticsearch/spec/enableSSL') - if (enabelSSL === false) { - removeCertificatesOfAliases({ model, getValue, commit }, [ - 'http', - 'archiver', - 'metrics-exporter', - ]) + 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 removeCertificatesOfAliases({ model, getValue, commit }, aliasesToRemove) { - const certificates = - getValue(model, '/resources/kubedbComElasticsearch/spec/tls/certificates') || [] - const updatedCertificates = certificates.filter((item) => !aliasesToRemove.includes(item.alias)) - commit('wizard/model$update', { - path: '/resources/kubedbComElasticsearch/spec/tls/certificates', - value: updatedCertificates, - force: true, - }) -} + function onConfigChange() { + const configName = getValue(discriminator, '/config') + const configs = objectCopy(backupConfigurationsFromStore) + const configDetails = configs?.find((item) => item?.metadata?.name === configName) -/************************************* Database Secret Section ********************************************/ + commit('wizard/model$update', { + path: '/resources/coreKubestashComBackupConfiguration', + value: configDetails, + force: true, + }) + } -function getCreateAuthSecret({ model, getValue }) { - const authSecret = getValue(model, '/resources/kubedbComElasticsearch/spec/authSecret') + function showPause() { + const contex = getValue(discriminator, '/backupConfigContext') + const configName = getValue(discriminator, '/config') + return !!configName && contex === 'Modify' + } - return !authSecret -} + 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 showExistingSecretSection({ getValue, watchDependency, discriminator }) { - watchDependency('discriminator#/createAuthSecret') + function showConfigList() { + const contex = getValue(discriminator, '/backupConfigContext') + return contex === 'Modify' || contex === 'Delete' + } - const hasAuthSecretName = getValue(discriminator, '/createAuthSecret') - return !hasAuthSecretName -} + function showSchedule() { + 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 showPasswordSection({ getValue, watchDependency, discriminator }) { - return !showExistingSecretSection({ - getValue, - watchDependency, - discriminator, - }) -} + // ************************* Gateway Binding ******************************************** -function setAuthSecretPassword({ model, getValue, watchDependency, discriminator, commit }) { - watchDependency('discriminator#/selectedVersionAuthPlugin') + 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/kubedbComElasticsearch/metadata/labels') + const bindingValues = { + apiVersion: 'catalog.appscode.com/v1alpha1', + kind: 'ElasticsearchBinding', + metadata: { + labels, + name: dbName, + namespace: dbNamespace, + }, + spec: { + sourceRef: { + name: dbName, + namespace: dbNamespace, + }, + }, + } - const dist = getValue(discriminator, '/selectedVersionAuthPlugin') - if (dist) { - if (dist === 'X-Pack') { - const encodedPassword = getValue(model, '/resources/secret_elastic_cred/data/password') - commit('wizard/model$delete', '/resources/secret_admin_cred') - return encodedPassword ? decodePassword({}, encodedPassword) : '' + if (value) { + commit('wizard/model$update', { + path: '/resources/catalogAppscodeComElasticsearchBinding', + value: bindingValues, + force: true, + }) } else { - const encodedPassword = getValue(model, '/resources/secret_admin_cred/data/password') - commit('wizard/model$delete', '/resources/secret_elastic_cred') - return encodedPassword ? decodePassword({}, encodedPassword) : '' + commit('wizard/model$delete', '/resources/catalogAppscodeComElasticsearchBinding') } } -} -function onAuthSecretPasswordChange({ getValue, discriminator, commit }) { - const stringPassword = getValue(discriminator, '/password') - const dist = getValue(discriminator, '/selectedVersionAuthPlugin') + function isBindingAlreadyOn() { + const value = getValue(model, '/resources') + const keys = Object.keys(value) + const isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComElasticsearchBinding') + return isExposeBinding + } - if (dist) { - if (stringPassword) { - if (dist === 'X-Pack') { - commit('wizard/model$update', { - path: '/resources/secret_elastic_cred/data/password', - value: encodePassword({}, stringPassword), - force: true, - }) - commit('wizard/model$update', { - path: '/resources/secret_elastic_cred/data/username', - value: encodePassword({}, 'elastic'), - force: true, - }) - commit('wizard/model$delete', '/resources/secret_admin_cred') - } else { + // ************************* Storage Autoscaling & Unit Handling ******************************************** + + 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/secret_admin_cred/data/password', - value: encodePassword({}, stringPassword), + path: `/resources/${path}`, + value: updatedValue, force: true, }) + } + } else { + if (!isNaN(value)) { + value += 'Gi' commit('wizard/model$update', { - path: '/resources/secret_admin_cred/data/username', - value: encodePassword({}, 'admin'), + path: `/resources/${path}`, + value: value, force: true, }) - commit('wizard/model$delete', '/resources/secret_elastic_cred') } - } else { - commit('wizard/model$delete', '/resources/secret_admin_cred') - commit('wizard/model$delete', '/resources/secret_elastic_cred') } } -} - -// eslint-disable-next-line no-empty-pattern -function encodePassword({}, value) { - return btoa(value) -} - -// eslint-disable-next-line no-empty-pattern -function decodePassword({}, value) { - return atob(value) -} - -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/authSecret') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/resources/secret_admin_cred') - commit('wizard/model$delete', '/resources/secret_elastic_cred') - } -} -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') + // ************************* Compute Autoscaling ******************************************** - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, + let autoscaleType = '' + let dbDetails = {} + let instance = {} + async function getDbDetails() { + const annotations = getValue( + model, + '/resources/autoscalingKubedbComElasticsearchAutoscaler/metadata/annotations', ) + instance = annotations['kubernetes.io/instance-type'] + 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, + '/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/databaseRef/name', + ) || + '' + + if (namespace && name) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/elasticsearches/${name}`, + ) + dbDetails = resp.data || {} + setDiscriminatorValue('/dbDetails', true) + } catch (e) { + console.log(e) + } + } - 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 + commit('wizard/model$update', { + path: `/metadata/release/name`, + value: name, + force: true, + }) + commit('wizard/model$update', { + path: `/metadata/release/namespace`, + value: namespace, + force: true, + }) + commit('wizard/model$update', { + path: `/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/databaseRef/name`, + value: name, + force: true, + }) + commit('wizard/model$update', { + path: `/resources/autoscalingKubedbComElasticsearchAutoscaler/metadata/labels`, + value: dbDetails.metadata?.labels || {}, + force: true, }) - return filteredSecrets - } catch (e) { - console.log(e) - return [] } -} - -function showSecretSection({ model, getValue, watchDependency, storeGet }) { - const steps = storeGet('/wizard/configureOptions') - return ( - !steps.includes('internal-users') && isSecurityEnabled({ model, getValue, watchDependency }) - ) -} + function dbTypeEqualsTo(dbType, type) { + autoscaleType = type + const dbDetailsSuccess = getValue(discriminator, '/dbDetails') -// ********************* Database Mode *********************** -function isNotCombinedMode({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - return mode !== 'Combined' -} + if (!dbDetailsSuccess) return false -function setDatabaseMode({ model, getValue }) { - isDedicatedSelected = getValue(model, '/resources/kubedbComElasticsearch/spec/topology') - if (isDedicatedSelected) { - return 'Dedicated' - } else { - return 'Combined' + const { spec } = dbDetails || {} + const { topology } = spec || {} + let verd = '' + if (topology) verd = 'topology' + else verd = 'node' + clearSpecModel(verd) + return dbType === verd && spec } -} - -let storageClassList = [] -async function getStorageClassNames( - { axios, storeGet, commit, setDiscriminatorValue, getValue, model }, - path, -) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/storage.k8s.io/v1/storageclasses`, - { - params: { - filter: { items: { metadata: { name: null, annotations: 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 - }) - - if (!path) { - setDiscriminatorValue('/storageClasses', resources) + function clearSpecModel(dbtype) { + if (dbtype === 'node') { + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/${autoscaleType}/data`, + ) + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/${autoscaleType}/ingest`, + ) + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/${autoscaleType}/master`, + ) + } else if (dbtype === 'topology') { + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/${autoscaleType}/node`, + ) + } } - storageClassList = resources - const initialStorageClass = getValue(model, path) - if (!initialStorageClass) setStorageClass({ model, getValue, commit }, path) - return resources -} -function setStorageClass({ model, getValue, commit }, path) { - const deletionPolicy = - getValue(model, 'resources/kubedbComElasticsearch/spec/deletionPolicy') || '' - let storageClass = getValue(model, path) || '' - const suffix = '-retain' - - const simpleClassList = storageClassList.filter((item) => { - return !item.metadata?.name?.endsWith(suffix) - }) - - const retainClassList = storageClassList.filter((item) => { - return item.metadata?.name?.endsWith(suffix) - }) - - const defaultSimpleList = simpleClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] - ) - }) - - const defaultRetainList = retainClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] - ) - }) - - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - if (simpleClassList.length > 1) { - const found = defaultSimpleList.length ? defaultSimpleList[0] : simpleClassList[0] - storageClass = found.value - } else if (simpleClassList.length === 1) { - storageClass = simpleClassList[0]?.value - } else { - const found = defaultRetainList.length - ? defaultRetainList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found - } - } else { - if (retainClassList.length > 1) { - const found = defaultRetainList.length ? defaultRetainList[0] : retainClassList[0] - storageClass = found.value - } else if (retainClassList.length === 1) { - storageClass = retainClassList[0]?.value - } else { - const found = defaultSimpleList.length - ? defaultSimpleList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found - } + function setTrigger(path) { + let value = getValue(model, `/resources/${path}`) + if (value) return value + return 'On' } - if (storageClass && path) { + function onTriggerChange(path) { + const trigger = getValue(discriminator, `/${path}`) + const commitPath = `/resources/${path}` + commit('wizard/model$update', { - path: path, - value: storageClass, + path: commitPath, + value: trigger ? 'On' : 'Off', force: true, }) } -} -function deleteDatabaseModePath({ discriminator, getValue, commit }) { - const mode = getValue(discriminator, '/activeDatabaseMode') - if (mode === 'Dedicated') { - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/replicas') - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/storage') - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/maxUnavailable') - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/podTemplate') - } else if (mode === 'Combined') { - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/topology') + function setControlledResources(path) { + const list = ['cpu', 'memory'] + const resourcePath = `/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/compute/${path}/controlledResources` + commit('wizard/model$update', { + path: resourcePath, + value: list, + force: true, + }) + return list } -} -function isEqualToDatabaseMode({ getValue, watchDependency, discriminator }, value) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') + async function fetchTopologyMachines() { + const instance = hasAnnotations() - return mode === value -} + 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) -function getMaxUnavailableOptions({ model, getValue, watchDependency, commit, elementUi }, path) { - let prefixPath - if (path) { - prefixPath = path - } else { - const { $ref } = elementUi.schema || {} - const replacedPath = ($ref || '').replace( - 'schema#/properties/resources/properties/kubedbComElasticsearch/properties/spec/properties/topology/properties/', - '', - ) - const dyn = replacedPath.split('/').shift() - prefixPath = `/resources/kubedbComElasticsearch/spec/topology/${dyn}` + const nodeGroups = resp.data?.spec?.nodeGroups || [] + setDiscriminatorValue('/topologyMachines', nodeGroups) + return nodeGroups + } catch (e) { + console.log(e) + return [] + } + } } - watchDependency(`model#${prefixPath}/replicas`) - - const replicas = getValue(model, `${prefixPath}/replicas`) - const maxUnavailable = getValue(model, `${prefixPath}/maxUnavailable`) + function hasAnnotations() { + const annotations = + getValue( + model, + '/resources/autoscalingKubedbComElasticsearchAutoscaler/metadata/annotations', + ) || {} + const instance = annotations['kubernetes.io/instance-type'] - if (maxUnavailable > replicas) { - commit('wizard/model$update', { - path: `${prefixPath}/maxUnavailable`, - value: replicas, - force: true, - }) + return !!instance } - const options = [] + function hasNoAnnotations() { + return !hasAnnotations() + } - for (let i = 0; i <= Math.min(replicas, 1000); i++) { - options.push(i) + function setAllowedMachine(type, minmax) { + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = {} + } + const machine = parsedInstance[type] || '' + const mx = machine?.includes(',') ? machine.split(',')[1] : '' + const mn = machine?.includes(',') ? machine.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: '', + } } - return options -} -function getStorageClassNamesFromDiscriminator( - { model, discriminator, getValue, watchDependency, commit }, - path, -) { - watchDependency('discriminator#/storageClasses') - const options = getValue(discriminator, '/storageClasses') || [] + function getMachines(type, minmax) { + const depends = minmax === 'min' ? 'max' : 'min' + const dependantPath = `/allowedMachine-${type}-${depends}` - setStorageClass({ model, getValue, commit }, path) + const dependantMachineObj = getValue(discriminator, dependantPath) + const dependantMachine = dependantMachineObj?.machine || '' - return options -} + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] -async function getSelectedVersionAuthPlugin( - { model, getValue, watchDependency, axios, storeGet, setDiscriminatorValue }, - path, -) { - watchDependency('model#/resources/kubedbComElasticsearch/spec/version') - const version = getValue(model, '/resources/kubedbComElasticsearch/spec/version') || '' - - const elasticVersions = await getElasticSearchVersions( - { axios, storeGet }, - 'catalog.kubedb.com', - 'v1alpha1', - 'elasticsearchversions', - ) + const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) - const selectedVersion = elasticVersions?.find((item) => item.value === version) + // 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 ret = selectedVersion?.spec?.authPlugin || '' + const filteredMachine = machines?.filter((item, ind) => + minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, + ) - if (path) { - setDiscriminatorValue(path, ret) + return dependantIndex === -1 ? machines : filteredMachine } - return ret -} + function onMachineChange(type) { + const annoPath = '/resources/autoscalingKubedbComElasticsearchAutoscaler/metadata/annotations' + const annotations = getValue(model, annoPath) || {} + const instance = annotations['kubernetes.io/instance-type'] + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = {} + } -function onNodeSwitchFalse({ elementSchema, commit }) { - const { $ref } = elementSchema || {} - const node = ($ref || '').split('/').pop() - commit('wizard/model$delete', `/resources/kubedbComElasticsearch/spec/topology/${node}`) -} + // Now discriminator values are objects with { machine, cpu, memory } + const minMachineObj = getValue(discriminator, `/allowedMachine-${type}-min`) + const maxMachineObj = getValue(discriminator, `/allowedMachine-${type}-max`) + const minMachine = minMachineObj?.machine || '' + const maxMachine = maxMachineObj?.machine || '' + const minMaxMachine = `${minMachine},${maxMachine}` + + parsedInstance[type] = minMaxMachine + const instanceString = JSON.stringify(parsedInstance) + annotations['kubernetes.io/instance-type'] = instanceString + + // 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/autoscalingKubedbComElasticsearchAutoscaler/spec/compute/${type}` + + if (minMachine && maxMachine && instance !== instanceString) { + 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 hasTopologyNode({ model, getValue, itemCtx }) { - const nodeValue = getValue(model, `/resources/kubedbComElasticsearch/spec/topology/${itemCtx}`) + function setValueFromDbDetails(path) { + const value = getValue(model, path) + return value + } - return !nodeValue -} + function isKubedb() { + return !!storeGet('/route/params/actions') + } -function hideNode({ itemCtx, discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/selectedVersionAuthPlugin') - const authPlugin = getValue(discriminator, '/selectedVersionAuthPlugin') - - let hiddenNodes = ['coordinating'] - - if (authPlugin === 'OpenDistro') { - hiddenNodes = ['coordinating', 'ml', 'dataCold', 'dataFrozen', 'dataContent', 'transform'] - } else if (authPlugin === 'SearchGuard') { - hiddenNodes = [ - 'coordinating', - 'ml', - 'dataWarm', - 'dataHot', - 'dataCold', - 'dataFrozen', - 'dataContent', - 'transform', - ] + function showOpsRequestOptions() { + if (isKubedb() === true) return true + return ( + !!getValue( + model, + '/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/databaseRef/name', + ) && !!getValue(discriminator, '/autoscalingType') + ) } - const verd = hiddenNodes.includes(itemCtx) - return verd -} + function setApplyToIfReady() { + return 'IfReady' + } -function setInitialStatusFalse({ elementSchema }) { - const disableNodes = ['master', 'data', 'ingest'] - const { $ref } = elementSchema || {} - const node = ($ref || '').split('/').pop() - return !disableNodes.includes(node) -} + 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 disableNode({ elementSchema }) { - const disableNodes = ['master', 'data', 'ingest'] - const { $ref } = elementSchema || {} - const node = ($ref || '').split('/').pop() - return disableNodes.includes(node) -} + function isNodeTopologySelected() { + const nodeTopologyName = + getValue( + model, + '/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/compute/nodeTopology/name', + ) || '' + return !!nodeTopologyName.length + } -// ************************** Internal Users ******************************** - -const defaultUsers = [ - 'admin', - 'kibanaro', - 'kibanaserver', - 'logstash', - 'readall', - 'snapshotrestore', - 'metrics_exporter', -] - -function onInternalUsersChange({ discriminator, getValue, commit }) { - const users = getValue(discriminator, '/internalUsers') - - const internalUsers = {} - - if (users) { - users.forEach((item) => { - const { username, createCred, secretName, password, ...obj } = item - if (createCred === 'no') { - obj.secretName = secretName - commit('wizard/model$delete', `/resources/secret_${username}_cred`) - } else if (createCred === 'yes') { - if (password) { - commit('wizard/model$update', { - path: `/resources/secret_${username}_cred/data/password`, - value: encodePassword({}, password), - force: true, - }) - commit('wizard/model$update', { - path: `/resources/secret_${username}_cred/data/username`, - value: encodePassword({}, username), - force: true, - }) - } else { - commit('wizard/model$delete', `/resources/secret_${username}_cred`) - } - } - internalUsers[username] = obj - }) + function setMetadata() { + const dbname = storeGet('/route/params/name') || '' + const namespace = storeGet('/route/query/namespace') || '' + const isKube = !!storeGet('/route/params/actions') + if (isKube) { + commit('wizard/model$update', { + path: '/metadata/release/name', + value: dbname, + force: true, + }) + commit('wizard/model$update', { + path: '/metadata/release/namespace', + value: namespace, + force: true, + }) + } + } + + // ************************* Monitoring Functions ******************************************** + + function showMonitoringSection() { + const configureStatus = getValue(discriminator, '/enableMonitoring') + return configureStatus } - if (Object.keys(internalUsers).length) { + function onEnableMonitoringChange() { + const configureStatus = getValue(discriminator, '/enableMonitoring') + + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComElasticsearch/spec/monitor', + value: {}, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/monitor') + } + + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: '/resources/kubedbComElasticsearch/spec/internalUsers', - value: internalUsers, + path: '/form/alert/enabled', + value: configureStatus ? 'warning' : 'none', force: true, }) - } else { - // on initial call discriminator value is undefined - // to ignore model$delete for this case, - // users value checking is required, - // model$delete will be executed only if users value is not falsy value (empty array) - // and internalUsers is emptyObject - if (users) commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/internalUsers') } -} -function setInternalUsers({ model, getValue, watchDependency, setDiscriminatorValue }) { - watchDependency('model#/resources/kubedbComElasticsearch/spec/internalUsers') - const internalUsers = getValue(model, '/resources/kubedbComElasticsearch/spec/internalUsers') - - const users = [] + function showCustomizeExporterSection() { + const configureStatus = getValue(discriminator, '/customizeExporter') + return configureStatus + } - for (const item in internalUsers) { - internalUsers[item].username = item - const encodedPassword = getValue(model, `/resources/secret_${item}_cred/data/password`) - if (internalUsers[item].secretName) { - internalUsers[item].createCred = 'no' + function onCustomizeExporterChange() { + const configureStatus = getValue(discriminator, '/customizeExporter') + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComElasticsearch/spec/monitor/prometheus/exporter', + value: {}, + force: true, + }) } else { - if (encodedPassword) { - internalUsers[item].password = decodePassword({}, encodedPassword) - } - internalUsers[item].createCred = 'yes' + commit( + 'wizard/model$delete', + '/resources/kubedbComElasticsearch/spec/monitor/prometheus/exporter', + ) } - users.push(internalUsers[item]) } - setDiscriminatorValue('/internalUsers', users) - - return users -} + function onAgentChange() { + const agent = getValue(model, '/resources/kubedbComElasticsearch/spec/monitor/agent') -function validateNewUser({ itemCtx }) { - if (defaultUsers.includes(itemCtx.username) && itemCtx.isCreate) { - return { isInvalid: true, message: "Can't use this username" } - } - return {} -} + if (!agent) { + removeCertificatesOfAliases(['metrics-exporter']) + } -function disableUsername({ rootModel }) { - return defaultUsers.includes(rootModel && rootModel.username) -} + if (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', + value: [], + force: true, + }) -function disableUserEdit({ itemCtx }) { - if (defaultUsers.includes(itemCtx.username)) { - return { isEditDisabled: false, isDeleteDisabled: true } + onNamespaceChange() + onLabelChange() + } else { + commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') + } } - return {} -} - -async function isAuthPluginEqualTo( - { model, getValue, watchDependency, axios, storeGet, setDiscriminatorValue }, - authPlugin, -) { - const dist = await getSelectedVersionAuthPlugin({ - model, - getValue, - watchDependency, - axios, - storeGet, - setDiscriminatorValue, - }) - return dist === authPlugin -} -// internal user cred -function showPasswordCredSection({ rootModel, getValue, watchDependency }) { - watchDependency('rootModel#/createCred') - const createCred = getValue(rootModel, '/createCred') + function onNamespaceChange() { + const namespace = getValue(model, '/metadata/release/namespace') + const agent = getValue(model, '/resources/kubedbComElasticsearch/spec/monitor/agent') + if (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + value: [namespace], + force: true, + }) + } + } - return createCred === 'yes' -} + function onLabelChange() { + const labels = getValue(model, '/resources/kubedbComElasticsearch/spec/metadata/labels') -function showExistingCredSection({ rootModel, getValue, watchDependency }) { - return !showPasswordCredSection({ rootModel, getValue, watchDependency }) -} + const agent = getValue(model, '/resources/kubedbComElasticsearch/spec/monitor/agent') -function disableRoleDeletion({ itemCtx, rootModel }) { - return itemCtx === 'admin' && rootModel.username === 'admin' -} + if (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', + value: labels, + force: true, + }) + } + } -// ************************** Roles Mapping ******************************** + // ************************* Resource & Network Functions ******************************************** -const defaultRoles = ['readall_and_monitor'] + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function onRolesMappingChange({ discriminator, getValue, commit }) { - const roles = getValue(discriminator, '/rolesMapping') + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) - const rolesMapping = {} + const resources = (resp && resp.data && resp.data.items) || [] - if (roles) { - roles.forEach((item) => { - const { roleName, ...obj } = item - rolesMapping[roleName] = obj - }) + 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 [] + } } - if (Object.keys(rolesMapping).length) { + function removeCertificatesOfAliases(aliasesToRemove) { + const certificates = + getValue(model, '/resources/kubedbComElasticsearch/spec/tls/certificates') || [] + const updatedCertificates = certificates.filter((item) => !aliasesToRemove.includes(item.alias)) commit('wizard/model$update', { - path: '/resources/kubedbComElasticsearch/spec/rolesMapping', - value: rolesMapping, + path: '/resources/kubedbComElasticsearch/spec/tls/certificates', + value: updatedCertificates, force: true, }) - } else { - // on initial call discriminator value is undefined - // to ignore model$delete for this case, - // roles value checking is required, - // model$delete will be executed only if roles value is not falsy value (empty array) - // and rolesMapping is emptyObject - if (roles) commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/rolesMapping') } -} -function setRolesMapping({ model, getValue, watchDependency, setDiscriminatorValue }) { - watchDependency('model#/resources/kubedbComElasticsearch/spec/rolesMapping') - const rolesMapping = getValue(model, '/resources/kubedbComElasticsearch/spec/rolesMapping') + 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 roles = [] + const isKube = !!storeGet('/route/params/actions') - for (const item in rolesMapping) { - rolesMapping[item].roleName = item - roles.push(rolesMapping[item]) + if (isKube) return pathConstructedForKubedb + else + return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/elasticsearchopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=${reqType}` } - setDiscriminatorValue('/rolesMapping', roles) + // ************************* ValueFrom Functions (ConfigMap/Secret) ******************************************** - return roles -} + function setValueFrom() { + if (isConfigMapTypeValueFrom()) { + return 'configMap' + } else if (isSecretTypeValueFrom()) { + return 'secret' + } else { + return 'input' + } + } -function disableRolesEdit({ itemCtx }) { - if (defaultRoles.includes(itemCtx.roleName)) { - return { isEditDisabled: false, isDeleteDisabled: true } + function isConfigMapTypeValueFrom() { + const valueFrom = getValue(discriminator, '/valueFrom') + return !!(valueFrom && valueFrom.configMapKeyRef) } - return {} -} -function disableRoleName({ rootModel }) { - return defaultRoles.includes(rootModel && rootModel.roleName) -} + function isSecretTypeValueFrom() { + const valueFrom = getValue(discriminator, '/valueFrom') + return !!(valueFrom && valueFrom.secretKeyRef) + } -function validateNewRole({ itemCtx }) { - if (defaultRoles.includes(itemCtx.roleName) && itemCtx.isCreate) { - return { isInvalid: true, message: "Can't use this role name" } + 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, + }) + } } - return {} -} -function getInternalUsers({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComElasticsearch/spec/internalUsers') - const internalUsers = getValue(model, '/resources/kubedbComElasticsearch/spec/internalUsers') + // function isEqualToValueFromType(value) { + // const valueFrom = getValue(discriminator, '/valueFromType') + // return valueFrom === value + // } - return Object.keys(internalUsers) -} + async function getNamespacedResourceList( + axios, + storeGet, + { namespace, group, version, resource }, + ) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function disableUserDeletion({ itemCtx, rootModel }) { - return itemCtx.value === 'metrics_exporter' && rootModel.roleName === 'readall_and_monitor' -} + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` -// ************************* Kernel Settings ********************************* + let ans = [] + try { + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) -function onCustomizeKernelSettingChange({ discriminator, getValue, commit }) { - const customizeKernelSettings = getValue(discriminator, '/customizeKernelSettings') + const items = (resp && resp.data && resp.data.items) || [] + ans = items + } catch (e) { + console.log(e) + } - if (customizeKernelSettings === 'no') { - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/kernelSettings') - } else if (customizeKernelSettings === 'disable') { - commit('wizard/model$update', { - path: '/resources/kubedbComElasticsearch/spec/kernelSettings', - value: {}, - force: true, - }) + return ans } -} -// ************************** TLS ******************************************* + async function resourceNames(group, version, resource) { + const namespace = getValue(model, '/metadata/release/namespace') -function setApiGroup() { - return 'cert-manager.io' -} + let resources = await getNamespacedResourceList(axios, storeGet, { + namespace, + group, + version, + resource, + }) -function setApiGroupEdit({ model, getValue }) { - const kind = getValue(model, '/resources/kubedbComElasticsearch/spec/tls/issuerRef/kind') - const name = getValue(model, '/resources/kubedbComElasticsearch/spec/tls/issuerRef/name') - return kind && name ? 'cert-manager.io' : '' -} + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - watchDependency('model#/resources/kubedbComElasticsearch/spec/tls/issuerRef/apiGroup') - watchDependency('model#/resources/kubedbComElasticsearch/spec/tls/issuerRef/kind') - watchDependency('model#/metadata/release/namespace') - const apiGroup = getValue(model, '/resources/kubedbComElasticsearch/spec/tls/issuerRef/apiGroup') - const kind = getValue(model, '/resources/kubedbComElasticsearch/spec/tls/issuerRef/kind') - const namespace = getValue(model, '/metadata/release/namespace') - - let url - if (kind === 'Issuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/namespaces/${namespace}/issuers` - } else if (kind === 'ClusterIssuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/clusterissuers` - } - - 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.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } }) - return resources - } catch (e) { - console.log(e) - return [] } -} -async function hasIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await getIssuerRefsName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) + async function getConfigMapKeys(index) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + const configMapName = getValue( + model, + `/resources/kubedbComElasticsearch/spec/monitor/prometheus/exporter/env/${index}/valueFrom/configMapKeyRef/name`, + ) - return !!(resp && resp.length) -} + if (!configMapName) return [] -async function hasNoIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await hasIssuerRefName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/configmaps/${configMapName}`, + ) - return !resp -} + const configMaps = (resp && resp.data && resp.data.data) || {} -function setClusterAuthMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComElasticsearch/spec/clusterAuthMode') - return val || 'x509' -} + const configMapKeys = Object.keys(configMaps).map((item) => ({ + text: item, + value: item, + })) -function setSSLMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComElasticsearch/spec/sslMode') - return val || 'requireSSL' -} + return configMapKeys + } catch (e) { + console.log(e) + return [] + } + } -function showTlsConfigureSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configureTLS') - const configureStatus = getValue(discriminator, '/configureTLS') - return configureStatus -} + async function getSecrets() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') -function onTlsConfigureChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/configureTLS') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComElasticsearch/spec/tls', - value: { issuerRef: {}, certificates: [] }, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/tls') - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/clusterAuthMode') - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/sslMode') - } -} - -async function showTlsRecommendation({ axios, storeGet }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const url = `/clusters/${owner}/${cluster}/proxy/cert-manager.io/v1/issuers` - - try { - await axios.get(url, { - params: { filter: { items: { metadata: { name: null } } } }, - }) - return false - } catch (err) { - // if any error response status is 404 or not - if (err.response && err.response.status === 404) { - resp = false - } - console.log(err) - return true - } -} - -async function getAliasOptions({ - model, - getValue, - watchDependency, - axios, - storeGet, - setDiscriminatorValue, -}) { - watchDependency('model#/resources/kubedbComElasticsearch/spec/enableSSL') - watchDependency('model#/resources/kubedbComElasticsearch/spec/monitor') - - const enableSSL = getValue(model, '/resources/kubedbComElasticsearch/spec/enableSSL') - const monitor = getValue(model, '/resources/kubedbComElasticsearch/spec/monitor') - const authPlugin = await getSelectedVersionAuthPlugin({ - model, - getValue, - watchDependency, - axios, - storeGet, - setDiscriminatorValue, - }) - - // always include transport cert alias - const aliases = ['transport'] - - if (authPlugin !== 'X-Pack') { - aliases.push('admin') - } - - if (enableSSL) { - aliases.push('http') - aliases.push('archiver') - if (monitor) { - aliases.push('metrics-exporter') - } - } - - return aliases -} - -/****** Monitoring *********/ - -function showMonitoringSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/enableMonitoring') - const configureStatus = getValue(discriminator, '/enableMonitoring') - return configureStatus -} - -function onEnableMonitoringChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/enableMonitoring') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComElasticsearch/spec/monitor', - value: {}, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/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, getValue }) { - watchDependency('discriminator#/customizeExporter') - const configureStatus = getValue(discriminator, '/customizeExporter') - return configureStatus -} - -function onCustomizeExporterChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/customizeExporter') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComElasticsearch/spec/monitor/prometheus/exporter', - value: {}, - force: true, - }) - } else { - commit( - 'wizard/model$delete', - '/resources/kubedbComElasticsearch/spec/monitor/prometheus/exporter', - ) - } -} - -// ********************************* Initialization & Backup ************************************* -const stashAppscodeComRestoreSession_init = { - spec: { - repository: { - name: '', - }, - rules: [ - { - snapshots: ['latest'], - }, - ], - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} -const initScript = { - scriptPath: '', - secret: { - secretName: '', - }, -} -const stashAppscodeComRepository_init_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const stashAppscodeComRepository_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const restoreSessionInitRunTimeSettings = { - container: { - resources: { - requests: { - cpu: '', - memory: '', - }, - limits: { - cpu: '', - memory: '', - }, - }, - nice: { - adjustment: null, - }, - ionice: { - class: null, - classData: null, - }, - securityContext: { - privileged: false, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - env: [], - envFrom: [], - }, - pod: { - serviceAccountName: '', - imagePullSecrets: [], - securityContext: { - fsGroup: null, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - }, -} - -const stashAppscodeComBackupConfiguration = { - spec: { - repository: { - name: '', - }, - retentionPolicy: { - keepLast: 5, - name: 'keep-last-5', - prune: true, - }, - schedule: '*/5 * * * *', - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} - -function disableInitializationSection({ model, getValue, watchDependency }) { - const initialized = getValue(model, '/resources/kubedbComElasticsearch/spec/init/initialized') - watchDependency('model#/resources/kubedbComElasticsearch/spec/init/initialized') - return !!initialized -} - -function valueExists(value, getValue, path) { - const val = getValue(value, path) - if (val) return true - else return false -} - -function initPrePopulateDatabase({ getValue, model }) { - const waitForInitialRestore = getValue( - model, - '/resources/kubedbComElasticsearch/spec/init/waitForInitialRestore', - ) - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - const script = getValue(model, '/resources/kubedbComElasticsearch/spec/init/script') - - return waitForInitialRestore || !!stashAppscodeComRestoreSession_init || !!script ? 'yes' : 'no' -} - -function onPrePopulateDatabaseChange({ commit, getValue, discriminator, model }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - if (prePopulateDatabase === 'no') { - // delete related properties - commit('wizard/model$update', { - path: '/resources/kubedbComElasticsearch/spec/init/waitForInitialRestore', - value: false, - }) - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/init/script') - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else { - const dbName = getValue(model, '/metadata/release/name') - // set stashAppscodeComRestoreSession_init if it doesn't exist - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - force: true, - }) - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - } - } -} - -function initDataSource({ getValue, model }) { - const script = getValue(model, '/resources/kubedbComElasticsearch/spec/init/script') - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - - if (script) return 'script' - else if (stashAppscodeComRestoreSession_init) return 'stashBackup' - else return undefined -} - -function onDataSourceChange({ commit, getValue, discriminator, model }) { - const dataSource = getValue(discriminator, '/dataSource') - - commit('wizard/model$update', { - path: '/resources/kubedbComElasticsearch/spec/init/waitForInitialRestore', - value: dataSource === 'stashBackup', - force: true, - }) - - if (dataSource === 'script') { - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - - // create a new script if there is no script property - if (!valueExists(model, getValue, '/resources/kubedbComElasticsearch/spec/init/script')) - commit('wizard/model$update', { - path: '/resources/kubedbComElasticsearch/spec/init/script', - value: initScript, - }) - } else if (dataSource === 'stashBackup') { - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/init/script') - - // create a new stashAppscodeComRestoreSession_init if there is no stashAppscodeComRestoreSession_init property - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - const dbName = getValue(model, '/metadata/release/name') - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - }) - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - } - } -} - -// // for script -function initVolumeType({ getValue, model }) { - const configMap = getValue( - model, - '/resources/kubedbComElasticsearch/spec/init/script/configMap/name', - ) - const secret = getValue( - model, - '/resources/kubedbComElasticsearch/spec/init/script/secret/secretName', - ) - - if (configMap) return 'configMap' - else if (secret) return 'secret' - else return undefined -} - -function onVolumeTypeChange({ commit, getValue, discriminator, model }) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - if (sourceVolumeType === 'configMap') { - // add configMap object and delete secret object - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/init/script/secret') - - if ( - !valueExists(model, getValue, '/resources/kubedbComElasticsearch/spec/init/script/configMap') - ) { - commit('wizard/model$update', { - path: '/resources/kubedbComElasticsearch/spec/init/script/configMap', - value: { - name: '', - }, - }) - } - } else if (sourceVolumeType === 'secret') { - // delete configMap object and add secret object - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/init/script/configMap') - - if ( - !valueExists(model, getValue, '/resources/kubedbComElasticsearch/spec/init/script/secret') - ) { - commit('wizard/model$update', { - path: '/resources/kubedbComElasticsearch/spec/init/script/secret', - value: { - secretName: '', - }, - }) - } - } -} - -function showInitializationForm({ getValue, discriminator, watchDependency }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - watchDependency('discriminator#/prePopulateDatabase') - return prePopulateDatabase === 'yes' -} - -function showScriptOrStashForm({ getValue, discriminator, watchDependency }, value) { - const dataSource = getValue(discriminator, '/dataSource') - watchDependency('discriminator#/dataSource') - return dataSource === value -} - -function showConfigMapOrSecretName({ getValue, discriminator, watchDependency }, value) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - watchDependency('discriminator#/sourceVolumeType') - return sourceVolumeType === value -} - -// for stash backup -function initializeNamespace({ getValue, model }) { - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} - -function showRepositorySelectOrCreate({ getValue, discriminator, watchDependency }, value) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - return repositoryChoise === value -} - -function onInitRepositoryChoiseChange({ getValue, discriminator, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - if (repositoryChoise === 'select') { - // delete stashAppscodeComRepository_init_repo from model - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else if (repositoryChoise === 'create') { - // add stashAppscodeComRepository_init_repo to model - commit('wizard/model$update', { - path: 'resources/stashAppscodeComRepository_init_repo', - value: stashAppscodeComRepository_init_repo, - }) - - const repositoryName = `${getValue(model, '/metadata/release/name')}-init-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: repositoryName, - }) - } -} - -function initCustomizeRestoreJobRuntimeSettings({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function initCustomizeRestoreJobRuntimeSettingsForBackup({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function onCustomizeRestoreJobRuntimeSettingsChange({ commit, getValue, discriminator, model }) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - value: restoreSessionInitRunTimeSettings, - }) - } - } -} - -function onCustomizeRestoreJobRuntimeSettingsChangeForBackup({ - commit, - getValue, - discriminator, - model, -}) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - value: {}, - force: true, - }) - } - } -} - -function showRuntimeForm({ discriminator, getValue, watchDependency }, value) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - watchDependency('discriminator#/customizeRestoreJobRuntimeSettings') - return customizeRestoreJobRuntimeSettings === value -} - -async function getImagePullSecrets({ getValue, model, watchDependency, axios, storeGet }) { - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - - let resources = await getNamespacedResourceList(axios, storeGet, { - namespace, - group: 'core', - version: 'v1', - resource: 'secrets', - }) - - resources = resources.filter((item) => { - const validType = ['kubernetes.io/dockerconfigjson'] - return validType.includes(item.type) - }) - - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: { name: name }, - } - }) -} - -// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// FOR Backup Configuration - -// schedule bakcup - -function getBackupConfigsAndAnnotations(getValue, model) { - const stashAppscodeComBackupConfiguration = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration', - ) - const kubedbComElasticsearchAnnotations = - getValue(model, '/resources/kubedbComElasticsearch/metadata/annotations') || {} - - const isBluePrint = Object.keys(kubedbComElasticsearchAnnotations).some( - (k) => - k === 'stash.appscode.com/backup-blueprint' || - k === 'stash.appscode.com/schedule' || - k.startsWith('params.stash.appscode.com/'), - ) - - return { - stashAppscodeComBackupConfiguration, - isBluePrint, - } -} - -function deleteKubedbComElasticsearchDbAnnotation(getValue, model, commit) { - const annotations = - getValue(model, '/resources/kubedbComElasticsearch/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/kubedbComElasticsearch/metadata/annotations', - value: filteredAnnotations, - }) -} - -function addKubedbComElasticsearchDbAnnotation(getValue, model, commit, key, value, force) { - const annotations = - getValue(model, '/resources/kubedbComElasticsearch/metadata/annotations') || {} - - if (annotations[key] === undefined) { - annotations[key] = value - } else if (force) { - annotations[key] = value - } - - commit('wizard/model$update', { - path: '/resources/kubedbComElasticsearch/metadata/annotations', - value: annotations, - force: true, - }) -} - -function initScheduleBackupForEdit({ getValue, model, setDiscriminatorValue }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function initScheduleBackup({ getValue, model }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function onScheduleBackupChange({ commit, getValue, discriminator, model }) { - 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 kubedbComElasticsearch annotation - deleteKubedbComElasticsearchDbAnnotation(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, - }) - } - } -} - -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 = {} - -// backup form -function showBackupForm({ getValue, discriminator, watchDependency }) { - const scheduleBackup = getValue(discriminator, '/scheduleBackup') - watchDependency('discriminator#/scheduleBackup') - - if (scheduleBackup === 'yes') return true - else return false -} - -async function initBackupData({ storeGet, axios, getValue, model, setDiscriminatorValue }) { - // 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/kubedbComElasticsearch') - initialDbMetadata = objectCopy(dbResource.metadata) - - // 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 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, getValue, discriminator }) { - watchDependency('discriminator#/isBackupDataLoaded') - return !!getValue(discriminator, '/isBackupDataLoaded') -} - -async function setBackupType() { - return 'BackupConfig' -} - -async function getTypes() { - const arr = [ - { - description: 'Create, Delete or Modify BackupConfig', - text: 'BackupConfig', - value: 'BackupConfig', - }, - { - description: 'Enable/Disable BackupBlueprint', - text: 'BackupBlueprint', - value: 'BackupBlueprint', - }, - ] - return arr -} - -function onBackupTypeChange({ commit, getValue, discriminator }) { - 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/kubedbComElasticsearch', - value: objectCopy(dbResource), - force: true, - }) -} - -function isBackupType({ watchDependency, getValue, discriminator }, 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({ getValue, discriminator, commit, model, storeGet }) { - const blueprintSwitch = getValue(discriminator, '/blueprintEnabled') - if (blueprintSwitch) addLabelAnnotation(commit, storeGet, 'annotations') - else deleteLabelAnnotation(commit, 'annotations') -} - -function setArchiverSwitch() { - const archiver = dbResource?.spec?.archiver - return !!archiver -} - -function onArchiverChange({ getValue, discriminator, commit }) { - const archiverSwitch = getValue(discriminator, '/archiverEnabled') - const path = 'resources/kubedbComElasticsearch/spec/archiver' - if (archiverSwitch) { - commit('wizard/model$update', { - path: path, - value: initialArchiver ? initialArchiver : archiverObjectToCommit, - }) - } else { - commit('wizard/model$delete', path) - } -} - -function addLabelAnnotation(commit, storeGet, 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/kubedbComElasticsearch/metadata/${type}`, - value: obj, - force: true, - }) -} - -function deleteLabelAnnotation(commit, 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/kubedbComElasticsearch/metadata/${type}`, - value: obj, - force: true, - }) -} - -function getContext() { - if (isBackupOn) return ['Create', 'Delete', 'Modify'] - return ['Create'] -} - -function onContextChange({ getValue, discriminator, commit, model }) { - 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, - }) - } -} - -function getConfigList({ storeGet }) { - 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({ getValue, discriminator, commit, storeGet, model }) { - 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, getValue, discriminator }) { - watchDependency('discriminator#/backupConfigContext') - watchDependency('discriminator#/config') - const contex = getValue(discriminator, '/backupConfigContext') - const configName = getValue(discriminator, '/config') - return !!configName && contex === 'Modify' -} - -function showConfigList({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/backupConfigContext') - const contex = getValue(discriminator, '/backupConfigContext') - return contex === 'Modify' || contex === 'Delete' -} - -function showSchedule({ watchDependency, getValue, discriminator }) { - 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 -} - -// backup configuration form -function initalizeTargetReferenceName({ getValue, model, watchDependency }) { - const databaseName = getValue(model, '/metadata/release/name') - watchDependency('model#/metadata/release/name') - - return databaseName -} - -// restore session repository -function setInitialRestoreSessionRepo({ getValue, model }) { - const value = getValue(model, 'resources/stashAppscodeComRepository_init_repo') - return value ? 'create' : 'select' -} - -// backup config repository -function initRepositoryChoise({ getValue, model }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - - if (stashAppscodeComRepository_repo) return 'create' - else return 'select' -} - -function initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' - setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) - - return repoInitialSelectionStatus -} - -function onRepositoryChoiseChange({ getValue, discriminator, watchDependency, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - if (repositoryChoise === 'select') { - // delete the stashAppscodeComRepository_repo - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') - } else if (repositoryChoise === 'create') { - // create new stashAppscodeComRepository_repo - if (!valueExists(model, getValue, '/resources/stashAppscodeComRepository_repo')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRepository_repo', - value: stashAppscodeComRepository_repo, - }) - const repositoryName = `${getValue(model, '/metadata/release/name')}-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) - } - } -} - -function onRepositoryNameChange({ getValue, model, commit }) { - const repositoryName = getValue(model, 'resources/stashAppscodeComRepository_repo/metadata/name') - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) -} - -// backup blueprint form -function getMongoAnnotations(getValue, model) { - const annotations = getValue(model, '/resources/kubedbComElasticsearch/metadata/annotations') - return { ...annotations } || {} -} - -function initFromAnnotationValue({ getValue, model }, key) { - const annotations = getMongoAnnotations(getValue, model) - return annotations[key] -} - -function onBackupBlueprintNameChange({ getValue, discriminator, commit, model }) { - const backupBlueprintName = getValue(discriminator, '/backupBlueprintName') - addKubedbComElasticsearchDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/backup-blueprint', - backupBlueprintName, - true, - ) -} - -function onBackupBlueprintScheduleChange({ getValue, discriminator, commit, model }) { - const backupBlueprintSchedule = getValue(discriminator, '/schedule') - addKubedbComElasticsearchDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/schedule', - backupBlueprintSchedule, - true, - ) -} - -function initFromAnnotationKeyValue({ getValue, model }, prefix) { - const annotations = getMongoAnnotations(getValue, model) - const newOb = {} - Object.keys(annotations).forEach((key) => { - if (key.startsWith(prefix)) { - const newKey = key.replace(prefix, '') - newOb[newKey] = annotations[key] - } - }) - return newOb -} - -function onTaskParametersChange({ getValue, discriminator, model, commit }) { - const taskParameters = getValue(discriminator, '/taskParameters') - - const taskParamterKeys = Object.keys(taskParameters).map( - (tp) => `params.stash.appscode.com/${tp}`, - ) - const oldAnnotations = - getValue(model, '/resources/kubedbComElasticsearch/metadata/annotations') || {} - const newAnnotations = {} - - const filteredAnnotationKeys = Object.keys(oldAnnotations).filter( - (key) => !taskParamterKeys.includes(key) && !key.startsWith('params.stash.appscode.com/'), - ) - - filteredAnnotationKeys.forEach((key) => { - newAnnotations[key] = oldAnnotations[key] - }) - - Object.keys(taskParameters).forEach((tpk) => { - newAnnotations[`params.stash.appscode.com/${tpk}`] = taskParameters[tpk] - }) - - commit('wizard/model$update', { - path: '/resources/kubedbComElasticsearch/metadata/annotations', - value: newAnnotations, - }) -} - -function isValueExistInModel({ model, getValue }, path) { - const modelValue = getValue(model, path) - return !!modelValue -} - -function onNamespaceChange({ commit, model, getValue }) { - const namespace = getValue(model, '/metadata/release/namespace') - const agent = getValue(model, '/resources/kubedbComElasticsearch/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', - value: [namespace], - force: true, - }) - } -} - -function onLabelChange({ commit, model, getValue }) { - const labels = getValue(model, '/resources/kubedbComElasticsearch/spec/metadata/labels') - - const agent = getValue(model, '/resources/kubedbComElasticsearch/spec/monitor/agent') - - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) - } -} - -function onNameChange({ commit, model, getValue }) { - const dbName = getValue(model, '/metadata/release/name') - - const agent = getValue(model, '/resources/kubedbComElasticsearch/spec/monitor/agent') - - const labels = getValue(model, '/resources/kubedbComElasticsearch/spec/metadata/labels') - - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) - } - - const scheduleBackup = getValue(model, '/resources/stashAppscodeComBackupConfiguration') - - if (scheduleBackup) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_repo') - if (creatingNewRepo) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: `${dbName}-repo`, - force: true, - }) - } - } - - const prePopulateDatabase = getValue(model, '/resources/stashAppscodeComRestoreSession_init') - - if (prePopulateDatabase) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_init_repo') - if (creatingNewRepo) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: `${dbName}-init-repo`, - force: true, - }) - } - } - - // to reset configSecret name field - const hasSecretConfig = getValue(model, '/resources/secret_user_config') - if (hasSecretConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComElasticsearch/spec/configSecret/name', - value: `${dbName}-config`, - force: true, - }) - } -} - -function returnFalse() { - return false -} - -function onAgentChange({ commit, model, getValue }) { - const agent = getValue(model, '/resources/kubedbComElasticsearch/spec/monitor/agent') - - if (!agent) { - removeCertificatesOfAliases({ model, getValue, commit }, ['metrics-exporter']) - } - - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', - value: [], - force: true, - }) - - onNamespaceChange({ commit, model, getValue }) - onLabelChange({ commit, model, getValue }) - } else { - commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') - } -} - -//////////////////// service monitor /////////////////// - -function isEqualToServiceMonitorType({ rootModel, watchDependency }, value) { - watchDependency('rootModel#/spec/type') - return rootModel && rootModel.spec && rootModel.spec.type === value -} - -//////////////////// custom config ///////////////// -function onConfigurationSourceChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSource') - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_user_config') - commit('wizard/model$delete', '/resources/config_secret') - } else { - const value = getValue(model, '/resources/secret_user_config') - if (!value) { - commit('wizard/model$update', { - path: '/resources/secret_user_config', - value: {}, - force: true, - }) - } - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComElasticsearch/spec/configSecret/name', - value: configSecretName, - force: true, - }) - } -} - -function setConfigurationSource({ model, getValue }) { - const modelValue = getValue(model, '/resources/secret_user_config') - if (modelValue) { - return 'create-new-config' - } - return 'use-existing-config' -} - -function setConfigFiles({ model, getValue, watchDependency, setDiscriminatorValue }) { - watchDependency('model#/resources/secret_user_config/stringData') - const configFiles = getValue(model, '/resources/secret_user_config/stringData') - - const files = [] - - for (const item in configFiles) { - const obj = {} - obj.key = item - obj.value = configFiles[item] - files.push(obj) - } - - setDiscriminatorValue('/configFiles', files) - - return files -} - -function onConfigFilesChange({ discriminator, getValue, commit }) { - const files = getValue(discriminator, '/configFiles') - - const configFiles = {} - - if (files) { - files.forEach((item) => { - const { key, value } = item - configFiles[key] = value - }) - } - - commit('wizard/model$update', { - path: '/resources/secret_user_config/stringData', - value: configFiles, - force: true, - }) -} - -function onSetCustomConfigChange({ discriminator, getValue, commit }) { - const value = getValue(discriminator, '/setCustomConfig') - - if (value === 'no') { - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/configSecret') - commit('wizard/model$delete', '/resources/secret_user_config') - } -} - -function initSetCustomConfig({ model, getValue }) { - const configSecret = getValue(model, '/resources/kubedbComElasticsearch/spec/configSecret/name') - - if (configSecret) return 'yes' - else return 'no' -} - -//////////////////// secret custom config ///////////////// -function onSecretConfigurationSourceChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSource') - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_secure_config') - } else { - const value = getValue(model, '/resources/secret_secure_config') - if (!value) { - commit('wizard/model$update', { - path: '/resources/secret_secure_config', - value: {}, - force: true, - }) - } - const configSecretName = `${getValue(model, '/metadata/release/name')}-secure-config` - commit('wizard/model$update', { - path: '/resources/kubedbComElasticsearch/spec/secureConfigSecret/name', - value: configSecretName, - force: true, - }) - } -} - -function setSecretConfigurationSource({ model, getValue }) { - const modelValue = getValue(model, '/resources/secret_secure_config') - if (modelValue) { - return 'create-new-config' - } - return 'use-existing-config' -} - -function setSecretConfigFiles({ model, getValue, watchDependency, setDiscriminatorValue }) { - watchDependency('model#/resources/secret_secure_config/stringData') - const configFiles = getValue(model, '/resources/secret_secure_config/stringData') - - const files = [] - - for (const item in configFiles) { - const obj = {} - obj.key = item - obj.value = configFiles[item] - files.push(obj) - } - - setDiscriminatorValue('/configFiles', files) - - return files -} - -function onSecretConfigFilesChange({ discriminator, getValue, commit }) { - const files = getValue(discriminator, '/configFiles') - - const configFiles = {} - - if (files) { - files.forEach((item) => { - const { key, value } = item - configFiles[key] = value - }) - } - - commit('wizard/model$update', { - path: '/resources/secret_secure_config/stringData', - value: configFiles, - force: true, - }) -} - -function onSetSecretCustomConfigChange({ discriminator, getValue, commit }) { - const value = getValue(discriminator, '/setSecretCustomConfig') - - if (value === 'no') { - commit('wizard/model$delete', '/resources/kubedbComElasticsearch/spec/secureConfigSecret') - commit('wizard/model$delete', '/resources/secret_secure_config') - } -} - -function initSetSecureCustomConfig({ model, getValue }) { - const configSecret = getValue( - model, - '/resources/kubedbComElasticsearch/spec/secureConfigSecret/name', - ) - - if (configSecret) return 'yes' - else return 'no' -} - -function getOpsRequestUrl({ storeGet, model, getValue, mode }, 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 + `/create-opsrequest-${reqType.toLowerCase()}?namespace=${namespace}` - - if (mode === 'standalone-step') return pathConstructedForKubedb - else - return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/elasticsearchopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=${reqType}` -} - -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } -} - -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} - -function showScheduleBackup({ storeGet }) { - const operationQuery = storeGet('/route/params/actions') || '' - const isBackupOperation = operationQuery === 'edit-self-backupconfiguration' ? true : false - return !isBackupOperation -} - -function showBackupOptions({ discriminator, getValue, watchDependency }, backup) { - const backupEnabled = getValue(discriminator, '/backupEnabled') - if (backupEnabled) { - if (backup === 'alert') return true - else return false - } else { - if (backup === 'alert') return false - else return true - } -} - -function isBlueprintOption({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/blueprintOptions') - const blueprintOptions = getValue(discriminator, '/blueprintOptions') - return blueprintOptions === value -} - -function ifUsagePolicy({ discriminator, getValue, watchDependency, model }, value) { - watchDependency( - 'model#/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', - ) - const usagePolicy = getValue( - model, - '/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', - ) - return usagePolicy === value -} - -async function getBlueprints({ getValue, model, setDiscriminatorValue, axios, storeGet }, backup) { - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const url = `clusters/${username}/${clusterName}/proxy/core.kubestash.com/v1alpha1/backupblueprints` - - try { - const resp = await axios.get(url) - let data = resp.data.items - return data - } catch (e) { - console.log(e) - } -} - -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} - -async function fetchNamespaces({ axios, storeGet }) { - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const group = storeGet('/route/params/group') - const version = storeGet('/route/params/version') - const resource = storeGet('/route/params/resource') - - const url = `clusters/${username}/${clusterName}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews` - - try { - const resp = await axios.post(url, { - _recurringCall: false, - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { items: { metadata: { name: null }, type: null } }, }, - ], - }, - }) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] - } - } catch (e) { - console.log(e) - } - return [] -} - -async function fetchNames( - { getValue, axios, storeGet, watchDependency, discriminator }, - version, - type, - discriminatorName, -) { - watchDependency(`discriminator#/${discriminatorName}`) - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const namespace = getValue(discriminator, `${discriminatorName}`) - const url = - type !== 'secrets' - ? `clusters/${username}/${clusterName}/proxy/storage.kubestash.com/${version}/namespaces/${namespace}/${type}` - : `clusters/${username}/${clusterName}/proxy/core/${version}/namespaces/${namespace}/${type}` - try { - if (namespace) { - const resp = await axios.get(url) - let data = resp.data.items - if (type === 'secrets') data = data.filter((ele) => !!ele.data['RESTIC_PASSWORD']) - data = data.map((ele) => ele.metadata.name) - return data - } - } catch (e) { - console.log(e) - } - return [] -} - -function initBlueprint() { - return 'create' -} -function initUsagePolicy() { - return 'Same' -} - -function onInputChange( - { getValue, discriminator, commit, model }, - modelPath, - field, - subfield, - discriminatorName, -) { - const value = getValue(discriminator, `/${discriminatorName}`) - const backends = getValue(model, modelPath) || [] - if (field !== 'encryptionSecret') backends[0][field][subfield] = value - else backends[0]['repositories'][0][field][subfield] = value - commit('wizard/model$update', { - path: modelPath, - value: backends, - }) -} - -function setFileValueFromStash({ getValue, commit, model }, modelPath, field, subfield, value) { - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') backends[0][field][subfield] = value - else backends[0]['repositories'][0][field][subfield] = value - commit('wizard/model$update', { - path: modelPath, - value: backends, - }) -} - -function onInputChangeSchedule( - { getValue, discriminator, commit, model }, - modelPath, - discriminatorName, -) { - const value = getValue(discriminator, `/${discriminatorName}`) - const session = getValue(model, modelPath) - session[0].scheduler.schedule = value - commit('wizard/model$update', { - path: modelPath, - value: session, - }) -} - -function setInitSchedule( - { getValue, discriminator, watchDependency, commit, model }, - modelPath, - value, -) { - const session = getValue(model, modelPath) - session[0].scheduler.schedule = value - commit('wizard/model$update', { - path: modelPath, - value: session, - }) -} - -function getDefault({ getValue, model }, modelPath, field, subfield) { - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') return backends[0][field][subfield] - else { - return backends[0]['repositories'][0][field][subfield] - } -} - -function getDefaultSchedule({ getValue, model, watchDependency }, modelPath) { - watchDependency('discriminator#/config') - const session = getValue(model, modelPath) - return session?.length ? session[0]?.scheduler.schedule : '' -} + }, + ) -////////////////// auto scaler ////////////// -let autoscaleType = '' -let dbDetails = {} + const secrets = (resp && resp.data && resp.data.items) || [] -function isConsole({ storeGet, commit }) { - const isKube = isKubedb({ storeGet }) + const filteredSecrets = secrets.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) - if (isKube) { - const dbName = storeGet('/route/params/name') || '' - commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComElasticsearchAutoscaler/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: '/metadata/name', - value: modifiedName, - force: true, - }) - const namespace = storeGet('/route/query/namespace') || '' - if (namespace) { - commit('wizard/model$update', { - path: '/metadata/namespace', - value: namespace, - force: true, + 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 [] } } - return !isKube -} - -function isKubedb({ storeGet }) { - return !!storeGet('/route/params/actions') -} - -function showOpsRequestOptions({ model, getValue, watchDependency, storeGet, discriminator }) { - if (isKubedb({ storeGet }) === true) return true - watchDependency( - 'model#/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/databaseRef/name', - ) - watchDependency('discriminator#/autoscalingType') - return ( - !!getValue( + async function getSecretKeys(index) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + const secretName = getValue( model, - '/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/databaseRef/name', - ) && !!getValue(discriminator, '/autoscalingType') - ) -} - -async function getNamespaces({ axios, storeGet }) { - 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({ axios, storeGet, model, getValue, watchDependency }) { - watchDependency('model#/metadata/namespace') - const namespace = getValue(model, '/metadata/namespace') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/elasticsearches`, - { - 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, - } - }) -} + `/resources/kubedbComElasticsearch/spec/monitor/prometheus/exporter/env/${index}/valueFrom/secretKeyRef/name`, + ) -async function getDbDetails({ setDiscriminatorValue, commit, axios, storeGet, getValue, model }) { - 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, - '/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/databaseRef/name', - ) || - '' + if (!secretName) return [] - if (namespace && name) { try { const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/elasticsearches/${name}`, + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets/${secretName}`, ) - dbDetails = resp.data || {} - setDiscriminatorValue('/dbDetails', true) - } catch (e) { - console.log(e) - } - } - - commit('wizard/model$update', { - path: `/metadata/release/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/metadata/release/namespace`, - value: namespace, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingkubedbComElasticsearchAutoscaler/spec/databaseRef/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingkubedbComElasticsearchAutoscaler/metadata/labels`, - value: dbDetails.metadata.labels, - force: true, - }) -} - -async function dbTypeEqualsTo({ axios, storeGet, watchDependency, model, getValue, commit }, type) { - watchDependency('discriminator#/dbDetails') - - const { spec } = dbDetails || {} - const { topology } = spec || {} - let verd = '' - if (topology) verd = 'topology' - else verd = 'node' - clearSpecModel({ commit }, verd) - return type === verd && spec -} - -function clearSpecModel({ commit }, dbtype) { - if (dbtype === 'node') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/${autoscaleType}/data`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/${autoscaleType}/ingest`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/${autoscaleType}/master`, - ) - } else if (dbtype === 'topology') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/${autoscaleType}/node`, - ) - } -} - -function initMetadata({ getValue, discriminator, model, commit, storeGet }) { - const dbName = - getValue( - model, - '/resources/autoscalingKubedbComElasticsearchAutoscaler/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: '/metadata/name', - value: modifiedName, - force: true, - }) - - // delete the other type object from model - if (type === 'compute') - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/storage', - ) - if (type === 'storage') - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/compute', - ) -} - -function onNamespaceChange({ model, getValue, commit }) { - const namespace = getValue(model, '/metadata/namespace') - if (!namespace) { - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/databaseRef/name', - ) - } -} -function ifScalingTypeEqualsTo( - { storeGet, watchDependency, getValue, discriminator, model }, - type, -) { - watchDependency('discriminator#/autoscalingType') - watchDependency( - 'model#/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/databaseRef/name', - ) + const secret = (resp && resp.data && resp.data.data) || {} - const operation = storeGet('/route/params/actions') || '' - if (operation.length) { - const splitOp = operation.split('-') - if (splitOp.length > 2) autoscaleType = splitOp[2] - } else autoscaleType = getValue(discriminator, '/autoscalingType') || '' - const isDatabaseSelected = !!getValue( - model, - '/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/databaseRef/name', - ) - return autoscaleType === type && isDatabaseSelected -} + const secretKeys = Object.keys(secret).map((item) => ({ + text: item, + value: item, + })) -async function fetchNodeTopology({ axios, storeGet }) { - 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 secretKeys + } catch (e) { + console.log(e) + return [] + } } - return [] -} - -function isNodeTopologySelected({ watchDependency, model, getValue }) { - watchDependency( - 'model#/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/compute/nodeTopology/name', - ) - const nodeTopologyName = - getValue( - model, - '/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/compute/nodeTopology/name', - ) || '' - return !!nodeTopologyName.length -} - -function setControlledResources({ commit }, type) { - const list = ['cpu', 'memory'] - const path = `/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/compute/${type}/controlledResources` - commit('wizard/model$update', { - path: path, - value: list, - force: true, - }) - return list -} -function setTrigger({ model, getValue }, path) { - let value = getValue(model, `/resources/${path}`) - if (value) return value - return 'On' -} - -function setApplyToIfReady() { - return 'IfReady' -} - -function handleUnit({ commit, model, getValue }, 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' + 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 } } } - if (!isNaN(threshold)) { - threshold += 'pc' - } - updatedValue.push({ threshold, appliesUpto }) + return ret }) - if (JSON.stringify(updatedValue) !== JSON.stringify(value)) { - commit('wizard/model$update', { - path: `/resources/${path}`, - value: updatedValue, - force: true, - }) - } - } else { - if (!isNaN(value)) { - value += 'Gi' + + if (filteredEnv.length) commit('wizard/model$update', { - path: `/resources/${path}`, - value: value, + path: '/resources/kubedbComElasticsearch/spec/monitor/prometheus/exporter/env', + value: filteredEnv, force: true, }) - } - } -} - -function objectCopy(obj) { - const temp = JSON.stringify(obj) - return JSON.parse(temp) -} - -function isBindingAlreadyOn({ model, getValue }) { - const value = getValue(model, '/resources') - const keys = Object.keys(value) - isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComElasticsearchBinding') - return isExposeBinding -} - -async function addOrRemoveBinding({ commit, model, getValue, discriminator }) { - const value = getValue(discriminator, `/binding`) - const dbName = getValue(model, '/metadata/release/name') - const dbNamespace = getValue(model, '/metadata/release/namespace') - const labels = getValue(model, '/resources/kubedbComElasticsearch/metadata/labels') - const bindingValues = { - apiVersion: 'catalog.appscode.com/v1alpha1', - kind: 'ElasticsearchBinding', - metadata: { - labels, - name: dbName, - namespace: dbNamespace, - }, - spec: { - sourceRef: { - name: dbName, - namespace: dbNamespace, - }, - }, - } - - if (value) { - await commit('wizard/model$update', { - path: '/resources/catalogAppscodeComElasticsearchBinding', - value: bindingValues, - force: true, - }) - } else { - await commit('wizard/model$delete', '/resources/catalogAppscodeComElasticsearchBinding') } -} -async function fetchTopologyMachines({ axios, getValue, storeGet, model, setDiscriminatorValue }) { - const instance = hasAnnotations({ model, getValue }) - - 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) + function initEnvArray() { + const env = getValue( + model, + '/resources/kubedbComElasticsearch/spec/monitor/prometheus/exporter/env', + ) - const nodeGroups = resp.data?.spec?.nodeGroups || [] - setDiscriminatorValue('/topologyMachines', nodeGroups) - return nodeGroups - } catch (e) { - console.log(e) - return [] - } + return env || [] } -} -function setAllowedMachine({ model, getValue }, type, minmax) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComElasticsearchAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - let parsedInstance = {} - try { - if (instance) parsedInstance = JSON.parse(instance) - } catch (e) { - console.log(e) - parsedInstance = {} + function isEqualToTemp(value, index) { + //watchDependency('discriminator#/valueFromType') + const valueFrom = getValue(discriminator, `/env/${index}/temp/valueFromType`) + return valueFrom === value } - const machine = parsedInstance[type] || '' - const mx = machine?.includes(',') ? machine.split(',')[1] : '' - const mn = machine?.includes(',') ? machine.split(',')[0] : '' - - if (minmax === 'min') return mn - else return mx -} - -async function getMachines({ getValue, watchDependency, discriminator }, type, minmax) { - watchDependency('discriminator#/topologyMachines') - const depends = minmax === 'min' ? 'max' : 'min' - const dependantPath = `/allowedMachine-${type}-${depends}` - - watchDependency(`discriminator#${dependantPath}`) - const dependantMachine = getValue(discriminator, dependantPath) - - const nodeGroups = getValue(discriminator, '/topologyMachines') || [] - - const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) - - const machines = nodeGroups?.map((item) => { - const subText = `CPU: ${item.allocatable.cpu}, Memory: ${item.allocatable.memory}` - const text = item.topologyValue - return { text, subText, value: item.topologyValue } - }) - - const filteredMachine = machines?.filter((item, ind) => - minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, - ) - - return dependantIndex === -1 ? machines : filteredMachine -} - -function hasAnnotations({ model, getValue }, type) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComElasticsearchAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - - return !!instance -} - -function hasNoAnnotations({ model, getValue }) { - return !hasAnnotations({ model, getValue }) -} - -function onMachineChange({ model, getValue, discriminator, commit }, type) { - const annoPath = '/resources/autoscalingKubedbComElasticsearchAutoscaler/metadata/annotations' - const annotations = getValue(model, annoPath) - const instance = annotations['kubernetes.io/instance-type'] - let parsedInstance = {} - try { - if (instance) parsedInstance = JSON.parse(instance) - } catch (e) { - console.log(e) - parsedInstance = {} - } - - const minMachine = getValue(discriminator, `/allowedMachine-${type}-min`) - const maxMachine = getValue(discriminator, `/allowedMachine-${type}-max`) - const minMaxMachine = `${minMachine},${maxMachine}` - - parsedInstance[type] = minMaxMachine - const instanceString = JSON.stringify(parsedInstance) - annotations['kubernetes.io/instance-type'] = instanceString - - const machines = getValue(discriminator, `/topologyMachines`) || [] - const minMachineObj = machines.find((item) => item.topologyValue === minMachine) - const maxMachineObj = machines.find((item) => item.topologyValue === maxMachine) - const minMachineAllocatable = minMachineObj?.allocatable - const maxMachineAllocatable = maxMachineObj?.allocatable - const allowedPath = `/resources/autoscalingKubedbComElasticsearchAutoscaler/spec/compute/${type}` - - if (minMachine && maxMachine && instance !== instanceString) { - 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 initMonitoring() { + const env = + getValue(model, '/resources/kubedbComElasticsearch/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 { - handleUnit, - isConsole, - getNamespaces, - getDbs, - isKubedb, - getDbDetails, - dbTypeEqualsTo, - clearSpecModel, - initMetadata, - onNamespaceChange, - ifScalingTypeEqualsTo, - fetchNodeTopology, - isNodeTopologySelected, - setControlledResources, - setTrigger, - setApplyToIfReady, - showOpsRequestOptions, - setInitSchedule, - fetchNames, - fetchNamespaces, - isRancherManaged, - onInputChangeSchedule, - getDefaultSchedule, - getBlueprints, - ifUsagePolicy, - initUsagePolicy, - isBlueprintOption, - initBlueprint, - getDefault, - onInputChange, - showBackupOptions, - showScheduleBackup, - fetchJsons, - disableLableChecker, - isEqualToModelPathValue, - getResources, - isEqualToDiscriminatorPath, - setValueFromModel, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - returnTrue, - returnStringYes, - isDedicatedModeSelected, - isCombinedModeSelected, - isDiscriminatorEqualTo, - isAuthPluginNotSearchGuard, - showInternalUsersAndRolesMapping, - showSecureCustomConfig, - getElasticSearchVersions, - isSecurityEnabled, - onDisableSecurityChange, - onVersionChange, - onEnableSSLChange, - removeCertificatesOfAliases, - setDatabaseMode, - getStorageClassNames, - getStorageClassNamesFromDiscriminator, - deleteDatabaseModePath, - isEqualToDatabaseMode, - getSelectedVersionAuthPlugin, - onNodeSwitchFalse, - hasTopologyNode, - hideNode, - disableNode, - setInitialStatusFalse, - onInternalUsersChange, - disableRoleDeletion, - setInternalUsers, - validateNewUser, - disableUsername, - disableUserEdit, - isAuthPluginEqualTo, - showExistingCredSection, - showPasswordCredSection, - onRolesMappingChange, - setRolesMapping, - disableRolesEdit, - disableRoleName, - validateNewRole, - disableUserDeletion, - onCustomizeKernelSettingChange, - getInternalUsers, - setApiGroup, - setApiGroupEdit, - getIssuerRefsName, - hasIssuerRefName, - hasNoIssuerRefName, - setClusterAuthMode, - setSSLMode, - showTlsConfigureSection, - onTlsConfigureChange, - showTlsRecommendation, - getAliasOptions, - showMonitoringSection, - onEnableMonitoringChange, - showCustomizeExporterSection, - onCustomizeExporterChange, - disableInitializationSection, - valueExists, - initPrePopulateDatabase, - onPrePopulateDatabaseChange, - initDataSource, - onDataSourceChange, - initVolumeType, - onVolumeTypeChange, - showInitializationForm, - showScriptOrStashForm, - showConfigMapOrSecretName, - initializeNamespace, - showRepositorySelectOrCreate, - onInitRepositoryChoiseChange, - initCustomizeRestoreJobRuntimeSettings, - initCustomizeRestoreJobRuntimeSettingsForBackup, - onCustomizeRestoreJobRuntimeSettingsChange, - onCustomizeRestoreJobRuntimeSettingsChangeForBackup, - showRuntimeForm, - getImagePullSecrets, - getBackupConfigsAndAnnotations, - deleteKubedbComElasticsearchDbAnnotation, - addKubedbComElasticsearchDbAnnotation, - initScheduleBackup, - initScheduleBackupForEdit, - onScheduleBackupChange, - showBackupForm, - initalizeTargetReferenceName, - setInitialRestoreSessionRepo, - initRepositoryChoise, - initRepositoryChoiseForEdit, - onRepositoryChoiseChange, - onRepositoryNameChange, - getMongoAnnotations, - initFromAnnotationValue, - onBackupBlueprintNameChange, - onBackupBlueprintScheduleChange, - initFromAnnotationKeyValue, - onTaskParametersChange, - isValueExistInModel, - onNamespaceChange, - onLabelChange, - onNameChange, - returnFalse, - onAgentChange, - getCreateAuthSecret, - showExistingSecretSection, - showPasswordSection, - encodePassword, - decodePassword, - onCreateAuthSecretChange, - setAuthSecretPassword, - onAuthSecretPasswordChange, - showSecretSection, - getSecrets, - isEqualToServiceMonitorType, - onConfigurationSourceChange, - setConfigurationSource, - getMaxUnavailableOptions, - setConfigFiles, - onConfigFilesChange, - onSetCustomConfigChange, - onSecretConfigurationSourceChange, - setSecretConfigurationSource, - setSecretConfigFiles, - onSecretConfigFilesChange, - onSetSecretCustomConfigChange, - initSetCustomConfig, - initSetSecureCustomConfig, - getOpsRequestUrl, - getCreateNameSpaceUrl, - isVariantAvailable, - setStorageClass, - - initBackupData, - setBackupType, - getTypes, - isBackupDataLoadedTrue, - isBackupType, - getContext, - onContextChange, - getConfigList, - onConfigChange, - showPause, - showSchedule, - showConfigList, - setBlueprintSwitch, - onBlueprintChange, - setArchiverSwitch, - onArchiverChange, - onBackupTypeChange, - isBindingAlreadyOn, - addOrRemoveBinding, - getMachines, - setAllowedMachine, - hasAnnotations, - hasNoAnnotations, - fetchTopologyMachines, - onMachineChange, + return { + // Common helpers + returnFalse, + objectCopy, + isEqualToModelPathValue, + isValueExistInModel, + isRancherManaged, + + // Backup & restore + initScheduleBackup, + initScheduleBackupForEdit, + onScheduleBackupChange, + showBackupForm, + showScheduleBackup, + getDefaultSchedule, + onInputChangeSchedule, + + // New backup data management (KubeStash) + initBackupData, + isBackupDataLoadedTrue, + setBackupType, + getTypes, + onBackupTypeChange, + isBackupType, + setBlueprintSwitch, + onBlueprintChange, + setArchiverSwitch, + onArchiverChange, + getContext, + onContextChange, + getConfigList, + onConfigChange, + showPause, + showConfigList, + showSchedule, + setPausedValue, + + // Gateway binding + addOrRemoveBinding, + isBindingAlreadyOn, + + // Storage autoscaling + handleUnit, + + // Compute autoscaling + getDbDetails, + dbTypeEqualsTo, + setTrigger, + onTriggerChange, + fetchTopologyMachines, + getMachines, + setAllowedMachine, + onMachineChange, + hasAnnotations, + hasNoAnnotations, + setControlledResources, + setValueFromDbDetails, + showOpsRequestOptions, + setApplyToIfReady, + fetchNodeTopology, + isNodeTopologySelected, + setMetadata, + isKubedb, + + // Monitoring + showMonitoringSection, + onEnableMonitoringChange, + showCustomizeExporterSection, + onCustomizeExporterChange, + onAgentChange, + onNamespaceChange, + onLabelChange, + + // Resources & network + getResources, + removeCertificatesOfAliases, + getOpsRequestUrl, + + // ValueFrom (ConfigMap/Secret) + setValueFrom, + isConfigMapTypeValueFrom, + isSecretTypeValueFrom, + onValueFromChange, + getNamespacedResourceList, + resourceNames, + getConfigMapKeys, + getSecrets, + getSecretKeys, + onEnvArrayChange, + initEnvArray, + isEqualToTemp, + initMonitoring, + } } diff --git a/charts/kubedbcom-ferretdb-editor-options/ui/create-ui.yaml b/charts/kubedbcom-ferretdb-editor-options/ui/create-ui.yaml index 96e027e220..606b76c941 100644 --- a/charts/kubedbcom-ferretdb-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-ferretdb-editor-options/ui/create-ui.yaml @@ -1,369 +1,405 @@ -steps: -- form: - discriminator: - bundleApiLoaded: - default: false - type: boolean +step: +- type: single-step-form + loader: initBundle + elements: + - type: label-element + label: '' + subtitle: Select the FerretDB version you want to deploy on Kubernetes. The chosen version determines the FerretDB engine features, compatibility, and runtime behavior of your document database proxy. + - disableUnselect: true + loader: getAdminOptions|databases/FerretDB/versions + if: + type: function + name: isToggleOn|databases/FerretDB/versions + label: Database Version + schema: schema/properties/spec/properties/admin/properties/databases/properties/FerretDB/properties/versions/properties/default + type: select + - init: + type: func + value: getDefault|databases/FerretDB/mode + loader: getAdminOptions|databases/FerretDB/mode + if: + type: function + name: isToggleOn|databases/FerretDB/mode + label: Database Mode + isHorizontal: true + watcher: + func: onModeChange + paths: + - schema/properties/spec/properties/mode + schema: schema/properties/spec/properties/mode + type: radio + - elements: + - type: label-element + label: '' + subtitle: Configure primary FerretDB server nodes that handle read and write operations. Select a machine profile to allocate CPU and memory resources, or choose 'custom' to manually specify requirements. + - label: Replicaset Number + schema: schema/properties/spec/properties/server/properties/primary/properties/replicas + type: input + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/server/properties/primary/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu|server/primary + disable: isMachineNotCustom|server/primary + if: + type: function + name: isMachineCustom|server/primary + label: CPU + loader: setLimits|cpu|server/primary + watcher: + func: setRequests|cpu|server/primary + paths: + - schema/properties/spec/properties/server/properties/primary/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/server/properties/primary/properties/podResources/properties/machine + schema: schema/properties/spec/properties/server/properties/primary/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory|server/primary + disable: isMachineNotCustom|server/primary + if: + type: function + name: isMachineCustom|server/primary + label: Memory + loader: setLimits|memory|server/primary + watcher: + func: setRequests|memory|server/primary + paths: + - schema/properties/spec/properties/server/properties/primary/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/server/properties/primary/properties/podResources/properties/machine + schema: schema/properties/spec/properties/server/properties/primary/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + label: Primary + showLabels: true + type: block-layout + - elements: + - type: label-element + label: '' + subtitle: Configure secondary FerretDB server nodes for read scaling and high availability. Select a machine profile to allocate CPU and memory resources, or choose 'custom' to manually specify requirements. + - label: Replicaset Number + schema: schema/properties/spec/properties/server/properties/secondary/properties/replicas + type: input + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/server/properties/secondary/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu|server/secondary + disable: isMachineNotCustom|server/secondary + if: + type: function + name: isMachineCustom|server/secondary + label: CPU + loader: setLimits|cpu|server/secondary + watcher: + func: setRequests|cpu|server/secondary + paths: + - schema/properties/spec/properties/server/properties/secondary/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/server/properties/secondary/properties/podResources/properties/machine + schema: schema/properties/spec/properties/server/properties/secondary/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory|server/secondary + disable: isMachineNotCustom|server/secondary + if: + type: function + name: isMachineCustom|server/secondary + label: Memory + loader: setLimits|memory|server/secondary + watcher: + func: setRequests|memory|server/secondary + paths: + - schema/properties/spec/properties/server/properties/secondary/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/server/properties/secondary/properties/podResources/properties/machine + schema: schema/properties/spec/properties/server/properties/secondary/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + if: + type: function + name: isEqualToModelPathValue|PrimaryAndSecondary|/spec/mode + label: Secondary + showLabels: true + type: block-layout + - elements: + - type: label-element + label: '' + subtitle: Configure the backend database that FerretDB uses for data storage. Specify storage class, persistent volume size, and replica count. Select a machine profile to allocate CPU and memory resources, or choose 'custom' to manually specify requirements. + - type: horizontal-layout + showLabels: true + elements: + - loader: getAdminOptions|storageClasses + label: Storage Class + schema: schema/properties/spec/properties/admin/properties/storageClasses/properties/default + type: select + - label: Storage Size + schema: schema/properties/spec/properties/backend/properties/persistence/properties/size + type: input + - label: Replicaset Number + schema: schema/properties/spec/properties/backend/properties/replicas + type: input + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/backend/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu|backend + disable: isMachineNotCustom|backend + if: + type: function + name: isMachineCustom|backend + label: CPU + loader: setLimits|cpu|backend + watcher: + func: setRequests|cpu|backend + paths: + - schema/properties/spec/properties/backend/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/backend/properties/podResources/properties/machine + schema: schema/properties/spec/properties/backend/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory|backend + disable: isMachineNotCustom|backend + if: + type: function + name: isMachineCustom|backend + label: Memory + loader: setLimits|memory|backend + watcher: + func: setRequests|memory|backend + paths: + - schema/properties/spec/properties/backend/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/backend/properties/podResources/properties/machine + schema: schema/properties/spec/properties/backend/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + label: Backend + showLabels: true + type: block-layout + - description: Configure Credentials, Deployment Mode etc. elements: - - computed: initBundle - if: returnFalse - type: label-element - - disableUnselect: true - fetch: getAdminOptions|databases/FerretDB/versions - if: isToggleOn|databases/FerretDB/versions - label: - text: labels.database.version - schema: - $ref: schema#/properties/spec/properties/admin/properties/databases/properties/FerretDB/properties/versions/properties/default + - elements: + - type: label-element + label: '' + subtitle: Add custom labels and annotations to your database resources for organization, monitoring, and integration with other Kubernetes tools and services. + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/annotations + label: Labels & Annotations + showLabels: true + hideBlock: true + type: block-layout + - init: + type: func + value: getDefault|deletionPolicy + customClass: mt-20 + if: + type: function + name: isToggleOn|deletionPolicy + label: Deletion Policy + watcher: + func: setStorageClass + paths: + - schema/properties/spec/properties/deletionPolicy + options: + - description: options.deletionPolicy.delete.description + text: Delete + value: Delete + - description: options.deletionPolicy.halt.description + text: Halt + value: Halt + - description: options.deletionPolicy.wipeOut.description + text: WipeOut + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: DoNotTerminate + value: DoNotTerminate + schema: schema/properties/spec/properties/deletionPolicy type: select - - computed: getDefault|databases/FerretDB/mode - fetch: getAdminOptions|databases/FerretDB/mode - hasDescription: true - if: isToggleOn|databases/FerretDB/mode - label: - text: labels.database.mode - onChange: onModeChange - schema: - $ref: schema#/properties/spec/properties/mode + - if: + type: function + name: getDefaultValue|spec/admin/authCredential/customize + label: Provide Authentication Credentials? + watcher: + func: onAuthChange + paths: + - temp/createAuthSecret + schema: temp/createAuthSecret + type: switch + - if: + type: function + name: showReferSecretSwitch + label: Refer existing Secret? + watcher: + func: onReferSecretChange + paths: + - temp/referSecret + schema: temp/referSecret + type: switch + - loader: getReferSecrets + if: + type: function + name: showSecretDropdown + label: Secret + schema: schema/properties/spec/properties/authSecret/properties/name + type: select + - if: + type: function + name: showReferSecret + label: password + schema: schema/properties/spec/properties/authSecret/properties/password + type: input + - if: + type: function + name: getDefaultValue|spec/admin/customConfiguration + label: Configure Database? + watcher: + func: clearConfiguration + paths: + - temp/configDatabase + schema: temp/configDatabase + type: switch + - if: + type: function + name: isConfigDatabaseOn + label: Configuration + # hasCopy: true + schema: schema/properties/spec/properties/configuration + type: textarea + - if: + type: function + name: isToggleOn|deployment + label: Deployment name + options: + - description: labels.deployment.shared + text: Shared + value: Shared + - description: labels.deployment.dedicated + text: Dedicated + value: Dedicated + schema: schema/properties/spec/properties/admin/properties/deployment/properties/default type: radio - - elements: - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/server/properties/primary/properties/replicas - type: input - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/server/properties/primary/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu|server/primary - disabled: isMachineNotCustom - if: isMachineCustom|server/primary - label: - text: labels.cpu - onChange: setRequests|cpu|server/primary - schema: - $ref: schema#/properties/spec/properties/server/properties/primary/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory|server/primary - disabled: isMachineNotCustom - if: isMachineCustom|server/primary - label: - text: labels.memory - onChange: setRequests|memory|server/primary - schema: - $ref: schema#/properties/spec/properties/server/properties/primary/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - label: - text: Primary - show_label: true - type: single-step-form - - elements: - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/server/properties/secondary/properties/replicas - type: input - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/server/properties/secondary/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu|server/secondary - disabled: isMachineNotCustom - if: isMachineCustom|server/secondary - label: - text: labels.cpu - onChange: setRequests|cpu|server/secondary - schema: - $ref: schema#/properties/spec/properties/server/properties/secondary/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory|server/secondary - disabled: isMachineNotCustom - if: isMachineCustom|server/secondary - label: - text: labels.memory - onChange: setRequests|memory|server/secondary - schema: - $ref: schema#/properties/spec/properties/server/properties/secondary/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - if: isEqualToModelPathValue|PrimaryAndSecondary|/spec/mode - label: - text: Secondary - show_label: true - type: single-step-form - - fetch: getAdminOptions|storageClasses - label: - text: labels.storage.class - schema: - $ref: schema#/properties/spec/properties/admin/properties/storageClasses/properties/default + - if: + type: function + name: isToggleOn|clusterTier + isHorizontal: true + label: Cluster Tier + options: + - text: General Purpose + value: GeneralPurpose + - text: Memory Optimized + value: MemoryOptimized + - text: CPU Optimized + value: CPUOptimized + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/default + type: radio + - disableUnselect: true + loader: getAdminOptions|clusterTier/placement + if: + type: function + name: isToggleOn|clusterTier/placement + label: Placement + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + type: select + - disableUnselect: true + loader: getNodeTopology + if: + type: function + name: isToggleOn|clusterTier/nodeTopology + label: Node Topology + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default type: select + label: Advanced Configuration + showLabels: true + type: block-layout + - description: Enable Backup, Monitoring, TLS etc. + elements: - elements: - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/backend/properties/persistence/properties/size - type: input - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/backend/properties/replicas - type: input - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/backend/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu|backend - disabled: isMachineNotCustom - if: isMachineCustom|backend - label: - text: labels.cpu - onChange: setRequests|cpu|backend - schema: - $ref: schema#/properties/spec/properties/backend/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory|backend - disabled: isMachineNotCustom - if: isMachineCustom|backend - label: - text: labels.memory - onChange: setRequests|memory|backend - schema: - $ref: schema#/properties/spec/properties/backend/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - label: - text: Backend - show_label: true - type: single-step-form - - accordion: true - description: - text: Configure Credentials, Deployment Mode etc. - discriminator: - backend: - default: {} - type: object - configDatabase: - default: false - type: boolean - createAuthSecret: - default: false - type: boolean - referSecret: - default: false - type: boolean - elements: - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties - type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties - type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - computed: getDefault|deletionPolicy - customClass: mt-20 - if: isToggleOn|deletionPolicy - 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/spec/properties/deletionPolicy - type: select - - if: getDefaultValue|spec/admin/authCredential/customize - label: - text: Provide Authentication Credentials? - onChange: onAuthChange - schema: - $ref: discriminator#/createAuthSecret + - init: + type: func + value: setMonitoring + label: Enable Monitoring? + watcher: + func: updateAlertValue + paths: + - temp/monitoring + schema: temp/monitoring type: switch - - if: showReferSecretSwitch - label: - text: Refer existing Secret? - onChange: onReferSecretChange - schema: - $ref: discriminator#/referSecret + if: + type: function + name: isToggleOn|monitoring + type: block-layout + - elements: + - init: + type: func + value: checkHostnameOrIP + if: + type: function + name: isToggleOn|tls + label: Enable TLS? + watcher: + func: checkHostnameOrIP + paths: + - schema/properties/spec/properties/admin/properties/tls/properties/default + schema: schema/properties/spec/properties/admin/properties/tls/properties/default type: switch - - fetch: getReferSecrets - if: showSecretDropdown - label: - text: Secret - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/name + - loader: getAdminOptions|clusterIssuers + if: + type: function + name: showIssuer + label: Cluster Issuers + validation: + type: required + schema: schema/properties/spec/properties/admin/properties/clusterIssuers/properties/default type: select - - if: showReferSecret - label: - text: labels.password - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/password - type: input - - computed: isConfigAvailable - if: getDefaultValue|spec/admin/customConfiguration - label: - text: Configure Database? - onChange: clearConfiguration - schema: - $ref: discriminator#/configDatabase + type: block-layout + - elements: + - init: + type: func + value: checkHostnameOrIP + label: Expose via Gateway? + watcher: + func: checkHostnameOrIP + paths: + - schema/properties/spec/properties/admin/properties/expose/properties/default + schema: schema/properties/spec/properties/admin/properties/expose/properties/default type: switch - - if: isConfigDatabaseOn - label: - text: Configuration - schema: - $ref: schema#/properties/spec/properties/configuration - type: editor - - hasDescription: true - if: isToggleOn|deployment - label: - text: labels.deployment.name - options: - - description: labels.deployment.shared - text: Shared - value: Shared - - description: labels.deployment.dedicated - text: Dedicated - value: Dedicated - schema: - $ref: schema#/properties/spec/properties/admin/properties/deployment/properties/default - type: radio - - if: isToggleOn|clusterTier - isHorizontal: true - label: - text: labels.clusterTier - options: - - text: General Purpose - value: GeneralPurpose - - text: Memory Optimized - value: MemoryOptimized - - text: CPU Optimized - value: CPUOptimized - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/default - type: radio - - disableUnselect: true - fetch: getAdminOptions|clusterTier/placement - if: isToggleOn|clusterTier/placement - label: - text: labels.placement - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default - type: select - - disableUnselect: true - fetch: getNodeTopology - if: isToggleOn|clusterTier/nodeTopology - label: - text: labels.nodeTopology - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default - type: select - hideForm: true - label: - text: Advanced Configuration - show_label: true - type: single-step-form - - accordion: true - description: - text: Enable Backup, Monitoring, TLS etc. - discriminator: - backup: - default: false - type: boolean - elements: - - discriminator: - monitoring: - default: false - type: boolean - elements: - - computed: setMonitoring - label: - text: labels.enable_monitoring - onChange: updateAlertValue - schema: - $ref: discriminator#/monitoring - type: switch - if: isToggleOn|monitoring - type: single-step-form - - elements: - - computed: checkHostnameOrIP - if: isToggleOn|tls - label: - text: Enable TLS? - onChange: checkHostnameOrIP - schema: - $ref: schema#/properties/spec/properties/admin/properties/tls/properties/default - type: switch - - fetch: getAdminOptions|clusterIssuers - if: showIssuer - label: - text: labels.clusterIssuers - required: true - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterIssuers/properties/default - type: select - type: single-step-form - - elements: - - computed: checkHostnameOrIP - label: - text: Expose via Gateway? - onChange: checkHostnameOrIP - schema: - $ref: schema#/properties/spec/properties/admin/properties/expose/properties/default - type: switch - if: isToggleOn|expose - type: single-step-form - if: showAdditionalSettings - label: - text: Additional Options - show_label: true - type: single-step-form - type: single-step-form + if: + type: function + name: isToggleOn|expose + type: block-layout + if: + type: function + name: showAdditionalSettings + label: Additional Options + showLabels: true + type: block-layout id: options - title: steps.0.label + # title: steps.0.label type: multi-step-form diff --git a/charts/kubedbcom-ferretdb-editor-options/ui/functions.js b/charts/kubedbcom-ferretdb-editor-options/ui/functions.js index 8b62a4df00..24a4e17779 100644 --- a/charts/kubedbcom-ferretdb-editor-options/ui/functions.js +++ b/charts/kubedbcom-ferretdb-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -315,941 +317,990 @@ const modeDetails = { }, } -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) -function onModeChange({ model, getValue, commit }) { - const dbMode = getValue(model, '/spec/mode') - commit('wizard/model$update', { - path: '/spec/replicas', - value: dbMode === 'Replicaset' ? 3 : 1, - force: true, - }) -} + setDiscriminatorValue('bundleApiLoaded', false) + setDiscriminatorValue('configDatabase', false) + setDiscriminatorValue('createAuthSecret', false) + setDiscriminatorValue('referSecret', false) + setDiscriminatorValue('backup', false) + setDiscriminatorValue('monitoring', false) + + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } -function getMachineListForOptions({ model, getValue }) { - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') + function onModeChange() { + const dbMode = getValue(model, '/spec/mode') + commit('wizard/model$update', { + path: '/spec/replicas', + value: dbMode === 'Replicaset' ? 3 : 1, + force: true, + }) + } let array = [] + function getMachineListForOptions() { + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') - if (available.length) { - array = available.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - else { - let subText = '', - text = '' - const machineData = machinesFromPreset.find((val) => val.id === machine) - if (machineData) { - subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` - text = machineData.name ? machineData.name : machineData.id - } - return { text, subText, value: machine } - } - }) - } else { - array = machineList - .map((machine) => { + if (available.length) { + array = available.map((machine) => { if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + else { + let subText = '', + text = '' + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + text = machineData.name ? machineData.name : machineData.id + } + return { text, subText, value: machine } + } }) - .filter((val) => !!val) + } else { + array = machineList + .map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { text, subText, value: machine } + }) + .filter((val) => !!val) + } + return array } - return array -} -function setLimits({ model, getValue, commit, watchDependency }, resource, type) { - const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' - watchDependency(`model#${path}`) - const selectedMachine = getValue(model, path) || 'custom' - const reqCommitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - const comparePath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - - const resourceValue = getValue(model, comparePath) - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - - let cpu = '', - memory = '' - if (available.length && selectedMachine !== 'custom') { - const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) - if (machineData) { - cpu = machineData.limits.cpu - memory = machineData.limits.memory + function setLimits(resource, type) { + const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' + // watchDependency(`model#${path}`) + const selectedMachine = getValue(model, path) || 'custom' + const reqCommitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + const comparePath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + + const resourceValue = getValue(model, comparePath) + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + let cpu = '', + memory = '' + if (available.length && selectedMachine !== 'custom') { + const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) + if (machineData) { + cpu = machineData.limits.cpu + memory = machineData.limits.memory + } + } else { + if (selectedMachine === 'custom') { + cpu = resourceValue + memory = resourceValue + } else { + cpu = machines[selectedMachine].resources.limits.cpu + memory = machines[selectedMachine].resources.limits.memory + } } - } else { - if (selectedMachine === 'custom') { - cpu = resourceValue - memory = resourceValue + + if (resource === 'memory') { + commit('wizard/model$update', { + path: reqCommitPath, + value: memory, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: memory, + force: true, + }) + return memory } else { - cpu = machines[selectedMachine].resources.limits.cpu - memory = machines[selectedMachine].resources.limits.memory + commit('wizard/model$update', { + path: reqCommitPath, + value: cpu, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: cpu, + force: true, + }) + return cpu } } - if (resource === 'memory') { - commit('wizard/model$update', { - path: reqCommitPath, - value: memory, - force: true, - }) + function setRequests(resource, type) { + const modelPath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + + const fullpath = `/spec/podResources/machine` + const modelPathValue = getValue(model, fullpath) + commit('wizard/model$update', { - path: comparePath, - value: memory, + path: commitPath, + value: val, force: true, }) - return memory - } else { - commit('wizard/model$update', { - path: reqCommitPath, - value: cpu, - force: true, + + if (modelPathValue === 'custom') { + return + } + let commitCpuMemory, ModelPathValue + if (resource && type) { + const fullPath = `/spec/${type}/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/${type}/podResources/resources/requests/${resource}` + } else { + const fullPath = `/spec/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/podResources/resources/requests/${resource}` + } + let cpuMemoryValue + array.forEach((item) => { + if (item.value === ModelPathValue) { + // Parse subText like "CPU: 2, Memory: 2Gi" + const subText = item.subText || '' + if (resource === 'cpu') { + // Extract CPU value + const cpuMatch = subText.match(/CPU:\s*([^,]+)/) + cpuMemoryValue = cpuMatch ? cpuMatch[1].trim() : '' + } else if (resource === 'memory') { + // Extract Memory value + const memoryMatch = subText.match(/Memory:\s*(.+)/) + cpuMemoryValue = memoryMatch ? memoryMatch[1].trim() : '' + } + } }) commit('wizard/model$update', { - path: comparePath, - value: cpu, + path: commitCpuMemory, + value: cpuMemoryValue, force: true, }) - return cpu + return cpuMemoryValue } -} - -function setRequests({ getValue, model, commit }, resource, type) { - const modelPath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - const val = getValue(model, modelPath) - commitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - commit('wizard/model$update', { - path: commitPath, - value: val, - force: true, - }) -} -function setMachineToCustom({ getValue, model }) { - const machine = getValue(model, '/spec/admin/machineProfiles/default') - return machine || 'custom' -} + function setMachineToCustom() { + const machine = getValue(model, '/spec/admin/machineProfiles/default') + return machine || 'custom' + } -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function getCreateNameSpaceUrl() { + 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + const domain = storeGet('/domain') || '' + if (domain.includes('bb.test')) { + return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } } -} -const ifCapiProviderIsNotEmpty = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/provider') - const val = getValue(model, '/form/capi/provider') - if (val) return true -} + const ifCapiProviderIsNotEmpty = () => { + // watchDependency('model#/form/capi/provider') + const val = getValue(model, '/form/capi/provider') + if (val) return true + } -const showMultiselectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') + const showMultiselectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') - if (val === 'capz' && ifDedicated({ model, getValue })) return true -} + if (val === 'capz' && ifDedicated()) return true + } -const showSelectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') - if (val !== 'capz' && ifDedicated({ model, getValue })) return true -} + const showSelectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') + if (val !== 'capz' && ifDedicated()) return true + } -const ifDedicated = ({ model, getValue }) => { - const val = getValue(model, 'form/capi/dedicated') - if (val) return true -} + const ifDedicated = () => { + const val = getValue(model, 'form/capi/dedicated') + if (val) return true + } -const dedicatedOnChange = ({ model, getValue, commit }) => { - const val = getValue(model, 'form/capi/dedicated') - if (!val) { - commit('wizard/model$delete', 'form/capi/zones') - commit('wizard/model$delete', 'form/capi/sku') + const dedicatedOnChange = () => { + const val = getValue(model, 'form/capi/dedicated') + if (!val) { + commit('wizard/model$delete', 'form/capi/zones') + commit('wizard/model$delete', 'form/capi/sku') + } } -} -const ifZones = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/zones') - watchDependency('model#/form/capi/dedicated') - const zones = getValue(model, 'form/capi/zones') || [] - const isDedicated = getValue(model, 'form/capi/dedicated') - if (zones.length && isDedicated) return true -} + const ifZones = () => { + // watchDependency('model#/form/capi/zones') + // watchDependency('model#/form/capi/dedicated') + const zones = getValue(model, 'form/capi/zones') || [] + const isDedicated = getValue(model, 'form/capi/dedicated') + if (zones.length && isDedicated) return true + } -const zonesOnChange = ({ model, getValue, commit }) => { - const zones = getValue(model, 'form/capi/zones') || [] - if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') -} + const zonesOnChange = () => { + const zones = getValue(model, 'form/capi/zones') || [] + if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') + } -async function getZones({ storeGet, axios, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const isDedicated = getValue(model, 'form/capi/dedicated') - if (isDedicated) { - try { - const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) - const val = resp.data.map((item) => { - return { value: item, text: item } - }) - return val - } catch (e) { - console.log(e) - return [] + async function getZones() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const isDedicated = getValue(model, 'form/capi/dedicated') + if (isDedicated) { + try { + const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) + const val = resp.data.map((item) => { + return { value: item, text: item } + }) + return val + } catch (e) { + console.log(e) + return [] + } } } -} -async function getSKU({ storeGet, axios, model, getValue, watchDependency }) { - watchDependency('model#/form/capi/zones') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const zones = getValue(model, 'form/capi/zones') || [] - if (zones.length) { - try { - let url = `clustersv2/${owner}/${cluster}/vms?` - if (typeof zones === 'string') { - url += `zones=${encodeURIComponent(zones)}` - } else { - zones.forEach((item) => { - url += `zones=${encodeURIComponent(item)}&` + async function getSKU() { + // watchDependency('model#/form/capi/zones') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const zones = getValue(model, 'form/capi/zones') || [] + if (zones.length) { + try { + let url = `clustersv2/${owner}/${cluster}/vms?` + if (typeof zones === 'string') { + url += `zones=${encodeURIComponent(zones)}` + } else { + zones.forEach((item) => { + url += `zones=${encodeURIComponent(item)}&` + }) + url = url.slice(0, -1) + } + const resp = await axios.get(url) + const val = resp.data.map((item) => { + return { + value: item.name, + text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, + } }) - url = url.slice(0, -1) + return val + } catch (e) { + console.log(e) + return [] } - const resp = await axios.get(url) - const val = resp.data.map((item) => { - return { - value: item.name, - text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, - } - }) - return val - } catch (e) { - console.log(e) - return [] } } -} -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} - -function setStorageClass({ model, getValue, commit, discriminator, watchDependency }) { - const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' - let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' - const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] - const suffix = '-retain' - - const simpleClassList = storageClassList.filter((item) => { - return !item.endsWith(suffix) - }) - const retainClassList = storageClassList.filter((item) => { - return item.endsWith(suffix) - }) - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] - } else { - storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false } - const isChangeable = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'storageClasses', - ) - if (isChangeable && storageClass) { - commit('wizard/model$update', { - path: '/spec/admin/storageClasses/default', - value: storageClass, - force: true, - }) - } -} + function setStorageClass() { + const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' + let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' + const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] + const suffix = '-retain' -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], - }, - }, - ) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace + const simpleClassList = storageClassList.filter((item) => { + return !item.endsWith(suffix) + }) + const retainClassList = storageClassList.filter((item) => { + return item.endsWith(suffix) + }) + if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { + storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] } else { - return resp.data?.status?.namespaces || [] + storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] } - } catch (e) { - console.log(e) - } - return [] -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} -let placement = [] -let versions = [] -let storageClass = [] -let clusterIssuers = [] -let nodetopologiesShared = [] -let nodetopologiesDedicated = [] -let features = [] -let hostName = '' -let ip = '' -async function initBundle({ commit, model, getValue, axios, storeGet, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - - let db = getValue(model, '/metadata/resource/kind') - db = db.toLowerCase() - let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` - const gatewayinfosurl = `/clusters/${owner}/${cluster}/proxy/meta.k8s.appscode.com/v1alpha1/gatewayinfos/${namespace}` - const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - - try { - const resp = await axios.get(url) - features = resp.data.features || [] - placement = resp.data.placementpolicies || [] - versions = resp.data.versions || [] - storageClass = resp.data.storageclasses || [] - clusterIssuers = resp.data.clusterissuers || [] - nodetopologiesDedicated = resp.data.dedicated || [] - nodetopologiesShared = resp.data.shared || [] - - const response = await axios.get(annotationUrl) - const annotations = response.data?.metadata?.annotations || {} - const uidRange = annotations['openshift.io/sa.scc.uid-range'] - if (uidRange) { - const val = uidRange.split('/')[0] + const isChangeable = isToggleOn('storageClasses') + if (isChangeable && storageClass) { commit('wizard/model$update', { - path: '/spec/openshift/securityContext/runAsUser', - value: val, + path: '/spec/admin/storageClasses/default', + value: storageClass, force: true, }) } - const gatewayinfosResp = await axios.get(gatewayinfosurl) - hostName = gatewayinfosResp.data?.spec?.hostName - ip = gatewayinfosResp.data?.spec?.ip - } catch (e) { - console.log(e) } - commit('wizard/model$update', { - path: '/spec/deletionPolicy', - value: getDefault({ getValue, model }, 'deletionPolicy'), - force: true, - }) - - if (!getValue(model, `/spec/admin/databases/FerretDB/mode/toggle`)) { - let defMode = getDefault({ getValue, model }, 'databases/FerretDB/mode') || '' - if (defMode === '') { - const arr = getValue(model, '/spec/databases/FerretDB/mode/available') || [] - if (arr.length) defMode = arr[0] + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, + }, + ) + if (resp.data?.status?.projects) { + const projects = resp.data?.status?.projects + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } + } catch (e) { + console.log(e) } - commit('wizard/model$update', { - path: '/spec/mode', - value: defMode, - force: true, - }) + return [] } - if (!features.includes('tls')) { - commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: false, - force: true, - }) - } - if (!features.includes('binding')) { - commit('wizard/model$update', { - path: '/spec/admin/expose/default', - value: false, - force: true, - }) - } - if (!features.includes('monitoring')) { - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: 'none', - force: true, - }) - } - if (!features.includes('backup')) { - commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, - force: true, - }) - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: '', - force: true, - }) + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found } - setDiscriminatorValue('/bundleApiLoaded', true) -} + let placement = [] + let versions = [] + let storageClass = [] + let clusterIssuers = [] + let nodetopologiesShared = [] + let nodetopologiesDedicated = [] + let features = [] + let hostName = '' + let ip = '' + + async function initBundle() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + + let db = getValue(model, '/metadata/resource/kind') + db = db.toLowerCase() + let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` + const gatewayinfosurl = `/clusters/${owner}/${cluster}/proxy/meta.k8s.appscode.com/v1alpha1/gatewayinfos/${namespace}` + const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` -function fetchOptions({ model, getValue, commit }, type) { - let kind = getValue(model, '/metadata/resource/kind') - - let returnArray = [] - if (type === 'clusterTier/placement') { - returnArray = placement - } else if (type === `databases/${kind}/versions`) { - returnArray = versions - } else if (type === 'storageClasses') { - returnArray = storageClass - } else if (type === 'clusterIssuers') { - returnArray = clusterIssuers - } + try { + const resp = await axios.get(url) + features = resp.data.features || [] + placement = resp.data.placementpolicies || [] + versions = resp.data.versions || [] + storageClass = resp.data.storageclasses || [] + clusterIssuers = resp.data.clusterissuers || [] + nodetopologiesDedicated = resp.data.dedicated || [] + nodetopologiesShared = resp.data.shared || [] + + const response = await axios.get(annotationUrl) + const annotations = response.data?.metadata?.annotations || {} + const uidRange = annotations['openshift.io/sa.scc.uid-range'] + if (uidRange) { + const val = uidRange.split('/')[0] + commit('wizard/model$update', { + path: '/spec/openshift/securityContext/runAsUser', + value: val, + force: true, + }) + } + const gatewayinfosResp = await axios.get(gatewayinfosurl) + hostName = gatewayinfosResp.data?.spec?.hostName + ip = gatewayinfosResp.data?.spec?.ip + } catch (e) { + console.log(e) + } - if (returnArray.length === 1) { - const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: path, - value: returnArray[0], + path: '/spec/deletionPolicy', + value: getDefault('deletionPolicy'), force: true, }) - } - return returnArray -} + if (!getValue(model, `/spec/admin/databases/FerretDB/mode/toggle`)) { + let defMode = getDefault('databases/FerretDB/mode') || '' + if (defMode === '') { + const arr = getValue(model, '/spec/databases/FerretDB/mode/available') || [] + if (arr.length) defMode = arr[0] + } + commit('wizard/model$update', { + path: '/spec/mode', + value: defMode, + force: true, + }) + } -function getAdminOptions({ getValue, model, watchDependency, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') - const options = getValue(model, `/spec/admin/${type}/available`) || [] + if (!features.includes('tls')) { + commit('wizard/model$update', { + path: '/spec/admin/tls/default', + value: false, + force: true, + }) + } + if (!features.includes('binding')) { + commit('wizard/model$update', { + path: '/spec/admin/expose/default', + value: false, + force: true, + }) + } + if (!features.includes('monitoring')) { + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: 'none', + force: true, + }) + } + if (!features.includes('backup')) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: '', + force: true, + }) + } - if (options.length === 0) { - return fetchOptions({ model, getValue, commit }, type) - } - if (type.endsWith('/mode')) { - return ( - options?.map((item) => ({ - description: modeDetails[item]?.description || '', - text: modeDetails[item]?.text || '', - value: item, - })) || [] - ) + setDiscriminatorValue('/bundleApiLoaded', true) } - return options -} - -function checkIfFeatureOn({ getValue, model }, type) { - let val = getValue(model, `/spec/admin/${type}/toggle`) - if (type === 'backup' || type === 'archiver') { - val = getValue(model, `/spec/admin/${type}/enable/toggle`) - } - const backupVal = getValue(model, '/spec/backup/tool') - - if (type === 'backup') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } else if (type === 'tls') { - return features.includes('tls') && val - } else if (type === 'expose') { - return features.includes('binding') && val - } else if (type === 'monitoring') { - return features.includes('monitoring') && val - } else if (type === 'archiver') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } -} + function fetchOptions(type) { + let kind = getValue(model, '/metadata/resource/kind') + + let returnArray = [] + if (type === 'clusterTier/placement') { + returnArray = placement + } else if (type === `databases/${kind}/versions`) { + returnArray = versions + } else if (type === 'storageClasses') { + returnArray = storageClass + } else if (type === 'clusterIssuers') { + returnArray = clusterIssuers + } -function isToggleOn({ getValue, model, discriminator, watchDependency }, type) { - watchDependency('discriminator#/bundleApiLoaded') - watchDependency('model#/spec/admin/deployment/default') - const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') - let deploymentType = getValue(model, `/spec/admin/deployment/default`) - if ( - type === 'tls' || - type === 'backup' || - type === 'expose' || - type === 'monitoring' || - type === 'archiver' - ) { - return checkIfFeatureOn({ getValue, model }, type) - } else if ( - type === 'clusterTier' || - type === 'clusterTier/placement' || - type === 'clusterTier/nodeTopology' - ) { - if (deploymentType === 'Dedicated' && bundleApiLoaded) return true - else return false - } else if (type === 'deployment') { - const deploymentType = getValue(model, '/spec/admin/deployment/default') - if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + if (returnArray.length === 1) { + const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: '/spec/admin/deployment/default', - value: 'Shared', + path: path, + value: returnArray[0], force: true, }) } - return ( - getValue(model, `/spec/admin/${type}/toggle`) && - nodetopologiesDedicated.length && - bundleApiLoaded - ) - } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded -} -async function getNodeTopology({ model, getValue, axios, storeGet, watchDependency }) { - watchDependency('model#/spec/admin/deployment/default') - watchDependency('model#/spec/admin/clusterTier/default') - const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' - const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' - let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + return returnArray + } - const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + function getAdminOptions(type) { + // watchDependency('discriminator#/bundleApiLoaded') + const options = getValue(model, `/spec/admin/${type}/available`) || [] - if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared - else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + if (options.length === 0) { + return fetchOptions(type) + } + if (type.endsWith('/mode')) { + return ( + options?.map((item) => ({ + description: modeDetails[item]?.description || '', + text: modeDetails[item]?.text || '', + value: item, + })) || [] + ) + } - const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) - return filteredList -} + return options + } + + let backupToolInitialValue = '' + function checkIfFeatureOn(type) { + let val = getValue(model, `/spec/admin/${type}/toggle`) + if (type === 'backup' || type === 'archiver') { + val = getValue(model, `/spec/admin/${type}/enable/toggle`) + } + const backupVal = getValue(model, '/spec/backup/tool') + if (type === 'backup') { + if (backupToolInitialValue === '') { + backupToolInitialValue = + features.includes('backup') && backupVal === 'KubeStash' && val ? 'on' : 'off' + return features.includes('backup') && backupVal === 'KubeStash' && val + } else { + if (backupToolInitialValue === 'on') { + return true + } else { + return false + } + } + } else if (type === 'tls') { + return features.includes('tls') && val + } else if (type === 'expose') { + return features.includes('binding') && val + } else if (type === 'monitoring') { + return features.includes('monitoring') && val + } else if (type === 'archiver') { + return features.includes('backup') && val + } + } -function filterNodeTopology(list, tier, provider) { - // first filter the list from value that exists from the filtered list got from API - const filteredlist = list + function isToggleOn(type) { + // watchDependency('discriminator#/bundleApiLoaded') + // watchDependency('model#/spec/admin/deployment/default') + const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') + let deploymentType = getValue(model, `/spec/admin/deployment/default`) + if ( + type === 'tls' || + type === 'backup' || + type === 'expose' || + type === 'monitoring' || + type === 'archiver' + ) { + return checkIfFeatureOn(type) + } else if ( + type === 'clusterTier' || + type === 'clusterTier/placement' || + type === 'clusterTier/nodeTopology' + ) { + if (deploymentType === 'Dedicated' && bundleApiLoaded) return true + else return false + } else if (type === 'deployment') { + const deploymentType = getValue(model, '/spec/admin/deployment/default') + if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + commit('wizard/model$update', { + path: '/spec/admin/deployment/default', + value: 'Shared', + force: true, + }) + } + return ( + getValue(model, `/spec/admin/${type}/toggle`) && + nodetopologiesDedicated.length && + bundleApiLoaded + ) + } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded + } - // filter the list based on clusterTier - if (provider === 'EKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('c') - else if (tier === 'MemoryOptimized') return item.startsWith('r') - else return !item.startsWith('c') && !item.startsWith('r') - }) - } else if (provider === 'AKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - else - return ( - !(item.startsWith('f') || item.startsWith('fx')) && - !( + async function getNodeTopology() { + // watchDependency('model#/spec/admin/deployment/default') + // watchDependency('model#/spec/admin/clusterTier/default') + const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' + const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' + let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + + const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + + if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared + else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + + const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) + return filteredList + } + + function filterNodeTopology(list, tier, provider) { + // first filter the list from value that exists from the filtered list got from API + const filteredlist = list + + // filter the list based on clusterTier + if (provider === 'EKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('c') + else if (tier === 'MemoryOptimized') return item.startsWith('r') + else return !item.startsWith('c') && !item.startsWith('r') + }) + } else if (provider === 'AKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('e') || item.startsWith('eb') || item.startsWith('ec') || item.startsWith('m') || item.startsWith('d') ) - ) - }) - } else if (provider === 'GKE') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') - return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - else - return ( - !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && - !( + else + return ( + !(item.startsWith('f') || item.startsWith('fx')) && + !( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + ) + }) + } else if (provider === 'GKE') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') + return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('x4') || item.startsWith('m1') || item.startsWith('m2') || item.startsWith('m3') ) - ) - }) - } else return filteredlist -} + else + return ( + !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && + !( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + ) + }) + } else return filteredlist + } -function returnFalse() { - return false -} + function returnFalse() { + return false + } -function isMachineCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue === 'custom' -} + function isMachineCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue === 'custom' + } -function isMachineNotCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue !== 'custom' && !!modelPathValue -} + function isMachineNotCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue !== 'custom' && !!modelPathValue + } -function onAuthChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/authSecret/password', - value: '', - force: true, - }) -} + function onAuthChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/spec/authSecret/password', + value: '', + force: true, + }) + } -function clearConfiguration({ discriminator, getValue, commit }) { - const configOn = getValue(discriminator, '/configDatabase') + function clearConfiguration() { + const configOn = getValue(discriminator, '/configDatabase') - if (!configOn) { - commit('wizard/model$delete', '/spec/configuration') + if (!configOn) { + commit('wizard/model$delete', '/spec/configuration') + } } -} -function isConfigDatabaseOn({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configDatabase') - return getValue(discriminator, '/configDatabase') -} + function isConfigDatabaseOn() { + // watchDependency('discriminator#/configDatabase') + return getValue(discriminator, '/configDatabase') + } -function showIssuer({ model, getValue, watchDependency, discriminator }) { - watchDependency('model#/spec/admin/tls/default') - const isTlsEnabled = getValue(model, '/spec/admin/tls/default') - const isIssuerToggleEnabled = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'clusterIssuers', - ) - return isTlsEnabled && isIssuerToggleEnabled -} + function showIssuer() { + // watchDependency('model#/spec/admin/tls/default') + const isTlsEnabled = getValue(model, '/spec/admin/tls/default') + const isIssuerToggleEnabled = isToggleOn('clusterIssuers') + return isTlsEnabled && isIssuerToggleEnabled + } -function setMonitoring({ getValue, model }) { - const agent = getValue(model, '/spec/admin/monitoring/agent') || '' - return !!agent -} + function setMonitoring() { + const agent = getValue(model, '/spec/admin/monitoring/agent') || '' + return !!agent + } -function updateAlertValue({ commit, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const alert = isMonitorEnabled ? 'warning' : 'none' - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: alert, - force: true, - }) - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} + function updateAlertValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const alert = isMonitorEnabled ? 'warning' : 'none' + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: alert, + force: true, + }) + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: agent, + force: true, + }) + } -function showAlerts({ watchDependency, model, getValue, discriminator }) { - watchDependency('discriminator#/monitoring') - const isMonitorEnabled = getValue(discriminator, '/monitoring') - return ( - isMonitorEnabled && isToggleOn({ getValue, model, discriminator, watchDependency }, 'alert') - ) -} + function showAlerts() { + // watchDependency('discriminator#/monitoring') + const isMonitorEnabled = getValue(discriminator, '/monitoring') + return isMonitorEnabled && isToggleOn('alert') + } -function setBackup({ model, getValue }) { - const backup = getValue(model, '/spec/backup/tool') - const val = getValue(model, '/spec/admin/backup/enable/default') - return backup === 'KubeStash' && features.includes('backup') && val -} + function setBackup() { + const backup = getValue(model, '/spec/backup/tool') + const val = getValue(model, '/spec/admin/backup/enable/default') + return backup === 'KubeStash' && features.includes('backup') && val + } -function onBackupSwitch({ discriminator, getValue, commit }) { - const isBackupOn = getValue(discriminator, '/backup') - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: isBackupOn ? 'KubeStash' : '', - force: true, - }) -} + function onBackupSwitch() { + const isBackupOn = getValue(discriminator, '/backup') + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: isBackupOn ? 'KubeStash' : '', + force: true, + }) + } -function onRefChange({ discriminator, getValue, commit }, type) { - const ref = getValue(discriminator, `/${type}`) || {} - commit('wizard/model$update', { - path: `/spec/${type}/name`, - value: ref.name || '', - force: true, - }) - commit('wizard/model$update', { - path: `/spec/${type}/namespace`, - value: ref.namespace || '', - force: true, - }) -} + function onRefChange(type) { + const ref = getValue(discriminator, `/${type}`) || {} + commit('wizard/model$update', { + path: `/spec/${type}/name`, + value: ref.name || '', + force: true, + }) + commit('wizard/model$update', { + path: `/spec/${type}/namespace`, + value: ref.namespace || '', + force: true, + }) + } -function isExternallyManaged( - { getValue, model, watchDependency, commit, setDiscriminatorValue }, - type, -) { - watchDependency(`model#/spec/${type}/externallyManaged`) - const isManaged = getValue(model, `/spec/${type}/externallyManaged`) || false - if (!isManaged) clearRefs({ commit, setDiscriminatorValue }, type) - return isManaged -} + function isExternallyManaged(type) { + // watchDependency(`model#/spec/${type}/externallyManaged`) + const isManaged = getValue(model, `/spec/${type}/externallyManaged`) || false + if (!isManaged) clearRefs(type) + return isManaged + } -function clearRefs({ commit, setDiscriminatorValue }, type) { - setDiscriminatorValue(`/${type}`, '') - commit('wizard/model$update', { - path: `/spec/${type}/name`, - value: '', - force: true, - }) - commit('wizard/model$update', { - path: `/spec/${type}/namespace`, - value: '', - force: true, - }) -} + function clearRefs(type) { + setDiscriminatorValue(`/${type}`, '') + commit('wizard/model$update', { + path: `/spec/${type}/name`, + value: '', + force: true, + }) + commit('wizard/model$update', { + path: `/spec/${type}/namespace`, + value: '', + force: true, + }) + } -async function getAppBindings({ axios, storeGet }, type) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const queryParams = { - filter: { - items: { - metadata: { name: null, namespace: null }, - spec: { type: null }, + async function getAppBindings(type) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const queryParams = { + filter: { + items: { + metadata: { name: null, namespace: null }, + spec: { type: null }, + }, }, - }, + } + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/appcatalog.appscode.com/v1alpha1/appbindings`, + queryParams, + ) + const resources = (resp && resp.data && resp.data.items) || [] + + const fileredResources = resources + .filter((item) => item.spec?.type === `kubedb.com/${type}`) + .map((item) => { + const name = item.metadata?.name || '' + const namespace = item.metadata?.namespace || '' + return { + text: `${namespace}/${name}`, + value: { + name: name, + namespace: namespace, + }, + } + }) + return fileredResources + } catch (e) { + console.log(e) + return [] + } } - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/appcatalog.appscode.com/v1alpha1/appbindings`, - queryParams, - ) - const resources = (resp && resp.data && resp.data.items) || [] - - const fileredResources = resources - .filter((item) => item.spec?.type === `kubedb.com/${type}`) - .map((item) => { - const name = item.metadata?.name || '' - const namespace = item.metadata?.namespace || '' - return { - text: `${namespace}/${name}`, - value: { - name: name, - namespace: namespace, - }, - } - }) - return fileredResources - } catch (e) { - console.log(e) - return [] + + function showAdditionalSettings() { + // watchDependency('discriminator#/bundleApiLoaded') + return features.length } -} -function showAdditionalSettings({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return features.length -} + function getDefault(type) { + const val = getValue(model, `/spec/admin/${type}/default`) || '' + return val + } -function getDefault({ getValue, model }, type) { - const val = getValue(model, `/spec/admin/${type}/default`) || '' - return val -} + async function getReferSecrets() { + const referSecret = getValue(discriminator, '/referSecret') + if (!referSecret) { + return [] + } -function isConfigAvailable({ getValue, model }) { - const val = getValue(model, '/spec/configuration') - return val !== '' -} + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/metadata/release/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` -async function getReferSecrets({ getValue, model, storeGet, axios, discriminator }) { - const referSecret = getValue(discriminator, '/referSecret') - if (!referSecret) { - return [] + const options = [] + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + return options } - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/metadata/release/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - - const options = [] - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) - } catch (e) { - console.log(e) + function showAuthPasswordField() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !modelPathValue && showReferSecret() } - return options -} -function showAuthPasswordField({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} - -function showSecretDropdown({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showSecretDropdown() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !!modelPathValue && showReferSecret() + } -function showReferSecret({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/createAuthSecret') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue -} + function showReferSecret() { + const modelPathValue = getValue(discriminator, '/createAuthSecret') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue + } -function getDefaultValue({ getValue, model }, path) { - const val = getValue(model, `/${path}`) || '' - return val -} + function getDefaultValue(path) { + const val = getValue(model, `/${path}`) || '' + return val + } -function showReferSecretSwitch({ model, getValue, watchDependency, discriminator }) { - const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showReferSecretSwitch() { + const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue && showReferSecret() + } -function onReferSecretChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) -} + function onReferSecretChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + } -async function checkHostnameOrIP({ commit, model, getValue }) { - const tls = getValue(model, '/spec/admin/tls/default') - const expose = getValue(model, '/spec/admin/expose/default') - if (tls && expose) { - if (hostName) { + function checkHostnameOrIP() { + const tls = getValue(model, '/spec/admin/tls/default') + const expose = getValue(model, '/spec/admin/expose/default') + if (tls && expose) { + if (hostName) { + commit('wizard/model$update', { + path: '/spec/hostName', + value: hostName, + force: true, + }) + } else { + commit('wizard/model$update', { + path: '/spec/ip', + value: ip, + force: true, + }) + } + } else { commit('wizard/model$update', { path: '/spec/hostName', - value: hostName, + value: '', force: true, }) - } else { commit('wizard/model$update', { path: '/spec/ip', - value: ip, + value: '', force: true, }) } - } else { - commit('wizard/model$update', { - path: '/spec/hostName', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/ip', - value: '', - force: true, - }) } -} -return { - checkHostnameOrIP, - showReferSecretSwitch, - onReferSecretChange, - getDefaultValue, - isRancherManaged, - showSecretDropdown, - showReferSecret, - getReferSecrets, - isConfigAvailable, - showAdditionalSettings, - initBundle, - returnFalse, - isVariantAvailable, - showAuthPasswordField, - isEqualToModelPathValue, - onModeChange, - getMachineListForOptions, - setLimits, - setRequests, - setMachineToCustom, - getCreateNameSpaceUrl, - ifCapiProviderIsNotEmpty, - ifDedicated, - dedicatedOnChange, - ifZones, - zonesOnChange, - getZones, - getSKU, - showMultiselectZone, - showSelectZone, - setStorageClass, - getNamespaces, - isToggleOn, - getAdminOptions, - getNodeTopology, - isMachineNotCustom, - isMachineCustom, - onAuthChange, - clearConfiguration, - isConfigDatabaseOn, - showIssuer, - setMonitoring, - updateAlertValue, - showAlerts, - onBackupSwitch, - onRefChange, - isExternallyManaged, - clearRefs, - getAppBindings, - setBackup, - getDefault, + return { + checkHostnameOrIP, + showReferSecretSwitch, + onReferSecretChange, + getDefaultValue, + isRancherManaged, + showSecretDropdown, + showReferSecret, + getReferSecrets, + showAdditionalSettings, + initBundle, + returnFalse, + isVariantAvailable, + showAuthPasswordField, + isEqualToModelPathValue, + onModeChange, + getMachineListForOptions, + setLimits, + setRequests, + setMachineToCustom, + getCreateNameSpaceUrl, + ifCapiProviderIsNotEmpty, + ifDedicated, + dedicatedOnChange, + ifZones, + zonesOnChange, + getZones, + getSKU, + showMultiselectZone, + showSelectZone, + setStorageClass, + getNamespaces, + isToggleOn, + getAdminOptions, + getNodeTopology, + filterNodeTopology, + isMachineNotCustom, + isMachineCustom, + onAuthChange, + clearConfiguration, + isConfigDatabaseOn, + showIssuer, + setMonitoring, + updateAlertValue, + showAlerts, + onBackupSwitch, + onRefChange, + isExternallyManaged, + clearRefs, + getAppBindings, + setBackup, + getDefault, + } } diff --git a/charts/kubedbcom-ferretdb-editor/ui/edit-ui.yaml b/charts/kubedbcom-ferretdb-editor/ui/edit-ui.yaml index a5a7b99d42..ccf66527a3 100644 --- a/charts/kubedbcom-ferretdb-editor/ui/edit-ui.yaml +++ b/charts/kubedbcom-ferretdb-editor/ui/edit-ui.yaml @@ -1,556 +1,593 @@ -steps: -- form: - discriminator: - dbDetails: - default: false - type: boolean +type: multi-step-form +step: + - type: single-step-form + id: compute-autoscaler + loader: getDbDetails + elements: + - type: block-layout + if: + type: function + name: isConsole + elements: + - type: input + label: Name + schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/metadata/properties/name + - type: select + label: Select Namespace + loader: getNamespaces + if: + type: function + name: isRancherManaged + schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/metadata/properties/namespace + - type: select + label: Select Db + loader: getDbs + validation: + type: required + refresh: true + schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/databaseRef/properties/name + watcher: + func: initMetadata + paths: + - schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/databaseRef/properties/name + + - type: radio + if: + type: function + name: isConsole + label: Select Type + validation: + type: required + schema: temp/properties/autoscalingType + watcher: + func: initMetadata + paths: + - temp/properties/autoscalingType + options: + - text: Compute + value: compute + description: Scale your CPU Memory based on resource usage + - text: Storage + value: storage + description: Expand your database size based on volume usage + + - type: block-layout + showLabels: false + loader: fetchTopologyMachines + elements: + # primary + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComFerretDBAutoscaler/spec/compute/primary/trigger + schema: temp/properties/compute/properties/primary/properties/trigger + watcher: + func: onTriggerChange|compute/primary + paths: + - temp/properties/compute/properties/primary/properties/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/primary/properties/podLifeTimeThreshold + customClass: width-300 + - type: block-layout + label: Primary + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/primary + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/primary/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-primary-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|primary|min + loader: + name: getMachines|primary|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-primary-max + watcher: + func: onMachineChange|primary + paths: + - temp/properties/allowedMachine-primary-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/primary/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/primary/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-primary-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|primary|max + loader: + name: getMachines|primary|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-primary-min + watcher: + func: onMachineChange|primary + paths: + - temp/properties/allowedMachine-primary-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/primary/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/primary/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|compute/primary + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/primary/properties/controlledResources + + # secondary + - type: switch + label: Trigger + fullwidth: true + if: + type: function + name: ferretTypeEqualsTo|secondary + init: + type: func + value: setTrigger|autoscalingKubedbComFerretDBAutoscaler/spec/compute/secondary/trigger + schema: temp/properties/compute/properties/secondary/properties/trigger + watcher: + func: onTriggerChange|compute/secondary + paths: + - temp/properties/compute/properties/secondary/properties/trigger + - type: label-element + label: Pod lifetime threshold + subtitle: Specifies the duration a pod can exist before using considered for scaling decisions, ensuring resource optimization and workload stability + if: + type: function + name: ferretTypeEqualsTo|secondary + - type: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/secondary/properties/podLifeTimeThreshold + customClass: width-300 + if: + type: function + name: ferretTypeEqualsTo|secondary + - type: block-layout + label: Secondary + if: + type: function + name: ferretTypeEqualsTo|secondary + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/secondary + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/secondary/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-secondary-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|secondary|min + loader: + name: getMachines|secondary|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-secondary-max + watcher: + func: onMachineChange|secondary + paths: + - temp/properties/allowedMachine-secondary-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/secondary/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/secondary/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-secondary-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|secondary|max + loader: + name: getMachines|secondary|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-secondary-min + watcher: + func: onMachineChange|secondary + paths: + - temp/properties/allowedMachine-secondary-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/secondary/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/secondary/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|compute/secondary + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/secondary/properties/controlledResources + + - type: block-layout + label: Node Topology + if: + type: function + name: hasNoAnnotations + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology + elements: + - type: select + label: Select NodeTopology + loader: fetchNodeTopology + schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name + - type: threshold-input + label: ScaleUp Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage + - type: threshold-input + label: ScaleDown Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage + + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + # schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/opsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: monitoring + loader: initMonitoring elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: Select Db - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: Select Type - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - discriminator: - topologyMachines: - default: [] - type: array + - type: label-element + label: To update Exporter Resource section click on Create OpsRequest + - type: anchor + label: Create OpsRequest + schema: temp/properties/opsRequestUrl + init: + type: func + value: getOpsRequestUrl|scale-vertically + - type: switch + label: Enable Monitoring + fullwidth: true + schema: temp/properties/enableMonitoring + init: + type: func + value: isValueExistInModel|/resources/kubedbComFerretDB/spec/monitor + watcher: + func: onEnableMonitoringChange + paths: + - temp/properties/enableMonitoring + - type: block-layout + if: + type: function + name: showMonitoringSection elements: - - fetch: fetchTopologyMachines - if: returnFalse - schema: - $ref: discriminator#/topologyMachines - type: input - - elements: - - computed: setTrigger|autoscalingKubedbComFerretDBAutoscaler/spec/compute/primary/trigger - label: - text: Trigger + - type: radio + label: Select a Monitoring Method + schema: schema/properties/resources/properties/kubedbComFerretDB/properties/spec/properties/monitor/properties/agent + isHorizontal: true options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/primary/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/primary/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/primary/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-primary-max: - type: string - allowedMachine-primary-min: - type: string + - text: Prometheus Operator + value: prometheus.io/operator + description: Inject metric exporter sidecar and creates a ServiceMonitor + - text: Custom ServiceMonitor + value: prometheus.io + description: Injects the metric exporter sidecar and let you customize ServiceMonitor + - text: Custom Scrapper + value: prometheus.io/builtin + description: Inject metric exporter sidecar and add Prometheus annotations to the stats Service + init: + type: static + value: prometheus.io/operator + watcher: + func: onAgentChange + paths: + - schema/properties/resources/properties/kubedbComFerretDB/properties/spec/properties/monitor/properties/agent + - type: block-layout + label: ServiceMonitor Configuration + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComFerretDB/spec/monitor/agent elements: - - computed: setAllowedMachine|primary|min - disableUnselect: true - fetch: getMachines|primary|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|primary - schema: - $ref: discriminator#/properties/allowedMachine-primary-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/primary/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/primary/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/primary/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|primary|max - disableUnselect: true - fetch: getMachines|primary|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|primary - schema: - $ref: discriminator#/properties/allowedMachine-primary-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/primary/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/primary/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/primary/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|primary - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/primary/properties/controlledResources - type: multiselect - label: - text: Primary - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/primary - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComFerretDBAutoscaler/spec/compute/secondary/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/secondary/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/secondary/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/secondary/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-secondary-max: - type: string - allowedMachine-secondary-min: - type: string + - label: Scrapping Interval + schema: schema/properties/resources/properties/kubedbComFerretDB/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval + type: input + - type: block-layout + label: Service Monitor + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComFerretDB/spec/monitor/agent elements: - - computed: setAllowedMachine|secondary|min - disableUnselect: true - fetch: getMachines|secondary|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|secondary - schema: - $ref: discriminator#/properties/allowedMachine-secondary-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/secondary/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/secondary/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/secondary/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|secondary|max - disableUnselect: true - fetch: getMachines|secondary|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|secondary - schema: - $ref: discriminator#/properties/allowedMachine-secondary-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/secondary/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/secondary/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/secondary/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|secondary - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/secondary/properties/controlledResources - type: multiselect - if: ferretTypeEqualsTo|secondary - label: - text: Secondary - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/secondary - show_label: true - type: single-step-form - - elements: - - fetch: fetchNodeTopology - label: - text: Select Node Topology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name - type: select - - if: isNodeTopologySelected - label: - text: ScaleUp Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage - type: input - - if: isNodeTopologySelected - label: - text: ScaleDown Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage - type: input - if: hasNoAnnotations - label: - text: NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComFerretDBAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: compute-autoscaler - title: steps.6.label -- form: - discriminator: - enableMonitoring: - default: true - type: boolean - elements: - - label: - text: labels.to_update_exporter_resources - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - function: getOpsRequestUrl|VerticalScaling - - computed: isValueExistInModel|/resources/kubedbComFerretDB/spec/monitor - 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/kubedbComFerretDB/properties/spec/properties/monitor/properties/agent - type: radio - - elements: - - label: - text: labels.scrapping_interval - schema: - $ref: schema#/properties/resources/properties/kubedbComFerretDB/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval - type: input - if: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComFerretDB/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: array-object-form + label: Endpoints + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/endpoints + buttonClass: is-light is-outlined + elements: + - type: switch + label: Honor labels + fullwidth: true + schema: honorLabels + - type: input + label: Interval + schema: interval + validation: + type: required + - type: input + label: Path + schema: path + validation: + type: required + - type: input + label: Port + schema: port + validation: + type: required + - type: select + multiple: true + label: Match Namespaces + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/namespaceSelector/properties/matchNames + loader: getResources|core|v1|namespaces + if: + type: function + name: returnFalse + - type: block-layout + showLabels: false + # schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector + if: + type: function + name: returnFalse + elements: + - type: object-item + label: Labels + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector/properties/matchLabels + - type: object-item + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/metadata/properties/labels + label : Labels + buttonClass: is-light is-outlined + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComFerretDB/spec/monitor/agent + # individualItemDisabilityCheck: disableLableChecker + - type: label-element + label: Exporter Configuration + schema: '' + - type: switch + label: Customize Exporter Sidecar + fullwidth: true + schema: temp/properties/customizeExporter + init: + type: static + value: true + watcher: + func: onCustomizeExporterChange + paths: + - temp/properties/customizeExporter + - type: block-layout + label: Customer Exporter Section + showLabels: false + if: + type: function + name: showCustomizeExporterSection + elements: + - type: machine-compare + label: Resources + schema: schema/properties/resources/properties/kubedbComFerretDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/resources + if: + type: function + name: returnFalse + - type: label-element + label: Security Context + schema: '' + - type: input + schema: schema/properties/resources/properties/kubedbComFerretDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsUser + label: Run as User + - type: input + schema: schema/properties/resources/properties/kubedbComFerretDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup + label: Run as Group + - type: input + schema: schema/properties/resources/properties/kubedbComFerretDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/port + label: Port + - type: array-item-form + label: Args + schema: schema/properties/resources/properties/kubedbComFerretDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args + buttonClass: is-light is-outlined + init: + type: static + value: ['--compatible-mode'] + element: 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/kubedbComFerretDB/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/kubedbComFerretDB/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: - - if: returnFalse - label: - text: labels.resources - schema: - $ref: schema#/properties/resources/properties/kubedbComFerretDB/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/kubedbComFerretDB/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/kubedbComFerretDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup - type: input - - label: - text: labels.port - schema: - $ref: schema#/properties/resources/properties/kubedbComFerretDB/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/kubedbComFerretDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args/items - type: input - label: - text: labels.args - schema: - $ref: schema#/properties/resources/properties/kubedbComFerretDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args - type: list-input-form - - alias: reusable_env - chart: - name: uibytebuildersdev-component-env - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComFerretDB/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 -type: multi-step-form + label: Args + # isSubsection: true + - type: block-layout + label: Metadata + showLabels: false + elements: + - type: array-object-form + init: + type: func + value: initEnvArray + label: Environment Variables + buttonClass: is-light is-outlined + watcher: + func: onEnvArrayChange + paths: + - temp/properties/env + schema: temp/properties/env + elements: + - type: input + label: Name + schema: name + validation: + type: required + - type: radio + label: Value From + schema: temp/properties/valueFromType + validation: + type: required + init: + type: func + value: setValueFrom + options: + - text: Input + value: input + - text: Secret + value: secret + - text: ConfigMap + value: configMap + watcher: + func: onValueFromChange + paths: + - temp/properties/valueFromType + - type: input + label: Value + schema: value + validation: + type: required + if: + name: isEqualToTemp|input + type: function + - type: select + if: + type: function + name: isEqualToTemp|configMap + label: ConfigMap Name + schema: valueFrom/properties/configMapKeyRef/properties/name + loader: + name: resourceNames|core|v1|configmaps + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: ConfigMap Key + schema: valueFrom/properties/configMapKeyRef/properties/key + if: + type: function + name: isEqualToTemp|configMap + loader: + name: getConfigMapKeys + watchPaths: + - schema/resources/kubedbComFerretDB/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/configMapKeyRef/name + - schema/metadata/release/namespace + - type: select + label: Secret Name + schema: valueFrom/properties/secretKeyRef/properties/name + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecrets + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: Secret Key + schema: valueFrom/properties/secretKeyRef/properties/key + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecretKeys + watchPaths: + - schema/resources/kubedbComFerretDB/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/secretKeyRef/name + - schema/metadata/release/namespace diff --git a/charts/kubedbcom-ferretdb-editor/ui/functions.js b/charts/kubedbcom-ferretdb-editor/ui/functions.js index a2a116e2fa..fcd4de6ae0 100644 --- a/charts/kubedbcom-ferretdb-editor/ui/functions.js +++ b/charts/kubedbcom-ferretdb-editor/ui/functions.js @@ -1,2215 +1,946 @@ -// ************************* common functions ******************************************** -// eslint-disable-next-line no-empty-pattern -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 disableLableChecker({ itemCtx }) { - const { key } = itemCtx - if (key.startsWith('app.kubernetes.io') || key.includes('helm')) return true - else return false -} - -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} - -async function getResources({ axios, storeGet }, 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 [] - } -} - -function isEqualToDiscriminatorPath( - { discriminator, getValue, watchDependency }, - value, - discriminatorPath, -) { - watchDependency('discriminator#' + discriminatorPath) - const discriminatorValue = getValue(discriminator, discriminatorPath) - return discriminatorValue === value -} - -function setValueFromModel({ getValue, model }, path) { - return getValue(model, path) -} - -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 -} - -async function getResourceList(axios, storeGet, { 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( - { axios, getValue, model, watchDependency, storeGet }, - 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 unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - 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, - } - }) -} - -function returnTrue() { - return true -} - -function returnStringYes() { - return 'yes' -} -function setAddressType({ model, getValue }) { - const value = getValue(model, '/resources/kubedbComFerretDB/spec/useAddressType') - - if (!value) { - return 'DNS' - } - - return value -} - -// ************************* Basic Info ********************************************** -async function getFerretDBVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, - }, - }, - } - - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) - - const resources = (resp && resp.data && resp.data.items) || [] - - // keep only non deprecated versions - const filteredMongoDbVersions = resources.filter((item) => item.spec && !item.spec.deprecated) - - filteredMongoDbVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredMongoDbVersions - } catch (e) { - console.log(e) - return [] - } -} - -// ********************* Database Mode *********************** -function setDatabaseMode({ model, getValue }) { - const replicas = getValue(model, '/resources/kubedbComFerretDB/spec/replicas') - - return replicas === 1 ? 'Standalone' : 'Cluster' -} - -function isEqualToDatabaseMode({ getValue, watchDependency, discriminator }, value) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - return mode === value -} - -const onDatabaseModeChange = ({ discriminator, getValue, commit }) => { - const databaseMode = getValue(discriminator, '/activeDatabaseMode') - - commit('wizard/model$update', { - path: '/resources/kubedbComFerretDB/spec/replicas', - value: databaseMode === 'Standalone' ? 1 : 3, - force: true, - }) -} - -// ************************** TLS ******************************88 - -function setApiGroup() { - return 'cert-manager.io' -} - -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - watchDependency('model#/resources/kubedbComFerretDB/spec/tls/issuerRef/apiGroup') - watchDependency('model#/resources/kubedbComFerretDB/spec/tls/issuerRef/kind') - watchDependency('model#/metadata/release/namespace') - const apiGroup = getValue(model, '/resources/kubedbComFerretDB/spec/tls/issuerRef/apiGroup') - const kind = getValue(model, '/resources/kubedbComFerretDB/spec/tls/issuerRef/kind') - const namespace = getValue(model, '/metadata/release/namespace') - - let url - if (kind === 'Issuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/namespaces/${namespace}/issuers` - } else if (kind === 'ClusterIssuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/clusterissuers` - } - - if (!url) return [] - - 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 [] - } -} - -async function hasIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await getIssuerRefsName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !!(resp && resp.length) -} - -async function hasNoIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await hasIssuerRefName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !resp -} - -function setSSLMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComFerretDB/spec/sslMode') - return val || 'require' -} - -function showTlsConfigureSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configureTLS') - const configureStatus = getValue(discriminator, '/configureTLS') - return configureStatus -} - -function onTlsConfigureChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/configureTLS') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComFerretDB/spec/tls', - value: { issuerRef: {}, certificates: [] }, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComFerretDB/spec/tls') - commit('wizard/model$delete', '/resources/kubedbComFerretDB/spec/sslMode') - } -} - -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} - -/****** Monitoring *********/ - -function showMonitoringSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/enableMonitoring') - const configureStatus = getValue(discriminator, '/enableMonitoring') - return configureStatus -} - -function onEnableMonitoringChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/enableMonitoring') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComFerretDB/spec/monitor', - value: {}, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComFerretDB/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, getValue }) { - watchDependency('discriminator#/customizeExporter') - const configureStatus = getValue(discriminator, '/customizeExporter') - return configureStatus -} - -function onCustomizeExporterChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/customizeExporter') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComFerretDB/spec/monitor/prometheus/exporter', - value: {}, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComFerretDB/spec/monitor/prometheus/exporter') - } -} - -// ********************************* Initialization & Backup ************************************* -const stashAppscodeComRestoreSession_init = { - spec: { - repository: { - name: '', - }, - rules: [ - { - snapshots: ['latest'], - }, - ], - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} -const initScript = { - scriptPath: '', - secret: { - secretName: '', - }, -} -const stashAppscodeComRepository_init_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const stashAppscodeComRepository_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const restoreSessionInitRunTimeSettings = { - container: { - resources: { - requests: { - cpu: '', - memory: '', - }, - limits: { - cpu: '', - memory: '', - }, - }, - nice: { - adjustment: null, - }, - ionice: { - class: null, - classData: null, - }, - securityContext: { - privileged: false, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - env: [], - envFrom: [], - }, - pod: { - serviceAccountName: '', - imagePullSecrets: [], - securityContext: { - fsGroup: null, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - }, -} - -const stashAppscodeComBackupConfiguration = { - spec: { - repository: { - name: '', - }, - retentionPolicy: { - keepLast: 5, - name: 'keep-last-5', - prune: true, - }, - schedule: '*/5 * * * *', - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} - -function valueExists(value, getValue, path) { - const val = getValue(value, path) - if (val) return true - else return false -} - -function initPrePopulateDatabase({ getValue, model }) { - const waitForInitialRestore = getValue( - model, - '/resources/kubedbComFerretDB/spec/init/waitForInitialRestore', - ) - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - const script = getValue(model, '/resources/kubedbComFerretDB/spec/init/script') - - return waitForInitialRestore || !!stashAppscodeComRestoreSession_init || !!script ? 'yes' : 'no' -} - -function onPrePopulateDatabaseChange({ commit, getValue, discriminator, model }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - if (prePopulateDatabase === 'no') { - // delete related properties - commit('wizard/model$update', { - path: '/resources/kubedbComFerretDB/spec/init/waitForInitialRestore', - value: false, - }) - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - commit('wizard/model$delete', '/resources/kubedbComFerretDB/spec/init/script') - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else { - const dbName = getValue(model, '/metadata/release/name') - // set stashAppscodeComRestoreSession_init if it doesn't exist - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - force: true, - }) - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - } - } -} - -function initDataSource({ getValue, model }) { - const script = getValue(model, '/resources/kubedbComFerretDB/spec/init/script') - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - - if (script) return 'script' - else if (stashAppscodeComRestoreSession_init) return 'stashBackup' - else return undefined -} - -function onDataSourceChange({ commit, getValue, discriminator, model }) { - const dataSource = getValue(discriminator, '/dataSource') - - commit('wizard/model$update', { - path: '/resources/kubedbComFerretDB/spec/init/waitForInitialRestore', - value: dataSource === 'stashBackup', - force: true, - }) - - if (dataSource === 'script') { - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - - // create a new script if there is no script property - if (!valueExists(model, getValue, '/resources/kubedbComFerretDB/spec/init/script')) - commit('wizard/model$update', { - path: '/resources/kubedbComFerretDB/spec/init/script', - value: initScript, - }) - } else if (dataSource === 'stashBackup') { - commit('wizard/model$delete', '/resources/kubedbComFerretDB/spec/init/script') - - // create a new stashAppscodeComRestoreSession_init if there is no stashAppscodeComRestoreSession_init property - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - const dbName = getValue(model, '/metadata/release/name') - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - }) - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - } - } -} - -// // for script -function initVolumeType({ getValue, model }) { - const configMap = getValue(model, '/resources/kubedbComFerretDB/spec/init/script/configMap/name') - const secret = getValue(model, '/resources/kubedbComFerretDB/spec/init/script/secret/secretName') - - if (configMap) return 'configMap' - else if (secret) return 'secret' - else return undefined -} - -function onVolumeTypeChange({ commit, getValue, discriminator, model }) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - if (sourceVolumeType === 'configMap') { - // add configMap object and delete secret object - commit('wizard/model$delete', '/resources/kubedbComFerretDB/spec/init/script/secret') - - if (!valueExists(model, getValue, '/resources/kubedbComFerretDB/spec/init/script/configMap')) { - commit('wizard/model$update', { - path: '/resources/kubedbComFerretDB/spec/init/script/configMap', - value: { - name: '', - }, - }) - } - } else if (sourceVolumeType === 'secret') { - // delete configMap object and add secret object - commit('wizard/model$delete', '/resources/kubedbComFerretDB/spec/init/script/configMap') - - if (!valueExists(model, getValue, '/resources/kubedbComFerretDB/spec/init/script/secret')) { - commit('wizard/model$update', { - path: '/resources/kubedbComFerretDB/spec/init/script/secret', - value: { - secretName: '', - }, - }) - } - } -} - -function showInitializationForm({ getValue, discriminator, watchDependency }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - watchDependency('discriminator#/prePopulateDatabase') - return prePopulateDatabase === 'yes' -} - -function showScriptOrStashForm({ getValue, discriminator, watchDependency }, value) { - const dataSource = getValue(discriminator, '/dataSource') - watchDependency('discriminator#/dataSource') - return dataSource === value -} - -function showConfigMapOrSecretName({ getValue, discriminator, watchDependency }, value) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - watchDependency('discriminator#/sourceVolumeType') - return sourceVolumeType === value -} - -// for stash backup -function initializeNamespace({ getValue, model }) { - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} - -function showRepositorySelectOrCreate({ getValue, discriminator, watchDependency }, value) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - return repositoryChoise === value -} - -function onInitRepositoryChoiseChange({ getValue, discriminator, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - if (repositoryChoise === 'select') { - // delete stashAppscodeComRepository_init_repo from model - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else if (repositoryChoise === 'create') { - // add stashAppscodeComRepository_init_repo to model - commit('wizard/model$update', { - path: 'resources/stashAppscodeComRepository_init_repo', - value: stashAppscodeComRepository_init_repo, - }) - - const repositoryName = `${getValue(model, '/metadata/release/name')}-init-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: repositoryName, - }) - } -} - -function initCustomizeRestoreJobRuntimeSettings({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function initCustomizeRestoreJobRuntimeSettingsForBackup({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function onCustomizeRestoreJobRuntimeSettingsChange({ commit, getValue, discriminator, model }) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - value: restoreSessionInitRunTimeSettings, - }) - } - } -} - -function onCustomizeRestoreJobRuntimeSettingsChangeForBackup({ - commit, - getValue, - discriminator, - model, -}) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - value: {}, - force: true, - }) - } - } -} - -function showRuntimeForm({ discriminator, getValue, watchDependency }, value) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - watchDependency('discriminator#/customizeRestoreJobRuntimeSettings') - return customizeRestoreJobRuntimeSettings === value -} - -async function getImagePullSecrets({ getValue, model, watchDependency, axios, storeGet }) { - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - - let resources = await getNamespacedResourceList(axios, storeGet, { - namespace, - group: 'core', - version: 'v1', - resource: 'secrets', - }) - - resources = resources.filter((item) => { - const validType = ['kubernetes.io/dockerconfigjson'] - return validType.includes(item.type) - }) - - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: { name: name }, - } - }) -} - -// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// FOR Backup Configuration - -// schedule bakcup - -function getBackupConfigsAndAnnotations(getValue, model) { - const stashAppscodeComBackupConfiguration = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration', - ) - const kubedbComFerretDBAnnotations = - getValue(model, '/resources/kubedbComFerretDB/metadata/annotations') || {} - - const isBluePrint = Object.keys(kubedbComFerretDBAnnotations).some( - (k) => - k === 'stash.appscode.com/backup-blueprint' || - k === 'stash.appscode.com/schedule' || - k.startsWith('params.stash.appscode.com/'), - ) - - return { - stashAppscodeComBackupConfiguration, - isBluePrint, - } -} - -function deleteKubeDbComFerretDBDbAnnotation(getValue, model, commit) { - const annotations = getValue(model, '/resources/kubedbComFerretDB/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/kubedbComFerretDB/metadata/annotations', - value: filteredAnnotations, - }) -} - -function addKubeDbComFerretDBDbAnnotation(getValue, model, commit, key, value, force) { - const annotations = getValue(model, '/resources/kubedbComFerretDB/metadata/annotations') || {} - - if (annotations[key] === undefined) { - annotations[key] = value - } else if (force) { - annotations[key] = value - } - - commit('wizard/model$update', { - path: '/resources/kubedbComFerretDB/metadata/annotations', - value: annotations, - force: true, - }) -} +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} -function initScheduleBackupForEdit({ getValue, model, setDiscriminatorValue }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function initScheduleBackup({ getValue, model }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function onScheduleBackupChange({ commit, getValue, discriminator, model }) { - 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 kubedbComFerretDB annotation - deleteKubeDbComFerretDBDbAnnotation(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, - }) - } - } -} - -// backup form -function showBackupForm({ getValue, discriminator, watchDependency }) { - const scheduleBackup = getValue(discriminator, '/scheduleBackup') - watchDependency('discriminator#/scheduleBackup') - - if (scheduleBackup === 'yes') return true - else return false -} - -// invoker form -function initBackupInvoker({ getValue, model }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, +// ************************* common functions ******************************************** +// eslint-disable-next-line no-empty-pattern +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( model, + store.state, ) - if (stashAppscodeComBackupConfiguration) return 'backupConfiguration' - else if (isBluePrint) return 'backupBlueprint' - else return undefined -} - -function onBackupInvokerChange({ getValue, discriminator, commit, model }) { - const backupInvoker = getValue(discriminator, '/backupInvoker') - - if (backupInvoker === 'backupConfiguration') { - // delete annotation and create backup config object - deleteKubeDbComFerretDBDbAnnotation(getValue, model, commit) - const dbName = getValue(model, '/metadata/release/name') - - if (!valueExists(model, getValue, '/resources/stashAppscodeComBackupConfiguration')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration', - value: stashAppscodeComBackupConfiguration, - }) + /********** Initialize Discriminator **************/ + + 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 autoscaleType = '' + let dbDetails = {} + let instance = {} + + function isConsole() { + const isKube = isKubedb() + + if (isKube) { + const dbName = storeGet('/route/params/name') || '' commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', + path: '/resources/autoscalingKubedbComFerretDBAutoscaler/spec/databaseRef/name', value: dbName, force: true, }) - } - } else if (backupInvoker === 'backupBlueprint') { - // delete backup configuration object and create the annotation - commit('wizard/model$delete', '/resources/stashAppscodeComBackupConfiguration') - addKubeDbComFerretDBDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/backup-blueprint', - '', - ) - } -} - -function showInvokerForm({ getValue, discriminator, watchDependency }, value) { - const backupInvoker = getValue(discriminator, '/backupInvoker') - watchDependency('discriminator#/backupInvoker') - - return backupInvoker === value -} - -// backup configuration form -function initalizeTargetReferenceName({ getValue, model, watchDependency }) { - const databaseName = getValue(model, '/metadata/release/name') - watchDependency('model#/metadata/release/name') - - return databaseName -} - -// restore session repository -function setInitialRestoreSessionRepo({ getValue, model }) { - const value = getValue(model, 'resources/stashAppscodeComRepository_init_repo') - return value ? 'create' : 'select' -} - -// backup config repository -function initRepositoryChoise({ getValue, model }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - - if (stashAppscodeComRepository_repo) return 'create' - else return 'select' -} - -function initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' - setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) - - return repoInitialSelectionStatus -} - -function onRepositoryChoiseChange({ getValue, discriminator, watchDependency, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - if (repositoryChoise === 'select') { - // delete the stashAppscodeComRepository_repo - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') - } else if (repositoryChoise === 'create') { - // create new stashAppscodeComRepository_repo - if (!valueExists(model, getValue, '/resources/stashAppscodeComRepository_repo')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRepository_repo', - value: stashAppscodeComRepository_repo, - }) - const repositoryName = `${getValue(model, '/metadata/release/name')}-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) - } - } -} - -function onRepositoryNameChange({ getValue, model, commit }) { - const repositoryName = getValue(model, 'resources/stashAppscodeComRepository_repo/metadata/name') - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) -} - -// backup blueprint form -function getMongoAnnotations(getValue, model) { - const annotations = getValue(model, '/resources/kubedbComFerretDB/metadata/annotations') - return { ...annotations } || {} -} - -function initFromAnnotationValue({ getValue, model }, key) { - const annotations = getMongoAnnotations(getValue, model) - return annotations[key] -} - -function onBackupBlueprintNameChange({ getValue, discriminator, commit, model }) { - const backupBlueprintName = getValue(discriminator, '/backupBlueprintName') - addKubeDbComFerretDBDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/backup-blueprint', - backupBlueprintName, - true, - ) -} - -function onBackupBlueprintScheduleChange({ getValue, discriminator, commit, model }) { - const backupBlueprintSchedule = getValue(discriminator, '/schedule') - addKubeDbComFerretDBDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/schedule', - backupBlueprintSchedule, - true, - ) -} - -function initFromAnnotationKeyValue({ getValue, model }, prefix) { - const annotations = getMongoAnnotations(getValue, model) - const newOb = {} - Object.keys(annotations).forEach((key) => { - if (key.startsWith(prefix)) { - const newKey = key.replace(prefix, '') - newOb[newKey] = annotations[key] - } - }) - return newOb -} - -function onTaskParametersChange({ getValue, discriminator, model, commit }) { - const taskParameters = getValue(discriminator, '/taskParameters') - - const taskParamterKeys = Object.keys(taskParameters).map( - (tp) => `params.stash.appscode.com/${tp}`, - ) - const oldAnnotations = getValue(model, '/resources/kubedbComFerretDB/metadata/annotations') || {} - const newAnnotations = {} - - const filteredAnnotationKeys = Object.keys(oldAnnotations).filter( - (key) => !taskParamterKeys.includes(key) && !key.startsWith('params.stash.appscode.com/'), - ) - - filteredAnnotationKeys.forEach((key) => { - newAnnotations[key] = oldAnnotations[key] - }) - - Object.keys(taskParameters).forEach((tpk) => { - newAnnotations[`params.stash.appscode.com/${tpk}`] = taskParameters[tpk] - }) - - commit('wizard/model$update', { - path: '/resources/kubedbComFerretDB/metadata/annotations', - value: newAnnotations, - }) -} - -function isValueExistInModel({ model, getValue }, path) { - const modelValue = getValue(model, path) - return !!modelValue -} - -function onNamespaceChange({ commit, model, getValue }) { - const namespace = getValue(model, '/metadata/release/namespace') - const agent = getValue(model, '/resources/kubedbComFerretDB/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', - value: [namespace], - force: true, - }) - } -} - -function onLabelChange({ commit, model, getValue }) { - const labels = getValue(model, '/resources/kubedbComFerretDB/spec/metadata/labels') - - const agent = getValue(model, '/resources/kubedbComFerretDB/spec/monitor/agent') - - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) - } -} - -function onNameChange({ commit, model, getValue }) { - const dbName = getValue(model, '/metadata/release/name') - - const agent = getValue(model, '/resources/kubedbComFerretDB/spec/monitor/agent') - - const labels = getValue(model, '/resources/kubedbComFerretDB/spec/metadata/labels') - - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) - } - - const scheduleBackup = getValue(model, '/resources/stashAppscodeComBackupConfiguration') - - if (scheduleBackup) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_repo') - if (creatingNewRepo) { + 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/stashAppscodeComBackupConfiguration/spec/repository/name', - value: `${dbName}-repo`, + path: '/resources/autoscalingKubedbComFerretDBAutoscaler/metadata/name', + value: modifiedName, force: true, }) + const namespace = storeGet('/route/query/namespace') || '' + if (namespace) { + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComFerretDBAutoscaler/metadata/namespace', + value: namespace, + force: true, + }) + } } - } - const prePopulateDatabase = getValue(model, '/resources/stashAppscodeComRestoreSession_init') - - if (prePopulateDatabase) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_init_repo') - if (creatingNewRepo) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: `${dbName}-init-repo`, - force: true, - }) + return !isKube + } + + async function getDbDetails() { + const annotations = + getValue(model, '/resources/autoscalingKubedbComFerretDBAutoscaler/metadata/annotations') || + {} + instance = annotations['kubernetes.io/instance-type'] + const owner = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + const namespace = + storeGet('/route/query/namespace') || + getValue(model, '/resources/autoscalingKubedbComFerretDBAutoscaler/metadata/namespace') || + '' + const name = + storeGet('/route/params/name') || + getValue(model, '/resources/autoscalingKubedbComFerretDBAutoscaler/spec/databaseRef/name') || + '' + + if (namespace && name) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/ferretdbs/${name}`, + ) + dbDetails = resp.data || {} + setDiscriminatorValue('/dbDetails', true) + } catch (e) { + console.log(e) + } } - } - // to reset configSecret name field - const hasSecretConfig = getValue(model, '/resources/secret_config') - if (hasSecretConfig) { commit('wizard/model$update', { - path: '/resources/kubedbComFerretDB/spec/configSecret/name', - value: `${dbName}-config`, + path: `/metadata/release/name`, + value: name, force: true, }) - } - - // to reset shard configSecret name field - const hasSecretShardConfig = getValue(model, '/resources/secret_shard_config') - if (hasSecretShardConfig) { commit('wizard/model$update', { - path: '/resources/kubedbComFerretDB/spec/shardTopology/shard/configSecret/name', - value: `${dbName}-shard-config`, + path: `/metadata/release/namespace`, + value: namespace, force: true, }) - } - - // to reset shard configSecret name field - const hasSecretConfigServerConfig = getValue(model, '/resources/secret_configserver_config') - if (hasSecretConfigServerConfig) { commit('wizard/model$update', { - path: '/resources/kubedbComFerretDB/spec/shardTopology/configServer/configSecret/name', - value: `${dbName}-configserver-config`, + path: `/resources/autoscalingKubedbComFerretDBAutoscaler/spec/databaseRef/name`, + value: name, force: true, }) - } - - // to reset mongos configSecret name field - const hasSecretMongosConfig = getValue(model, '/resources/secret_mongos_config') - if (hasSecretMongosConfig) { commit('wizard/model$update', { - path: '/resources/kubedbComFerretDB/spec/shardTopology/mongos/configSecret/name', - value: `${dbName}-mongos-config`, + path: `/resources/autoscalingKubedbComFerretDBAutoscaler/metadata/labels`, + value: dbDetails.metadata.labels, force: true, }) } -} -function returnFalse() { - return false -} + async function getNamespaces() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function onAgentChange({ commit, model, getValue }) { - const agent = getValue(model, '/resources/kubedbComFerretDB/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', - value: [], - force: true, + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, }) - onNamespaceChange({ commit, model, getValue }) - onLabelChange({ commit, model, getValue }) - } else { - commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') - } -} - -/************************************* Database Secret Section ********************************************/ - -function getCreateAuthSecret({ model, getValue }) { - const authSecret = getValue(model, '/resources/kubedbComFerretDB/spec/authSecret') - - return !authSecret -} - -function showExistingSecretSection({ getValue, watchDependency, discriminator }) { - watchDependency('discriminator#/createAuthSecret') - const hasAuthSecretName = getValue(discriminator, '/createAuthSecret') - return !hasAuthSecretName -} - -function showPasswordSection({ getValue, watchDependency, discriminator }) { - return !showExistingSecretSection({ - getValue, - watchDependency, - discriminator, - }) -} - -function setAuthSecretPassword({ model, getValue }) { - const encodedPassword = getValue(model, '/resources/secret_auth/data/password') - return encodedPassword ? decodePassword({}, encodedPassword) : '' -} - -function onAuthSecretPasswordChange({ getValue, discriminator, commit }) { - const stringPassword = getValue(discriminator, '/password') + const resources = (resp && resp.data && resp.data.items) || [] - if (stringPassword) { - commit('wizard/model$update', { - path: '/resources/secret_auth/data/password', - value: encodePassword({}, stringPassword), - force: true, - }) - commit('wizard/model$update', { - path: '/resources/secret_auth/data/username', - value: encodePassword({}, 'root'), - force: true, + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } }) - } else { - commit('wizard/model$delete', '/resources/secret_auth') } -} - -function disableInitializationSection({ model, getValue, watchDependency }) { - const initialized = getValue(model, '/resources/kubedbComFerretDB/spec/init/initialized') - watchDependency('model#/resources/kubedbComFerretDB/spec/init/initialized') - return !!initialized -} - -// eslint-disable-next-line no-empty-pattern -function encodePassword({}, value) { - return btoa(value) -} - -// eslint-disable-next-line no-empty-pattern -function decodePassword({}, value) { - return atob(value) -} -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/resources/kubedbComFerretDB/spec/authSecret') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/resources/secret_auth') + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found } -} - -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - - if (owner && cluster && namespace) { - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { - items: { - data: { username: null, password: null }, - 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', - 'kubernetes.io/basic-auth', - ] - return validType.includes(item.type) - }) + async function getDbs() { + // watchDependency('model#/resources/autoscalingKubedbComFerretDBAutoscaler/metadata/namespace') + const namespace = getValue( + model, + '/resources/autoscalingKubedbComFerretDBAutoscaler/metadata/namespace', + ) + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - 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 [] -} + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) -//////////////////// custom config ///////////////// -function onConfigurationSourceChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSource') - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_config') - } else { - const value = getValue(model, '/resources/secret_config') - if (!value) { - commit('wizard/model$update', { - path: '/resources/secret_config', - value: {}, - force: true, - }) - } - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` + const resources = (resp && resp.data && resp.data.items) || [] - commit('wizard/model$update', { - path: '/resources/kubedbComFerretDB/spec/configSecret/name', - value: configSecretName, - force: true, + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } }) } -} -function onConfigurationChange({ getValue, commit, discriminator, model }) { - const value = getValue(discriminator, '/configuration') - commit('wizard/model$update', { - path: '/resources/secret_config/stringData/user.conf', - value: value, - force: true, - }) - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComFerretDB/spec/configSecret/name', - value: configSecretName, - force: true, - }) -} - -function onConfigurationChangeEdit({ getValue, commit, discriminator, model }) { - const value = getValue(discriminator, '/configuration') - - commit('wizard/model$update', { - path: '/resources/secret_config/data/ferretdb.ini', - value: btoa(value), - force: true, - }) - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComFerretDB/spec/configSecret/name', - value: configSecretName, - force: true, - }) -} + function initMetadata() { + const dbName = + getValue(model, '/resources/autoscalingKubedbComFerretDBAutoscaler/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/autoscalingKubedbComFerretDBAutoscaler/metadata/name', + value: modifiedName, + force: true, + }) -function setConfigurationSource({ model, getValue }) { - const modelValue = getValue(model, '/resources/secret_config') - if (modelValue) { - return 'create-new-config' + // delete the other type object from model + if (type === 'compute') + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComFerretDBAutoscaler/spec/storage', + ) + if (type === 'storage') + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComFerretDBAutoscaler/spec/compute', + ) } - return 'use-existing-config' -} -function setSecretConfigNamespace({ getValue, model, watchDependency }) { - watchDependency('model#/metadata/release/namespace') - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} + async function fetchTopologyMachines() { + const instance = hasAnnotations() -function setConfiguration({ model, getValue }) { - return getValue(model, '/resources/secret_config/stringData/user.conf') -} + 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) -function setConfigurationForEdit({ model, getValue }) { - const value = getValue(model, '/resources/secret_config/data/ferretdb.ini') - return atob(value) -} + const nodeGroups = resp.data?.spec?.nodeGroups || [] + setDiscriminatorValue('/topologyMachines', nodeGroups) + return nodeGroups + } catch (e) { + console.log(e) + return [] + } + } + } -function setConfigurationFiles({ model, getValue }) { - const value = getValue(model, '/resources/secret_config/data/user.conf') - return atob(value) -} + function setTrigger(path) { + let value = getValue(model, `/resources/${path}`) + if (value) return value + return 'On' + } -function onSetCustomConfigChange({ discriminator, getValue, commit }) { - const value = getValue(discriminator, '/setCustomConfig') + function onTriggerChange(type) { + const trigger = getValue(discriminator, `/${type}/trigger`) + const commitPath = `/resources/autoscalingKubedbComFerretDBAutoscaler/spec/${type}/trigger` - if (value === 'no') { - commit('wizard/model$delete', '/resources/kubedbComFerretDB/spec/configSecret') - commit('wizard/model$delete', '/resources/secret_config') + commit('wizard/model$update', { + path: commitPath, + value: trigger ? 'On' : 'Off', + force: true, + }) } -} -function getOpsRequestUrl({ storeGet, model, getValue, mode }, 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 + `/create-opsrequest-${reqType.toLowerCase()}?namespace=${namespace}` - - if (mode === 'standalone-step') return pathConstructedForKubedb - else - return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/ferretdbopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` -} + function hasAnnotations(type) { + const annotations = + getValue(model, '/resources/autoscalingKubedbComFerretDBAutoscaler/metadata/annotations') || + {} + const instance = annotations['kubernetes.io/instance-type'] -const getAppbinding = async ({ axios, storeGet, getValue, watchDependency, rootModel }) => { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + return !!instance + } - const group = 'appcatalog.appscode.com' - const version = 'v1alpha1' - const resource = 'appbindings' + function setAllowedMachine(type, minmax) { + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = {} + } - watchDependency('rootModel#/databaseRef/namespace') + const machine = parsedInstance[type] || '' + const mx = machine?.includes(',') ? machine.split(',')[1] : '' + const mn = machine?.includes(',') ? machine.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: '', + } + } - const namespace = getValue(rootModel, '/databaseRef/namespace') + function getMachines(type, minmax) { + // watchDependency('discriminator#/topologyMachines') + const depends = minmax === 'min' ? 'max' : 'min' + const dependantPath = `/allowedMachine-${type}-${depends}` - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + // watchDependency(`discriminator#${dependantPath}`) + const dependantMachineObj = getValue(discriminator, dependantPath) + const dependantMachine = dependantMachineObj?.machine || '' - const resources = (resp && resp.data && resp.data.items) || [] + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return resources -} + const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} + // 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, + }, + } + }) -function onRefChange({ discriminator, getValue, commit }) { - const ref = getValue(discriminator, '/pgRef') || {} - commit('wizard/model$update', { - path: '/resources/kubedbComFerretDB/spec/database/databaseRef/name', - value: ref.name || '', - force: true, - }) - commit('wizard/model$update', { - path: '/resources/kubedbComFerretDB/spec/database/databaseRef/namespace', - value: ref.namespace || '', - force: true, - }) -} + const filteredMachine = machines?.filter((item, ind) => + minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, + ) -async function getAppBindings({ axios, storeGet }, type) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const queryParams = { - filter: { - items: { - metadata: { name: null, namespace: null }, - spec: { type: null }, - }, - }, + return dependantIndex === -1 ? machines : filteredMachine } - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/appcatalog.appscode.com/v1alpha1/appbindings`, - queryParams, - ) - const resources = (resp && resp.data && resp.data.items) || [] - const fileredResources = resources - .filter((item) => item.spec?.type === `kubedb.com/${type}`) - .map((item) => { - const name = item.metadata?.name || '' - const namespace = item.metadata?.namespace || '' - return { - text: `${namespace}/${name}`, - value: { - name: name, - namespace: namespace, - }, - } + function onMachineChange(type) { + const annoPath = '/resources/autoscalingKubedbComFerretDBAutoscaler/metadata/annotations' + const annotations = getValue(model, annoPath) || {} + const instance = annotations['kubernetes.io/instance-type'] + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = {} + } + + // Now discriminator values are objects with { machine, cpu, memory } + const minMachineObj = getValue(discriminator, `/allowedMachine-${type}-min`) + const maxMachineObj = getValue(discriminator, `/allowedMachine-${type}-max`) + const minMachine = minMachineObj?.machine || '' + const maxMachine = maxMachineObj?.machine || '' + const minMaxMachine = `${minMachine},${maxMachine}` + + parsedInstance[type] = minMaxMachine + const instanceString = JSON.stringify(parsedInstance) + annotations['kubernetes.io/instance-type'] = instanceString + + // 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/autoscalingKubedbComFerretDBAutoscaler/spec/compute/${type}` + + if (minMachine && maxMachine && instance !== instanceString) { + commit('wizard/model$update', { + path: `${allowedPath}/maxAllowed`, + value: maxMachineAllocatable, + force: true, }) - return fileredResources - } catch (e) { - console.log(e) - return [] + commit('wizard/model$update', { + path: `${allowedPath}/minAllowed`, + value: minMachineAllocatable, + force: true, + }) + commit('wizard/model$update', { + path: annoPath, + value: annotations, + force: true, + }) + } } -} -///////////////////////// Autoscaler /////////////////// -let autoscaleType = '' -let dbDetails = {} - -function isConsole({ storeGet, commit }) { - const isKube = isKubedb({ storeGet }) + function hasNoAnnotations() { + return !hasAnnotations() + } - if (isKube) { - const dbName = storeGet('/route/params/name') || '' - commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComFerretDBAutoscaler/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}` + function setControlledResources(type) { + const list = ['cpu', 'memory'] + const path = `/resources/autoscalingKubedbComFerretDBAutoscaler/spec/compute/${type}/controlledResources` commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComFerretDBAutoscaler/metadata/name', - value: modifiedName, + path: path, + value: list, force: true, }) - const namespace = storeGet('/route/query/namespace') || '' - if (namespace) { - commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComFerretDBAutoscaler/metadata/namespace', - value: namespace, - force: true, + return list + } + + function ferretTypeEqualsTo(param) { + const dbDetails = getValue(model, '/resources/kubedbComFerretDB') + const type = dbDetails.spec?.server?.secondary ? 'secondary' : 'primary' + return param === type + } + + 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 [] } - return !isKube -} + function isNodeTopologySelected() { + // watchDependency( + // 'model#/resources/autoscalingKubedbComFerretDBAutoscaler/spec/compute/nodeTopology/name', + // ) + const nodeTopologyName = + getValue( + model, + '/resources/autoscalingKubedbComFerretDBAutoscaler/spec/compute/nodeTopology/name', + ) || '' + return !!nodeTopologyName.length + } -function isKubedb({ storeGet }) { - return !!storeGet('/route/params/actions') -} + function showOpsRequestOptions() { + if (isKubedb() === true) return true + // watchDependency('model#/resources/autoscalingKubedbComFerretDBAutoscaler/spec/databaseRef/name') + // watchDependency('discriminator#/autoscalingType') + return ( + !!getValue( + model, + '/resources/autoscalingKubedbComFerretDBAutoscaler/spec/databaseRef/name', + ) && !!getValue(discriminator, '/autoscalingType') + ) + } -function showOpsRequestOptions({ model, getValue, watchDependency, storeGet, discriminator }) { - if (isKubedb({ storeGet }) === true) return true - watchDependency('model#/resources/autoscalingKubedbComFerretDBAutoscaler/spec/databaseRef/name') - watchDependency('discriminator#/autoscalingType') - return ( - !!getValue(model, '/resources/autoscalingKubedbComFerretDBAutoscaler/spec/databaseRef/name') && - !!getValue(discriminator, '/autoscalingType') - ) -} + function setApplyToIfReady() { + return 'IfReady' + } -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function isKubedb() { + return !!storeGet('/route/params/actions') + } -async function getNamespaces({ axios, storeGet }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + /********** Monitoring ***********/ - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } - const resources = (resp && resp.data && resp.data.items) || [] + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - watchDependency('model#/resources/autoscalingKubedbComFerretDBAutoscaler/metadata/namespace') - const namespace = getValue( - model, - '/resources/autoscalingKubedbComFerretDBAutoscaler/metadata/namespace', - ) - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + const resources = (resp && resp.data && resp.data.items) || [] - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + 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 [] + } + } - const resources = (resp && resp.data && resp.data.items) || [] + async function getNamespacedResourceList( + axios, + storeGet, + { namespace, group, version, resource }, + ) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` -async function getDbDetails({ commit, setDiscriminatorValue, axios, storeGet, getValue, model }) { - const owner = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - const namespace = - storeGet('/route/query/namespace') || - getValue(model, '/resources/autoscalingKubedbComFerretDBAutoscaler/metadata/namespace') || - '' - const name = - storeGet('/route/params/name') || - getValue(model, '/resources/autoscalingKubedbComFerretDBAutoscaler/spec/databaseRef/name') || - '' - - if (namespace && name) { + let ans = [] try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/ferretdbs/${name}`, - ) - dbDetails = resp.data || {} - setDiscriminatorValue('/dbDetails', true) + 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 } - commit('wizard/model$update', { - path: `/metadata/release/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/metadata/release/namespace`, - value: namespace, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComFerretDBAutoscaler/spec/databaseRef/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComFerretDBAutoscaler/metadata/labels`, - value: dbDetails.metadata.labels, - force: true, - }) -} + async function resourceNames(group, version, resource) { + const namespace = getValue(model, '/metadata/release/namespace') + // watchDependency('model#/metadata/release/namespace') -async function dbTypeEqualsTo({ watchDependency, commit }, type) { - watchDependency('discriminator#/dbDetails') + 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) + }) + } - const { spec } = dbDetails || {} - const { topology } = spec || {} - let verd = '' - if (topology) verd = 'topology' - else { - verd = 'combined' + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } + }) } - clearSpecModel({ commit }, verd) - return type === verd && spec -} -function clearSpecModel({ commit }, dbtype) { - if (dbtype === 'standalone') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComFerretDBAutoscaler/spec/${autoscaleType}/cluster`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComFerretDBAutoscaler/spec/${autoscaleType}/sentinel`, - ) - } else if (dbtype === 'cluster') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComFerretDBAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComFerretDBAutoscaler/spec/${autoscaleType}/sentinel`, - ) - } else if (dbtype === 'sentinel') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComFerretDBAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComFerretDBAutoscaler/spec/${autoscaleType}/cluster`, - ) + function showMonitoringSection() { + // watchDependency('discriminator#/enableMonitoring') + const configureStatus = getValue(discriminator, '/enableMonitoring') + return configureStatus } -} -function initMetadata({ getValue, discriminator, model, commit, storeGet }) { - const dbName = - getValue(model, '/resources/autoscalingKubedbComFerretDBAutoscaler/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) + function onEnableMonitoringChange() { + const configureStatus = getValue(discriminator, '/enableMonitoring') + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComFerretDB/spec/monitor', + value: {}, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/kubedbComFerretDB/spec/monitor') + } + + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComFerretDBAutoscaler/metadata/name', - value: modifiedName, + path: '/form/alert/enabled', + value: configureStatus ? 'warning' : 'none', force: true, }) - - // delete the other type object from model - if (type === 'compute') - commit('wizard/model$delete', '/resources/autoscalingKubedbComFerretDBAutoscaler/spec/storage') - if (type === 'storage') - commit('wizard/model$delete', '/resources/autoscalingKubedbComFerretDBAutoscaler/spec/compute') -} - -function onNamespaceChange({ model, getValue, commit }) { - const namespace = getValue( - model, - '/resources/autoscalingKubedbComFerretDBAutoscaler/metadata/namespace', - ) - if (!namespace) { - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComFerretDBAutoscaler/spec/databaseRef/name', - ) } -} -function ifScalingTypeEqualsTo( - { storeGet, watchDependency, getValue, discriminator, model }, - type, -) { - watchDependency('discriminator#/autoscalingType') - watchDependency('model#/resources/autoscalingKubedbComFerretDBAutoscaler/spec/databaseRef/name') - - const operation = storeGet('/route/params/actions') || '' - if (operation.length) { - const splitOp = operation.split('-') - if (splitOp.length > 2) autoscaleType = splitOp[2] - } else autoscaleType = getValue(discriminator, '/autoscalingType') || '' - const isDatabaseSelected = !!getValue( - model, - '/resources/autoscalingKubedbComFerretDBAutoscaler/spec/databaseRef/name', - ) - return autoscaleType === type && isDatabaseSelected -} + function showCustomizeExporterSection() { + // watchDependency('discriminator#/customizeExporter') + const configureStatus = getValue(discriminator, '/customizeExporter') + return configureStatus + } -async function fetchNodeTopology({ axios, storeGet }) { - 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) + function onCustomizeExporterChange() { + const configureStatus = getValue(discriminator, '/customizeExporter') + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComFerretDB/spec/monitor/prometheus/exporter', + value: {}, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/kubedbComFerretDB/spec/monitor/prometheus/exporter') + } } - return [] -} -function isNodeTopologySelected({ watchDependency, model, getValue }) { - watchDependency( - 'model#/resources/autoscalingKubedbComFerretDBAutoscaler/spec/compute/nodeTopology/name', - ) - const nodeTopologyName = - getValue( - model, - '/resources/autoscalingKubedbComFerretDBAutoscaler/spec/compute/nodeTopology/name', - ) || '' - return !!nodeTopologyName.length -} + function isValueExistInModel(path) { + const modelValue = getValue(model, path) || null + return !!modelValue + } -function setControlledResources({ commit }, type) { - const list = ['cpu', 'memory'] - const path = `/resources/autoscalingKubedbComFerretDBAutoscaler/spec/compute/${type}/controlledResources` - commit('wizard/model$update', { - path: path, - value: list, - force: true, - }) - return list -} + // function onNamespaceChange() { + // const namespace = getValue(model, '/metadata/release/namespace') + // const agent = getValue(model, '/resources/kubedbComFerretDB/spec/monitor/agent') + // if (agent === 'prometheus.io') { + // commit('wizard/model$update', { + // path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + // value: [namespace], + // force: true, + // }) + // } + // } -function setTrigger({ model, getValue }, path) { - let value = getValue(model, `/resources/${path}`) - if (value) return value - return 'On' -} + function onLabelChange() { + const labels = getValue(model, '/resources/kubedbComFerretDB/spec/metadata/labels') -function setApplyToIfReady() { - return 'IfReady' -} + const agent = getValue(model, '/resources/kubedbComFerretDB/spec/monitor/agent') -function handleUnit({ commit, model, getValue }, 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)) { + if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: `/resources/${path}`, - value: updatedValue, + path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', + value: labels, force: true, }) } - } else { - if (!isNaN(value)) { - value += 'Gi' + } + + function onAgentChange() { + const agent = getValue(model, '/resources/kubedbComFerretDB/spec/monitor/agent') + if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: `/resources/${path}`, - value: value, + path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', + value: [], force: true, }) + + onNamespaceChange() + onLabelChange() + } else { + commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') } } -} -function ferretTypeEqualsTo({ getValue, model }, param) { - const dbDetails = getValue(model, '/resources/kubedbComFerretDB') - const type = dbDetails.spec?.server?.secondary ? 'secondary' : 'primary' - return param === type -} + 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') + + if (owner && cluster && namespace) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { + items: { + data: { username: null, password: null }, + 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', + 'kubernetes.io/basic-auth', + ] + 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 fetchTopologyMachines({ axios, getValue, storeGet, model, setDiscriminatorValue }) { - const instance = hasAnnotations({ model, getValue }) + 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 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 isKube = !!storeGet('/route/params/actions') - const nodeGroups = resp.data?.spec?.nodeGroups || [] - setDiscriminatorValue('/topologyMachines', nodeGroups) - return nodeGroups - } catch (e) { - console.log(e) - return [] + if (isKube) return pathConstructedForKubedb + else + return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/ferretdbopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` + } + + function onNamespaceChange() { + const namespace = getValue( + model, + '/resources/autoscalingKubedbComFerretDBAutoscaler/metadata/namespace', + ) + if (!namespace) { + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComFerretDBAutoscaler/spec/databaseRef/name', + ) } } -} -function setAllowedMachine({ model, getValue }, type, minmax) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComFerretDBAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - let parsedInstance = {} - try { - if (instance) parsedInstance = JSON.parse(instance) - } catch (e) { - console.log(e) - parsedInstance = {} + function setValueFrom() { + if (isConfigMapTypeValueFrom()) { + return 'configMap' + } else if (isSecretTypeValueFrom()) { + return 'secret' + } else { + return 'input' + } } - const machine = parsedInstance[type] || '' - const mx = machine?.includes(',') ? machine.split(',')[1] : '' - const mn = machine?.includes(',') ? machine.split(',')[0] : '' + 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, + }) + } + } - if (minmax === 'min') return mn - else return mx -} + // function isEqualToValueFromType(value) { + // //watchDependency('discriminator#/valueFromType') + // const valueFrom = getValue(discriminator, '/valueFromType') + // return valueFrom === value + // } -async function getMachines({ getValue, watchDependency, discriminator }, type, minmax) { - watchDependency('discriminator#/topologyMachines') - const depends = minmax === 'min' ? 'max' : 'min' - const dependantPath = `/allowedMachine-${type}-${depends}` + 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/kubedbComFerretDB/spec/monitor/prometheus/exporter/env/${index}/valueFrom/configMapKeyRef/name`, + ) - watchDependency(`discriminator#${dependantPath}`) - const dependantMachine = getValue(discriminator, dependantPath) + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/configMapKeyRef/name') - const nodeGroups = getValue(discriminator, '/topologyMachines') || [] + if (!configMapName) return [] - const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/configmaps/${configMapName}`, + ) - const machines = nodeGroups?.map((item) => { - const subText = `CPU: ${item.allocatable.cpu}, Memory: ${item.allocatable.memory}` - const text = item.topologyValue - return { text, subText, value: item.topologyValue } - }) + const configMaps = (resp && resp.data && resp.data.data) || {} - const filteredMachine = machines?.filter((item, ind) => - minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, - ) + const configMapKeys = Object.keys(configMaps).map((item) => ({ + text: item, + value: item, + })) - return dependantIndex === -1 ? machines : filteredMachine -} + return configMapKeys + } catch (e) { + console.log(e) + return [] + } + } -function hasAnnotations({ model, getValue }, type) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComFerretDBAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] + 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/kubedbComFerretDB/spec/monitor/prometheus/exporter/env/${index}/valueFrom/secretKeyRef/name`, + ) - return !!instance -} + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/secretKeyRef/name') -function hasNoAnnotations({ model, getValue }) { - return !hasAnnotations({ model, getValue }) -} + if (!secretName) return [] -function onMachineChange({ model, getValue, discriminator, commit }, type) { - const annoPath = '/resources/autoscalingKubedbComFerretDBAutoscaler/metadata/annotations' - const annotations = getValue(model, annoPath) - const instance = annotations['kubernetes.io/instance-type'] - let parsedInstance = {} - try { - if (instance) parsedInstance = JSON.parse(instance) - } catch (e) { - console.log(e) - parsedInstance = {} - } + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets/${secretName}`, + ) - const minMachine = getValue(discriminator, `/allowedMachine-${type}-min`) - const maxMachine = getValue(discriminator, `/allowedMachine-${type}-max`) - const minMaxMachine = `${minMachine},${maxMachine}` + const secret = (resp && resp.data && resp.data.data) || {} - parsedInstance[type] = minMaxMachine - const instanceString = JSON.stringify(parsedInstance) - annotations['kubernetes.io/instance-type'] = instanceString + const secretKeys = Object.keys(secret).map((item) => ({ + text: item, + value: item, + })) - const machines = getValue(discriminator, `/topologyMachines`) || [] - const minMachineObj = machines.find((item) => item.topologyValue === minMachine) - const maxMachineObj = machines.find((item) => item.topologyValue === maxMachine) - const minMachineAllocatable = minMachineObj?.allocatable - const maxMachineAllocatable = maxMachineObj?.allocatable - const allowedPath = `/resources/autoscalingKubedbComFerretDBAutoscaler/spec/compute/${type}` + return secretKeys + } catch (e) { + console.log(e) + return [] + } + } - if (minMachine && maxMachine && instance !== instanceString) { - commit('wizard/model$update', { - path: `${allowedPath}/maxAllowed`, - value: maxMachineAllocatable, - force: true, - }) - commit('wizard/model$update', { - path: `${allowedPath}/minAllowed`, - value: minMachineAllocatable, - force: true, + function returnFalse() { + return false + } + + 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 }) - commit('wizard/model$update', { - path: annoPath, - value: annotations, - force: true, + + if (filteredEnv.length) + commit('wizard/model$update', { + path: '/resources/kubedbComFerretDB/spec/monitor/prometheus/exporter/env', + value: filteredEnv, + force: true, + }) + } + + function initEnvArray() { + const env = getValue(model, '/resources/kubedbComFerretDB/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/kubedbComFerretDB/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 { - isRancherManaged, - handleUnit, - isConsole, - getNamespaces, - getDbs, - isKubedb, - getDbDetails, - dbTypeEqualsTo, - clearSpecModel, - initMetadata, - onNamespaceChange, - ifScalingTypeEqualsTo, - fetchNodeTopology, - isNodeTopologySelected, - setControlledResources, - setTrigger, - setApplyToIfReady, - showOpsRequestOptions, - isVariantAvailable, - fetchJsons, - getAppbinding, - onDatabaseModeChange, - setDatabaseMode, - disableLableChecker, - isEqualToModelPathValue, - getResources, - isEqualToDiscriminatorPath, - setValueFromModel, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - returnTrue, - returnStringYes, - setAddressType, - getFerretDBVersions, - isEqualToDatabaseMode, - setApiGroup, - getIssuerRefsName, - hasIssuerRefName, - hasNoIssuerRefName, - setSSLMode, - showTlsConfigureSection, - onTlsConfigureChange, - getAliasOptions, - showMonitoringSection, - onEnableMonitoringChange, - showCustomizeExporterSection, - onCustomizeExporterChange, - valueExists, - onConfigurationChangeEdit, - setConfigurationForEdit, - initPrePopulateDatabase, - onPrePopulateDatabaseChange, - initDataSource, - onDataSourceChange, - initVolumeType, - onVolumeTypeChange, - showInitializationForm, - showScriptOrStashForm, - showConfigMapOrSecretName, - initializeNamespace, - showRepositorySelectOrCreate, - onInitRepositoryChoiseChange, - initCustomizeRestoreJobRuntimeSettings, - initCustomizeRestoreJobRuntimeSettingsForBackup, - onCustomizeRestoreJobRuntimeSettingsChange, - onCustomizeRestoreJobRuntimeSettingsChangeForBackup, - showRuntimeForm, - getImagePullSecrets, - getBackupConfigsAndAnnotations, - deleteKubeDbComFerretDBDbAnnotation, - addKubeDbComFerretDBDbAnnotation, - initScheduleBackup, - initScheduleBackupForEdit, - onScheduleBackupChange, - showBackupForm, - initBackupInvoker, - onBackupInvokerChange, - showInvokerForm, - initalizeTargetReferenceName, - setInitialRestoreSessionRepo, - initRepositoryChoise, - initRepositoryChoiseForEdit, - setConfigurationForEdit, - onRepositoryChoiseChange, - onRepositoryNameChange, - getMongoAnnotations, - initFromAnnotationValue, - onBackupBlueprintNameChange, - onBackupBlueprintScheduleChange, - initFromAnnotationKeyValue, - onTaskParametersChange, - isValueExistInModel, - onNamespaceChange, - onLabelChange, - onNameChange, - returnFalse, - onAgentChange, - getCreateAuthSecret, - showExistingSecretSection, - showPasswordSection, - setAuthSecretPassword, - onAuthSecretPasswordChange, - disableInitializationSection, - encodePassword, - decodePassword, - onCreateAuthSecretChange, - getSecrets, - onConfigurationSourceChange, - onConfigurationChange, - setConfigurationSource, - setSecretConfigNamespace, - setConfiguration, - setConfigurationFiles, - onSetCustomConfigChange, - getOpsRequestUrl, - onRefChange, - getAppBindings, - ferretTypeEqualsTo, - getMachines, - setAllowedMachine, - hasAnnotations, - hasNoAnnotations, - fetchTopologyMachines, - onMachineChange, + return { + isConsole, + getDbDetails, + getNamespaces, + isRancherManaged, + onNamespaceChange, + getDbs, + initMetadata, + fetchTopologyMachines, + setTrigger, + onTriggerChange, + hasAnnotations, + setAllowedMachine, + getMachines, + onMachineChange, + hasNoAnnotations, + setControlledResources, + ferretTypeEqualsTo, + fetchNodeTopology, + isNodeTopologySelected, + showOpsRequestOptions, + setApplyToIfReady, + + getOpsRequestUrl, + isValueExistInModel, + onEnableMonitoringChange, + showMonitoringSection, + onAgentChange, + getResources, + isEqualToModelPathValue, + onCustomizeExporterChange, + showCustomizeExporterSection, + onLabelChange, + setValueFrom, + onValueFromChange, + resourceNames, + getConfigMapKeys, + getSecrets, + getSecretKeys, + isConfigMapTypeValueFrom, + isSecretTypeValueFrom, + getNamespacedResourceList, + returnFalse, + onEnvArrayChange, + initEnvArray, + isEqualToTemp, + initMonitoring, + } } diff --git a/charts/kubedbcom-hazelcast-editor-options/ui/create-ui.yaml b/charts/kubedbcom-hazelcast-editor-options/ui/create-ui.yaml index 53cb44fd44..63f3fe7801 100644 --- a/charts/kubedbcom-hazelcast-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-hazelcast-editor-options/ui/create-ui.yaml @@ -1,316 +1,318 @@ -steps: -- form: - discriminator: - bundleApiLoaded: - default: false - type: boolean +step: +- type: single-step-form + loader: initBundle + elements: + - type: label-element + label: '' + subtitle: Select the Hazlecast version you want to deploy on Kubernetes. The chosen version determines the Hazlecast engine features, compatibility, and runtime behavior of your document database proxy. + - disableUnselect: true + loader: getAdminOptions|databases/Hazelcast/versions + if: + type: function + name: isToggleOn|databases/Hazelcast/versions + label: Database version + schema: schema/properties/spec/properties/admin/properties/databases/properties/Hazelcast/properties/versions/properties/default + type: select + - init: + type: func + value: getDefault|databases/Hazelcast/mode + loader: getAdminOptions|databases/Hazelcast/mode + if: + type: function + name: isToggleOn|databases/Hazelcast/mode + label: Database mode + isHorizontal: true + watcher: + func: toggleTls + paths: + - schema/properties/spec/properties/mode + schema: schema/properties/spec/properties/mode + type: radio + - if: + type: function + name: isEqualToModelPathValue|Replicaset|/spec/mode + label: Replicaset number + schema: schema/properties/spec/properties/replicas + type: input + - elements: + - type: label-element + label: '' + subtitle: Select a machine profile to allocate CPU and memory resources for your analytical database. Choose 'custom' to manually specify resource requirements or select a predefined profile. + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu + if: + type: function + name: isMachineCustom + label: cpu + watcher: + func: setRequests|cpu + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory + if: + type: function + name: isMachineCustom + label: memory + watcher: + func: setRequests|memory + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + label: Machine_profile + showLabels: true + type: block-layout + - type: horizontal-layout + showLabels: true elements: - - computed: initBundle - if: returnFalse - type: label-element - - disableUnselect: true - fetch: getAdminOptions|databases/Hazelcast/versions - if: isToggleOn|databases/Hazelcast/versions - label: - text: labels.database.version - schema: - $ref: schema#/properties/spec/properties/admin/properties/databases/properties/Hazelcast/properties/versions/properties/default - type: select - - computed: getDefault|databases/Hazelcast/mode - fetch: getAdminOptions|databases/Hazelcast/mode - hasDescription: true - if: isToggleOn|databases/Hazelcast/mode - label: - text: labels.database.mode - onChange: toggleTls - schema: - $ref: schema#/properties/spec/properties/mode - type: radio - - if: isEqualToModelPathValue|Replicaset|/spec/mode - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/replicas - type: input - - elements: - - computed: setMachineToCustom - customClass: mt-10 - fetch: getMachineListForOptions - label: - text: labels.machine - schema: - $ref: schema#/properties/spec/properties/podResources/properties/machine + - loader: getAdminOptions|storageClasses + if: + type: function + name: isToggleOn|storageClasses + label: Storage class + schema: schema/properties/spec/properties/admin/properties/storageClasses/properties/default type: select - - computed: setLimits|cpu - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.cpu - onChange: setRequests|cpu - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - label: Storage size + schema: schema/properties/spec/properties/persistence/properties/size type: input - - computed: setLimits|memory - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.memory - onChange: setRequests|memory - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - label: - text: labels.machine_profile - show_label: true - type: single-step-form - - fetch: getAdminOptions|storageClasses - if: isToggleOn|storageClasses - label: - text: labels.storage.class - schema: - $ref: schema#/properties/spec/properties/admin/properties/storageClasses/properties/default + - loader: getSecrets + label: License Secret + refresh: true + schema: schema/properties/spec/properties/licenseSecret/properties/name + type: select + - description: Configure Credentials, Deployment Mode etc. + elements: + - elements: + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/annotations + label: Labels & Annotations + showLabels: true + hideBlock: true + type: block-layout + - init: + type: func + value: getDefault|deletionPolicy + customClass: mt-20 + if: + type: function + name: isToggleOn|deletionPolicy + label: Deletion Policy + watcher: + func: setStorageClass + paths: + - schema/properties/spec/properties/deletionPolicy + options: + - description: options.deletionPolicy.delete.description + text: Delete + value: Delete + - description: options.deletionPolicy.halt.description + text: Halt + value: Halt + - description: options.deletionPolicy.wipeOut.description + text: WipeOut + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: DoNotTerminate + value: DoNotTerminate + schema: schema/properties/spec/properties/deletionPolicy + type: select + - if: + type: function + name: getDefaultValue|spec/admin/authCredential/customize + label: Provide Authentication Credentials? + watcher: + func: onAuthChange + paths: + - temp/createAuthSecret + schema: temp/createAuthSecret + type: switch + - if: + type: function + name: showReferSecretSwitch + label: Refer existing Secret? + watcher: + func: onReferSecretChange + paths: + - temp/referSecret + schema: temp/referSecret + type: switch + - loader: getReferSecrets + if: + type: function + name: showSecretDropdown + label: Secret + schema: schema/properties/spec/properties/authSecret/properties/name type: select - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/persistence/properties/size + - if: + type: function + name: showReferSecret + label: password + schema: schema/properties/spec/properties/authSecret/properties/password type: input - - fetch: getSecrets - label: - text: labels.licenseSecret - refresh: true - schema: - $ref: schema#/properties/spec/properties/licenseSecret/properties/name + - if: + type: function + name: getDefaultValue|spec/admin/customConfiguration + label: Configure Database? + watcher: + func: clearConfiguration + paths: + - temp/configDatabase + schema: temp/configDatabase + type: switch + - if: + type: function + name: isConfigDatabaseOn + label: Configuration + # hasCopy: true + schema: schema/properties/spec/properties/configuration + type: textarea + - if: + type: function + name: isToggleOn|deployment + label: Deployment name + options: + - description: labels.deployment.shared + text: Shared + value: Shared + - description: labels.deployment.dedicated + text: Dedicated + value: Dedicated + schema: schema/properties/spec/properties/admin/properties/deployment/properties/default + type: radio + - if: + type: function + name: isToggleOn|clusterTier + isHorizontal: true + label: Cluster Tier + options: + - text: General Purpose + value: GeneralPurpose + - text: Memory Optimized + value: MemoryOptimized + - text: CPU Optimized + value: CPUOptimized + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/default + type: radio + - disableUnselect: true + loader: getAdminOptions|clusterTier/placement + if: + type: function + name: isToggleOn|clusterTier/placement + label: Placement + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default type: select - - accordion: true - description: - text: Configure Credentials, Deployment Mode etc. - discriminator: - configDatabase: - default: false - type: boolean - createAuthSecret: - default: false - type: boolean - referSecret: - default: false - type: boolean - elements: - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties - type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties - type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - computed: getDefault|deletionPolicy - customClass: mt-20 - if: isToggleOn|deletionPolicy - 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/spec/properties/deletionPolicy - type: select - - if: getDefaultValue|spec/admin/authCredential/customize - label: - text: Provide Authentication Credentials? - onChange: onAuthChange - schema: - $ref: discriminator#/createAuthSecret - type: switch - - if: showReferSecretSwitch - label: - text: Refer existing Secret? - onChange: onReferSecretChange - schema: - $ref: discriminator#/referSecret + - disableUnselect: true + loader: getNodeTopology + if: + type: function + name: isToggleOn|clusterTier/nodeTopology + label: Node Topology + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + type: select + label: Advanced Configuration + showLabels: true + type: block-layout + - description: Enable Backup, Monitoring, TLS etc. + elements: + - init: + type: func + value: setBackup + if: + type: function + name: returnFalse + label: Enable Backup? + watcher: + func: onBackupSwitch + paths: + - temp/backup + schema: temp/backup + type: switch + - elements: + - disable: showArchiverAlert + label: Enable Archiver? + watcher: + func: onArchiverChange + paths: + - schema/properties/spec/properties/admin/properties/archiver/properties/enable/properties/default + schema: schema/properties/spec/properties/admin/properties/archiver/properties/enable/properties/default type: switch - - fetch: getReferSecrets - if: showSecretDropdown - label: - text: Secret - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/name - type: select - - if: showReferSecret - label: - text: labels.password - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/password - type: input - - computed: isConfigAvailable - if: getDefaultValue|spec/admin/customConfiguration - label: - text: Configure Database? - onChange: clearConfiguration - schema: - $ref: discriminator#/configDatabase + - if: + type: function + name: showArchiverAlert + label: The selected StorageClass does not support Archiver + type: warning + if: + type: function + name: returnFalse + type: block-layout + - elements: + - init: + type: func + value: checkHostnameOrIP + if: + type: function + name: isToggleOn|tls + label: Enable TLS? + watcher: + func: checkHostnameOrIP + paths: + - schema/properties/spec/properties/admin/properties/tls/properties/default + schema: schema/properties/spec/properties/admin/properties/tls/properties/default type: switch - - if: isConfigDatabaseOn - label: - text: Configuration - schema: - $ref: schema#/properties/spec/properties/configuration - type: editor - - hasDescription: true - if: isToggleOn|deployment - label: - text: labels.deployment.name - options: - - description: labels.deployment.shared - text: Shared - value: Shared - - description: labels.deployment.dedicated - text: Dedicated - value: Dedicated - schema: - $ref: schema#/properties/spec/properties/admin/properties/deployment/properties/default - type: radio - - if: isToggleOn|clusterTier - isHorizontal: true - label: - text: labels.clusterTier - options: - - text: General Purpose - value: GeneralPurpose - - text: Memory Optimized - value: MemoryOptimized - - text: CPU Optimized - value: CPUOptimized - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/default - type: radio - - disableUnselect: true - fetch: getAdminOptions|clusterTier/placement - if: isToggleOn|clusterTier/placement - label: - text: labels.placement - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default - type: select - - disableUnselect: true - fetch: getNodeTopology - if: isToggleOn|clusterTier/nodeTopology - label: - text: labels.nodeTopology - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + - loader: getAdminOptions|clusterIssuers + if: + type: function + name: showIssuer + label: Cluster Issuers + validation: + type: required + schema: schema/properties/spec/properties/admin/properties/clusterIssuers/properties/default type: select - hideForm: true - label: - text: Advanced Configuration - show_label: true - type: single-step-form - - accordion: true - description: - text: Enable Backup, Monitoring, TLS etc. - discriminator: - backup: - default: false - type: boolean - elements: - - computed: setBackup - if: returnFalse - label: - text: Enable Backup? - onChange: onBackupSwitch - schema: - $ref: discriminator#/backup + type: block-layout + - elements: + - init: + type: func + value: checkHostnameOrIP + if: + type: function + name: isToggleOn|expose + label: Expose via Gateway? + watcher: + func: checkHostnameOrIP + paths: + - schema/properties/spec/properties/admin/properties/expose/properties/default + schema: schema/properties/spec/properties/admin/properties/expose/properties/default type: switch - - elements: - - disabled: showArchiverAlert - label: - text: Enable Archiver? - onChange: onArchiverChange - schema: - $ref: schema#/properties/spec/properties/admin/properties/archiver/properties/enable/properties/default - type: switch - - alertInfo: - show: true - type: neutral - if: showArchiverAlert - label: - text: The selected StorageClass does not support Archiver - type: label-element - if: returnFalse - type: single-step-form - - elements: - - computed: checkHostnameOrIP - if: isToggleOn|tls - label: - text: Enable TLS? - onChange: checkHostnameOrIP - schema: - $ref: schema#/properties/spec/properties/admin/properties/tls/properties/default - type: switch - - fetch: getAdminOptions|clusterIssuers - if: showIssuer - label: - text: labels.clusterIssuers - required: true - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterIssuers/properties/default - type: select - type: single-step-form - - elements: - - computed: checkHostnameOrIP - if: isToggleOn|expose - label: - text: Expose via Gateway? - onChange: checkHostnameOrIP - schema: - $ref: schema#/properties/spec/properties/admin/properties/expose/properties/default - type: switch - type: single-step-form - if: showAdditionalSettings - label: - text: Additional Options - show_label: true - type: single-step-form - type: single-step-form + type: block-layout + if: + type: function + name: showAdditionalSettings + label: Additional Options + showLabels: true + type: block-layout id: options - title: steps.0.label + # title: steps.0.label type: multi-step-form diff --git a/charts/kubedbcom-hazelcast-editor-options/ui/functions.js b/charts/kubedbcom-hazelcast-editor-options/ui/functions.js index 8e6b1a35a3..9a4ad81b48 100644 --- a/charts/kubedbcom-hazelcast-editor-options/ui/functions.js +++ b/charts/kubedbcom-hazelcast-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -315,1182 +317,1238 @@ const modeDetails = { }, } -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) -function showAuthSecretField({ discriminator, getValue, watchDependency }) { - return !showAuthPasswordField({ - discriminator, - getValue, - watchDependency, - }) -} + setDiscriminatorValue('bundleApiLoaded', false) + setDiscriminatorValue('configDatabase', false) + setDiscriminatorValue('createAuthSecret', false) + setDiscriminatorValue('referSecret', false) + setDiscriminatorValue('backup', false) -async function getResources({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + function showAuthSecretField() { + return !showAuthPasswordField() + } - const resources = (resp && resp.data && resp.data.items) || [] + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return resources -} + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) -async function getMySqlVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + const resources = (resp && resp.data && resp.data.items) || [] - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, - }, - }, + resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true + }) + return resources } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) + async function getMySqlVersions(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + + const queryParams = { + filter: { + items: { + metadata: { name: null }, + spec: { version: null, deprecated: null }, + }, + }, + } - const resources = (resp && resp.data && resp.data.items) || [] + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: queryParams, + }, + ) - // keep only non deprecated versions - const filteredMySqlVersions = resources.filter((item) => item.spec && !item.spec.deprecated) + const resources = (resp && resp.data && resp.data.items) || [] - filteredMySqlVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredMySqlVersions -} + // keep only non deprecated versions + const filteredMySqlVersions = resources.filter((item) => item.spec && !item.spec.deprecated) -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/spec/authSecret/name') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/spec/authSecret/password') + filteredMySqlVersions.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + const specVersion = (item.spec && item.spec.version) || '' + item.text = `${name} (${specVersion})` + item.value = name + return true + }) + return filteredMySqlVersions } -} -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') + function onCreateAuthSecretChange() { + const createAuthSecret = getValue(discriminator, '/createAuthSecret') + if (createAuthSecret) { + commit('wizard/model$delete', '/spec/authSecret/name') + } else if (createAuthSecret === false) { + commit('wizard/model$delete', '/spec/authSecret/password') + } + } - if (owner && cluster && namespace) { - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { - items: { - data: { username: null, password: null }, - metadata: { name: null }, - type: null, + 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') + + if (owner && cluster && namespace) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { + items: { + data: { username: null, password: null }, + metadata: { name: null }, + type: null, + }, }, }, }, - }, - ) + ) - const secrets = (resp && resp.data && resp.data.items) || [] + const secrets = (resp && resp.data && resp.data.items) || [] - const filteredSecrets = secrets.filter((item) => { - const validType = [ - 'kubernetes.io/service-account-token', - 'Opaque', - 'kubernetes.io/basic-auth', - ] - return validType.includes(item.type) - }) + const filteredSecrets = secrets.filter((item) => { + const validType = [ + 'kubernetes.io/service-account-token', + 'Opaque', + 'kubernetes.io/basic-auth', + ] + 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) + 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 [] } - return [] -} -function getMachineListForOptions({ model, getValue }) { - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') let array = [] + function getMachineListForOptions() { + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') - if (available.length) { - array = available.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - else { - let subText = '', - text = '' - const machineData = machinesFromPreset.find((val) => val.id === machine) - if (machineData) { - subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` - text = machineData.name ? machineData.name : machineData.id - } - return { text, subText, value: machine } - } - }) - } else { - array = machineList - .map((machine) => { + if (available.length) { + array = available.map((machine) => { if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + else { + let subText = '', + text = '' + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + text = machineData.name ? machineData.name : machineData.id + } + return { text, subText, value: machine } + } }) - .filter((val) => !!val) + } else { + array = machineList + .map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { text, subText, value: machine } + }) + .filter((val) => !!val) + } + return array } - return array -} -function setMachineToCustom({ getValue, model }) { - const machine = getValue(model, '/spec/admin/machineProfiles/default') - return machine || 'custom' -} + function setMachineToCustom() { + const machine = getValue(model, '/spec/admin/machineProfiles/default') + return machine || 'custom' + } -async function fetchJsons({ axios, itemCtx }) { - let ui = {} - let language = {} - let functions = {} - const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart + async function fetchJsons() { + 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) + 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, + } } - return { - ui: ui.data || {}, - language: language.data || {}, - functions, + function updateAgentValue(val) { + commit('wizard/model$update', { + path: '/spec/monitoring/agent', + value: val ? 'prometheus.io/operator' : '', + force: true, + }) + + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: val ? 'warning' : 'none', + force: true, + }) } -} -function updateAgentValue({ commit }, val) { - commit('wizard/model$update', { - path: '/spec/monitoring/agent', - value: val ? 'prometheus.io/operator' : '', - force: true, - }) - - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: val ? 'warning' : 'none', - force: true, - }) -} + function setReplicaNumber() { + const modelPathValue = getValue(model, '/spec/mode') + if (modelPathValue === 'Topology') { + return 2 + } else return 1 + } -function setReplicaNumber({ model, getValue }) { - const modelPathValue = getValue(model, '/spec/mode') - if (modelPathValue === 'Topology') { - return 2 - } else return 1 -} -function setRouterNumber({ model, getValue }) { - const modelPathValue = getValue(model, '/spec/mode') - if (modelPathValue === 'Topology') { - return 3 - } else return 1 -} + function setRouterNumber() { + const modelPathValue = getValue(model, '/spec/mode') + if (modelPathValue === 'Topology') { + return 3 + } else return 1 + } -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function getCreateNameSpaceUrl() { + 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + const domain = storeGet('/domain') || '' + if (domain.includes('bb.test')) { + return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } } -} -const ifCapiProviderIsNotEmpty = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/provider') - const val = getValue(model, '/form/capi/provider') - if (val) return true -} + const ifCapiProviderIsNotEmpty = () => { + // watchDependency('model#/form/capi/provider') + const val = getValue(model, '/form/capi/provider') + if (val) return true + } -const showMultiselectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') + const showMultiselectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') - if (val === 'capz' && ifDedicated({ model, getValue })) return true -} + if (val === 'capz' && ifDedicated()) return true + } -const showSelectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') - if (val !== 'capz' && ifDedicated({ model, getValue })) return true -} + const showSelectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') + if (val !== 'capz' && ifDedicated()) return true + } -const ifDedicated = ({ model, getValue }) => { - const val = getValue(model, 'form/capi/dedicated') - if (val) return true -} + const ifDedicated = () => { + const val = getValue(model, 'form/capi/dedicated') + if (val) return true + } -const dedicatedOnChange = ({ model, getValue, commit }) => { - const val = getValue(model, 'form/capi/dedicated') - if (!val) { - commit('wizard/model$delete', 'form/capi/zones') - commit('wizard/model$delete', 'form/capi/sku') + const dedicatedOnChange = () => { + const val = getValue(model, 'form/capi/dedicated') + if (!val) { + commit('wizard/model$delete', 'form/capi/zones') + commit('wizard/model$delete', 'form/capi/sku') + } } -} -const ifZones = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/zones') - watchDependency('model#/form/capi/dedicated') - const zones = getValue(model, 'form/capi/zones') || [] - const isDedicated = getValue(model, 'form/capi/dedicated') - if (zones.length && isDedicated) return true -} + const ifZones = () => { + // watchDependency('model#/form/capi/zones') + // watchDependency('model#/form/capi/dedicated') + const zones = getValue(model, 'form/capi/zones') || [] + const isDedicated = getValue(model, 'form/capi/dedicated') + if (zones.length && isDedicated) return true + } -const zonesOnChange = ({ model, getValue, commit }) => { - const zones = getValue(model, 'form/capi/zones') || [] - if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') -} + const zonesOnChange = () => { + const zones = getValue(model, 'form/capi/zones') || [] + if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') + } -async function getZones({ storeGet, axios, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const isDedicated = getValue(model, 'form/capi/dedicated') - if (isDedicated) { - try { - const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) - const val = resp.data.map((item) => { - return { value: item, text: item } - }) - return val - } catch (e) { - console.log(e) - return [] + async function getZones() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const isDedicated = getValue(model, 'form/capi/dedicated') + if (isDedicated) { + try { + const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) + const val = resp.data.map((item) => { + return { value: item, text: item } + }) + return val + } catch (e) { + console.log(e) + return [] + } } } -} -async function getSKU({ storeGet, axios, model, getValue, watchDependency }) { - watchDependency('model#/form/capi/zones') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const zones = getValue(model, 'form/capi/zones') || [] - if (zones.length) { - try { - let url = `clustersv2/${owner}/${cluster}/vms?` - if (typeof zones === 'string') { - url += `zones=${encodeURIComponent(zones)}` - } else { - zones.forEach((item) => { - url += `zones=${encodeURIComponent(item)}&` + async function getSKU() { + // watchDependency('model#/form/capi/zones') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const zones = getValue(model, 'form/capi/zones') || [] + if (zones.length) { + try { + let url = `clustersv2/${owner}/${cluster}/vms?` + if (typeof zones === 'string') { + url += `zones=${encodeURIComponent(zones)}` + } else { + zones.forEach((item) => { + url += `zones=${encodeURIComponent(item)}&` + }) + url = url.slice(0, -1) + } + const resp = await axios.get(url) + const val = resp.data.map((item) => { + return { + value: item.name, + text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, + } }) - url = url.slice(0, -1) + return val + } catch (e) { + console.log(e) + return [] } - const resp = await axios.get(url) - const val = resp.data.map((item) => { - return { - value: item.name, - text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, - } - }) - return val - } catch (e) { - console.log(e) - return [] } } -} -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} - -function setStorageClass({ model, getValue, commit, discriminator, watchDependency }) { - const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' - let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' - const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] - const suffix = '-retain' - - const simpleClassList = storageClassList.filter((item) => { - return !item.endsWith(suffix) - }) - const retainClassList = storageClassList.filter((item) => { - return item.endsWith(suffix) - }) - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] - } else { - storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] - } - - const isChangeable = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'storageClasses', - ) - if (isChangeable && storageClass) { - commit('wizard/model$update', { - path: '/spec/admin/storageClasses/default', - value: storageClass, - force: true, - }) + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false } -} -function showAlerts({ watchDependency, model, getValue, discriminator }) { - watchDependency('discriminator#/monitoring') - const isMonitorEnabled = getValue(discriminator, '/monitoring') - return ( - isMonitorEnabled && isToggleOn({ getValue, model, discriminator, watchDependency }, 'alert') - ) -} - -function onBackupSwitch({ discriminator, getValue, commit }) { - const isBackupOn = getValue(discriminator, '/backup') - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: isBackupOn ? 'KubeStash' : '', - force: true, - }) -} + function setStorageClass() { + const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' + let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' + const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] + const suffix = '-retain' -function clearArbiterHidden({ commit }) { - commit('wizard/model$update', { - path: `/spec/arbiter/enabled`, - value: false, - force: true, - }) - - commit('wizard/model$update', { - path: `/spec/hidden/enabled`, - value: false, - force: true, - }) -} + const simpleClassList = storageClassList.filter((item) => { + return !item.endsWith(suffix) + }) + const retainClassList = storageClassList.filter((item) => { + return item.endsWith(suffix) + }) + if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { + storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] + } else { + storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + } -let placement = [] -let versions = [] -let storageClass = [] -let clusterIssuers = [] -let nodetopologiesShared = [] -let nodetopologiesDedicated = [] -let features = [] -async function initBundle({ commit, model, getValue, axios, storeGet, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - - let db = getValue(model, '/metadata/resource/kind') - db = db.toLowerCase() - let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` - const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - - try { - const resp = await axios.get(url) - features = resp.data.features || [] - placement = resp.data.placementpolicies || [] - versions = resp.data.versions || [] - storageClass = resp.data.storageclasses || [] - clusterIssuers = resp.data.clusterissuers || [] - nodetopologiesDedicated = resp.data.dedicated || [] - nodetopologiesShared = resp.data.shared || [] - - const response = await axios.get(annotationUrl) - const annotations = response.data?.metadata?.annotations || {} - const uidRange = annotations['openshift.io/sa.scc.uid-range'] - if (uidRange) { - const val = uidRange.split('/')[0] + const isChangeable = isToggleOn('storageClasses') + if (isChangeable && storageClass) { commit('wizard/model$update', { - path: '/spec/openshift/securityContext/runAsUser', - value: val, + path: '/spec/admin/storageClasses/default', + value: storageClass, force: true, }) } - } catch (e) { - console.log(e) } - commit('wizard/model$update', { - path: '/spec/deletionPolicy', - value: getDefault({ getValue, model }, 'deletionPolicy'), - force: true, - }) - - if (!getValue(model, `/spec/admin/databases/Hazelcast/mode/toggle`)) { - let defMode = getDefault({ getValue, model }, 'databases/Hazelcast/mode') || '' - if (defMode === '') { - const arr = getValue(model, '/spec/databases/Hazelcast/mode/available') || [] - if (arr.length) defMode = arr[0] - } - commit('wizard/model$update', { - path: '/spec/mode', - value: defMode, - force: true, - }) + function showAlerts() { + // watchDependency('discriminator#/monitoring') + const isMonitorEnabled = getValue(discriminator, '/monitoring') + return isMonitorEnabled && isToggleOn('alert') } - if (!features.includes('tls')) { + function onBackupSwitch() { + const isBackupOn = getValue(discriminator, '/backup') commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: false, + path: '/spec/backup/tool', + value: isBackupOn ? 'KubeStash' : '', force: true, }) } - if (!features.includes('binding')) { + + function clearArbiterHidden() { commit('wizard/model$update', { - path: '/spec/admin/expose/default', + path: `/spec/arbiter/enabled`, value: false, force: true, }) - } - if (!features.includes('monitoring')) { - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: 'none', - force: true, - }) - } - if (!features.includes('backup')) { + commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', + path: `/spec/hidden/enabled`, value: false, force: true, }) - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: '', - force: true, - }) } - setDiscriminatorValue('/bundleApiLoaded', true) -} + let placement = [] + let versions = [] + let storageClass = [] + let clusterIssuers = [] + let nodetopologiesShared = [] + let nodetopologiesDedicated = [] + let features = [] + let hostName = '' + let ip = '' + + async function initBundle() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + + let db = getValue(model, '/metadata/resource/kind') + db = db.toLowerCase() + let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` + const gatewayinfosurl = `/clusters/${owner}/${cluster}/proxy/meta.k8s.appscode.com/v1alpha1/gatewayinfos/${namespace}` + const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` -function fetchOptions({ model, getValue, commit }, type) { - let kind = getValue(model, '/metadata/resource/kind') + try { + const resp = await axios.get(url) + features = resp.data.features || [] + placement = resp.data.placementpolicies || [] + versions = resp.data.versions || [] + storageClass = resp.data.storageclasses || [] + clusterIssuers = resp.data.clusterissuers || [] + nodetopologiesDedicated = resp.data.dedicated || [] + nodetopologiesShared = resp.data.shared || [] + + const response = await axios.get(annotationUrl) + const annotations = response.data?.metadata?.annotations || {} + const uidRange = annotations['openshift.io/sa.scc.uid-range'] + if (uidRange) { + const val = uidRange.split('/')[0] + commit('wizard/model$update', { + path: '/spec/openshift/securityContext/runAsUser', + value: val, + force: true, + }) + } - let returnArray = [] - if (type === 'clusterTier/placement') { - returnArray = placement - } else if (type === `databases/${kind}/versions`) { - returnArray = versions - } else if (type === 'storageClasses') { - returnArray = storageClass - } else if (type === 'clusterIssuers') { - returnArray = clusterIssuers - } + const gatewayinfosResp = await axios.get(gatewayinfosurl) + hostName = gatewayinfosResp.data?.spec?.hostName + ip = gatewayinfosResp.data?.spec?.ip + } catch (e) { + console.log(e) + } - if (returnArray.length === 1) { - const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: path, - value: returnArray[0], + path: '/spec/deletionPolicy', + value: getDefault('deletionPolicy'), force: true, }) - } - - return returnArray -} -let archiverMap = [] -let archiverCalled = false + if (!getValue(model, `/spec/admin/databases/Hazelcast/mode/toggle`)) { + let defMode = getDefault('databases/Hazelcast/mode') || '' + if (defMode === '') { + const arr = getValue(model, '/spec/databases/Hazelcast/mode/available') || [] + if (arr.length) defMode = arr[0] + } + commit('wizard/model$update', { + path: '/spec/mode', + value: defMode, + force: true, + }) + } -function getAdminOptions({ getValue, axios, model, watchDependency, storeGet, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') + if (!features.includes('tls')) { + commit('wizard/model$update', { + path: '/spec/admin/tls/default', + value: false, + force: true, + }) + } + if (!features.includes('binding')) { + commit('wizard/model$update', { + path: '/spec/admin/expose/default', + value: false, + force: true, + }) + } + if (!features.includes('monitoring')) { + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: 'none', + force: true, + }) + } + if (!features.includes('backup')) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: '', + force: true, + }) + } - if (type === 'storageClasses' && !archiverCalled) { - getArchiverName({ axios, storeGet }) + setDiscriminatorValue('/bundleApiLoaded', true) } - const options = getValue(model, `/spec/admin/${type}/available`) || [] + function fetchOptions(type) { + let kind = getValue(model, '/metadata/resource/kind') + + let returnArray = [] + if (type === 'clusterTier/placement') { + returnArray = placement + } else if (type === `databases/${kind}/versions`) { + returnArray = versions + } else if (type === 'storageClasses') { + returnArray = storageClass + } else if (type === 'clusterIssuers') { + returnArray = clusterIssuers + } - if (options.length === 0) { - return fetchOptions({ model, getValue, commit }, type) - } - if (type.endsWith('/mode')) { - return ( - options?.map((item) => ({ - description: modeDetails[item]?.description || '', - text: modeDetails[item]?.text || '', - value: item, - })) || [] - ) - } - return options -} + if (returnArray.length === 1) { + const path = `/spec/admin/${type}/default` + commit('wizard/model$update', { + path: path, + value: returnArray[0], + force: true, + }) + } -function checkIfFeatureOn({ getValue, model }, type) { - let val = getValue(model, `/spec/admin/${type}/toggle`) - if (type === 'backup' || type === 'archiver') { - val = getValue(model, `/spec/admin/${type}/enable/toggle`) + return returnArray } - const backupVal = getValue(model, '/spec/backup/tool') - if (type === 'backup') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } else if (type === 'tls') { - return features.includes('tls') && val - } else if (type === 'expose') { - return features.includes('binding') && val - } else if (type === 'monitoring') { - return features.includes('monitoring') && val - } else if (type === 'archiver') { - return features.includes('backup') && backupVal === 'KubeStash' && val + let archiverMap = [] + let archiverCalled = false + + function getAdminOptions(type) { + // watchDependency('discriminator#/bundleApiLoaded') + + if (type === 'storageClasses' && !archiverCalled) { + getArchiverName() + } + + const options = getValue(model, `/spec/admin/${type}/available`) || [] + + if (options.length === 0) { + return fetchOptions(type) + } + if (type.endsWith('/mode')) { + return ( + options?.map((item) => ({ + description: modeDetails[item]?.description || '', + text: modeDetails[item]?.text || '', + value: item, + })) || [] + ) + } + return options } -} -function isToggleOn({ getValue, model, discriminator, watchDependency }, type) { - watchDependency('discriminator#/bundleApiLoaded') - watchDependency('model#/spec/admin/deployment/default') - const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') - let deploymentType = getValue(model, `/spec/admin/deployment/default`) - if ( - type === 'tls' || - type === 'backup' || - type === 'expose' || - type === 'monitoring' || - type === 'archiver' - ) { - return checkIfFeatureOn({ getValue, model }, type) - } else if ( - type === 'clusterTier' || - type === 'clusterTier/placement' || - type === 'clusterTier/nodeTopology' - ) { - if (deploymentType === 'Dedicated' && bundleApiLoaded) return true - else return false - } else if (type === 'deployment') { - const deploymentType = getValue(model, '/spec/admin/deployment/default') - if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { - commit('wizard/model$update', { - path: '/spec/admin/deployment/default', - value: 'Shared', - force: true, - }) + let backupToolInitialValue = '' + function checkIfFeatureOn(type) { + let val = getValue(model, `/spec/admin/${type}/toggle`) + if (type === 'backup' || type === 'archiver') { + val = getValue(model, `/spec/admin/${type}/enable/toggle`) } - return ( - getValue(model, `/spec/admin/${type}/toggle`) && - nodetopologiesDedicated.length && - bundleApiLoaded - ) - } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded -} + const backupVal = getValue(model, '/spec/backup/tool') + if (type === 'backup') { + if (backupToolInitialValue === '') { + backupToolInitialValue = + features.includes('backup') && backupVal === 'KubeStash' && val ? 'on' : 'off' + return features.includes('backup') && backupVal === 'KubeStash' && val + } else { + if (backupToolInitialValue === 'on') { + return true + } else { + return false + } + } + } else if (type === 'tls') { + return features.includes('tls') && val + } else if (type === 'expose') { + return features.includes('binding') && val + } else if (type === 'monitoring') { + return features.includes('monitoring') && val + } else if (type === 'archiver') { + return features.includes('backup') && val + } + } -async function getNodeTopology({ model, getValue, axios, storeGet, watchDependency }) { - watchDependency('model#/spec/admin/deployment/default') - watchDependency('model#/spec/admin/clusterTier/default') - const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' - const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' - let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + function isToggleOn(type) { + // watchDependency('discriminator#/bundleApiLoaded') + // watchDependency('model#/spec/admin/deployment/default') + const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') + let deploymentType = getValue(model, `/spec/admin/deployment/default`) + if ( + type === 'tls' || + type === 'backup' || + type === 'expose' || + type === 'monitoring' || + type === 'archiver' + ) { + return checkIfFeatureOn(type) + } else if ( + type === 'clusterTier' || + type === 'clusterTier/placement' || + type === 'clusterTier/nodeTopology' + ) { + if (deploymentType === 'Dedicated' && bundleApiLoaded) return true + else return false + } else if (type === 'deployment') { + const deploymentType = getValue(model, '/spec/admin/deployment/default') + if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + commit('wizard/model$update', { + path: '/spec/admin/deployment/default', + value: 'Shared', + force: true, + }) + } + return ( + getValue(model, `/spec/admin/${type}/toggle`) && + nodetopologiesDedicated.length && + bundleApiLoaded + ) + } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded + } - const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + async function getNodeTopology() { + // watchDependency('model#/spec/admin/deployment/default') + // watchDependency('model#/spec/admin/clusterTier/default') + const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' + const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' + let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] - if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared - else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' - const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) - return filteredList -} + if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared + else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated -function filterNodeTopology(list, tier, provider) { - // first filter the list from value that exists from the filtered list got from API - const filteredlist = list + const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) + return filteredList + } - // filter the list based on clusterTier - if (provider === 'EKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('c') - else if (tier === 'MemoryOptimized') return item.startsWith('r') - else return !item.startsWith('c') && !item.startsWith('r') - }) - } else if (provider === 'AKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - else - return ( - !(item.startsWith('f') || item.startsWith('fx')) && - !( + function filterNodeTopology(list, tier, provider) { + // first filter the list from value that exists from the filtered list got from API + const filteredlist = list + + // filter the list based on clusterTier + if (provider === 'EKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('c') + else if (tier === 'MemoryOptimized') return item.startsWith('r') + else return !item.startsWith('c') && !item.startsWith('r') + }) + } else if (provider === 'AKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('e') || item.startsWith('eb') || item.startsWith('ec') || item.startsWith('m') || item.startsWith('d') ) - ) - }) - } else if (provider === 'GKE') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') - return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - else - return ( - !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && - !( + else + return ( + !(item.startsWith('f') || item.startsWith('fx')) && + !( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + ) + }) + } else if (provider === 'GKE') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') + return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('x4') || item.startsWith('m1') || item.startsWith('m2') || item.startsWith('m3') ) - ) - }) - } else return filteredlist -} - -function returnFalse() { - return false -} - -function isConfigDatabaseOn({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configDatabase') - return getValue(discriminator, '/configDatabase') -} -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} -function showStorageSizeField({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - const validType = [] - return !validType.includes(modelPathValue) -} -function showHidden({ watchDependency, model, getValue }) { - watchDependency('model#/spec/hidden/enabled') - const isHiddenOn = getValue(model, '/spec/hidden/enabled') || '' - const notStandalone = notEqualToDatabaseMode({ model, getValue, watchDependency }, 'Standalone') - return isHiddenOn && notStandalone -} -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} -function showArbiter({ watchDependency, model, getValue }) { - watchDependency('model#/spec/arbiter/enabled') - const isArbiterOn = getValue(model, '/spec/arbiter/enabled') || '' - const notStandalone = notEqualToDatabaseMode({ model, getValue, watchDependency }, 'Standalone') - return isArbiterOn && notStandalone -} -function clearConfiguration({ discriminator, getValue, commit }) { - const configOn = getValue(discriminator, '/configDatabase') + else + return ( + !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && + !( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + ) + }) + } else return filteredlist + } - if (!configOn) { - commit('wizard/model$delete', '/spec/configuration') + function returnFalse() { + return false } -} -function showIssuer({ model, getValue, watchDependency, discriminator }) { - watchDependency('model#/spec/admin/tls/default') - const isTlsEnabled = getValue(model, '/spec/admin/tls/default') - const isIssuerToggleEnabled = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'clusterIssuers', - ) - return isTlsEnabled && isIssuerToggleEnabled -} -function onAuthChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/authSecret/password', - value: '', - force: true, - }) -} -function setMonitoring({ getValue, model }) { - const agent = getValue(model, '/spec/admin/monitoring/agent') || '' - return !!agent -} + function isConfigDatabaseOn() { + // watchDependency('discriminator#/configDatabase') + return getValue(discriminator, '/configDatabase') + } -function setBackup({ model, getValue }) { - const backup = getValue(model, '/spec/backup/tool') - const val = getValue(model, '/spec/admin/backup/enable/default') - return backup === 'KubeStash' && features.includes('backup') && val -} + function notEqualToDatabaseMode(mode) { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + return modelPathValue && modelPathValue !== mode + } -function isMachineCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue === 'custom' -} + function showStorageSizeField() { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + const validType = [] + return !validType.includes(modelPathValue) + } -function isMachineNotCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue !== 'custom' && !!modelPathValue -} -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], - }, - }, - ) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] - } - } catch (e) { - console.log(e) + function showHidden() { + // watchDependency('model#/spec/hidden/enabled') + const isHiddenOn = getValue(model, '/spec/hidden/enabled') || '' + const notStandalone = notEqualToDatabaseMode('Standalone') + return isHiddenOn && notStandalone } - return [] -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function showArbiter() { + // watchDependency('model#/spec/arbiter/enabled') + const isArbiterOn = getValue(model, '/spec/arbiter/enabled') || '' + const notStandalone = notEqualToDatabaseMode('Standalone') + return isArbiterOn && notStandalone + } -function updateAlertValue({ commit, model, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const alert = isMonitorEnabled ? 'warning' : 'none' - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: alert, - force: true, - }) - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} + function clearConfiguration() { + const configOn = getValue(discriminator, '/configDatabase') -function setLimits({ model, getValue, commit, watchDependency }, resource, type) { - const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' - watchDependency(`model#${path}`) - const selectedMachine = getValue(model, path) || 'custom' - const reqCommitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - const comparePath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - - const resourceValue = getValue(model, comparePath) - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - - let cpu = '', - memory = '' - if (available.length && selectedMachine !== 'custom') { - const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) - if (machineData) { - cpu = machineData.limits.cpu - memory = machineData.limits.memory - } - } else { - if (selectedMachine === 'custom') { - cpu = resourceValue - memory = resourceValue - } else { - cpu = machines[selectedMachine].resources.limits.cpu - memory = machines[selectedMachine].resources.limits.memory + if (!configOn) { + commit('wizard/model$delete', '/spec/configuration') } } - if (resource === 'memory') { + function showIssuer() { + // watchDependency('model#/spec/admin/tls/default') + const isTlsEnabled = getValue(model, '/spec/admin/tls/default') + const isIssuerToggleEnabled = isToggleOn('clusterIssuers') + return isTlsEnabled && isIssuerToggleEnabled + } + + function onAuthChange() { commit('wizard/model$update', { - path: reqCommitPath, - value: memory, + path: '/spec/authSecret/name', + value: '', force: true, }) commit('wizard/model$update', { - path: comparePath, - value: memory, + path: '/spec/authSecret/password', + value: '', force: true, }) - return memory - } else { + } + + function setMonitoring() { + const agent = getValue(model, '/spec/admin/monitoring/agent') || '' + return !!agent + } + + function setBackup() { + const backup = getValue(model, '/spec/backup/tool') + const val = getValue(model, '/spec/admin/backup/enable/default') + return backup === 'KubeStash' && features.includes('backup') && val + } + + function isMachineCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue === 'custom' + } + + function isMachineNotCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue !== 'custom' && !!modelPathValue + } + + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, + }, + ) + if (resp.data?.status?.projects) { + const projects = resp.data?.status?.projects + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } + } catch (e) { + console.log(e) + } + return [] + } + + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } + + function updateAlertValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const alert = isMonitorEnabled ? 'warning' : 'none' + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: reqCommitPath, - value: cpu, + path: '/form/alert/enabled', + value: alert, force: true, }) + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' commit('wizard/model$update', { - path: comparePath, - value: cpu, + path: '/spec/admin/monitoring/agent', + value: agent, force: true, }) - return cpu } -} -function setRequests({ getValue, model, commit }, resource, type) { - const modelPath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - const val = getValue(model, modelPath) - commitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - commit('wizard/model$update', { - path: commitPath, - value: val, - force: true, - }) -} + function setLimits(resource, type) { + const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' + // watchDependency(`model#${path}`) + const selectedMachine = getValue(model, path) || 'custom' + const reqCommitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + const comparePath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + + const resourceValue = getValue(model, comparePath) + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + let cpu = '', + memory = '' + if (available.length && selectedMachine !== 'custom') { + const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) + if (machineData) { + cpu = machineData.limits.cpu + memory = machineData.limits.memory + } + } else { + if (selectedMachine === 'custom') { + cpu = resourceValue + memory = resourceValue + } else { + cpu = machines[selectedMachine].resources.limits.cpu + memory = machines[selectedMachine].resources.limits.memory + } + } -function toggleTls({ commit, model, getValue }) { - let modelPathValue = getValue(model, '/spec/mode') - commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: modelPathValue !== 'Standalone', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/admin/tls/toggle', - value: modelPathValue !== 'Standalone', - force: true, - }) -} + if (resource === 'memory') { + commit('wizard/model$update', { + path: reqCommitPath, + value: memory, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: memory, + force: true, + }) + return memory + } else { + commit('wizard/model$update', { + path: reqCommitPath, + value: cpu, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: cpu, + force: true, + }) + return cpu + } + } -function showAdditionalSettings({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return features.length -} + function setRequests(resource, type) { + const modelPath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` -function getDefault({ getValue, model }, type) { - const val = getValue(model, `/spec/admin/${type}/default`) || '' - return val -} + const fullpath = `/spec/podResources/machine` + const modelPathValue = getValue(model, fullpath) -function isConfigAvailable({ getValue, model }) { - const val = getValue(model, '/spec/configuration') - return val !== '' -} + commit('wizard/model$update', { + path: commitPath, + value: val, + force: true, + }) -async function getReferSecrets({ getValue, model, storeGet, axios, discriminator }) { - const referSecret = getValue(discriminator, '/referSecret') - if (!referSecret) { - return [] + if (modelPathValue === 'custom') { + return + } + let commitCpuMemory, ModelPathValue + if (resource && type) { + const fullPath = `/spec/${type}/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/${type}/podResources/resources/requests/${resource}` + } else { + const fullPath = `/spec/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/podResources/resources/requests/${resource}` + } + let cpuMemoryValue + array.forEach((item) => { + if (item.value === ModelPathValue) { + // Parse subText like "CPU: 2, Memory: 2Gi" + const subText = item.subText || '' + if (resource === 'cpu') { + // Extract CPU value + const cpuMatch = subText.match(/CPU:\s*([^,]+)/) + cpuMemoryValue = cpuMatch ? cpuMatch[1].trim() : '' + } else if (resource === 'memory') { + // Extract Memory value + const memoryMatch = subText.match(/Memory:\s*(.+)/) + cpuMemoryValue = memoryMatch ? memoryMatch[1].trim() : '' + } + } + }) + commit('wizard/model$update', { + path: commitCpuMemory, + value: cpuMemoryValue, + force: true, + }) + return cpuMemoryValue } - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/metadata/release/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - - const options = [] - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) + function toggleTls() { + let modelPathValue = getValue(model, '/spec/mode') + commit('wizard/model$update', { + path: '/spec/admin/tls/default', + value: modelPathValue !== 'Standalone', + force: true, + }) + commit('wizard/model$update', { + path: '/spec/admin/tls/toggle', + value: modelPathValue !== 'Standalone', + force: true, }) - } catch (e) { - console.log(e) } - return options -} -function showAuthPasswordField({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showAdditionalSettings() { + // watchDependency('discriminator#/bundleApiLoaded') + return features.length + } -function showSecretDropdown({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function getDefault(type) { + const val = getValue(model, `/spec/admin/${type}/default`) || '' + return val + } -function showReferSecret({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/createAuthSecret') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue -} + async function getReferSecrets() { + const referSecret = getValue(discriminator, '/referSecret') + if (!referSecret) { + return [] + } -function getDefaultValue({ getValue, model }, path) { - const val = getValue(model, `/${path}`) || '' - return val -} + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/metadata/release/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` -function showReferSecretSwitch({ model, getValue, watchDependency, discriminator }) { - const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + const options = [] + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + return options + } -function onReferSecretChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) -} + function showAuthPasswordField() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !modelPathValue && showReferSecret() + } -function showArchiverAlert({ watchDependency, model, getValue, commit }) { - watchDependency('model#/spec/admin/storageClasses/default') + function showSecretDropdown() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !!modelPathValue && showReferSecret() + } - const mode = getValue(model, '/spec/mode') - if (mode === 'Standalone') return false + function showReferSecret() { + const modelPathValue = getValue(discriminator, '/createAuthSecret') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue + } - const stClass = getValue(model, '/spec/admin/storageClasses/default') - const found = archiverMap.find((item) => item.storageClass === stClass) - const show = !found?.annotation + function getDefaultValue(path) { + const val = getValue(model, `/${path}`) || '' + return val + } - // toggle archiver to false when storageClass annotation not found - if (show) + function showReferSecretSwitch() { + const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue && showReferSecret() + } + + function onReferSecretChange() { commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, + path: '/spec/authSecret/name', + value: '', force: true, }) - else onArchiverChange({ model, getValue, commit }) + } - return show -} + function showArchiverAlert() { + // watchDependency('model#/spec/admin/storageClasses/default') -function showArchiver({ watchDependency, getValue, model, commit }) { - watchDependency('model#/spec/mode') - const dbmode = getValue(model, '/spec/mode') + const mode = getValue(model, '/spec/mode') + if (mode === 'Standalone') return false - if (dbmode === 'Standalone') { - commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, - force: true, - }) - return false + const stClass = getValue(model, '/spec/admin/storageClasses/default') + const found = archiverMap.find((item) => item.storageClass === stClass) + const show = !found?.annotation + + // toggle archiver to false when storageClass annotation not found + if (show) + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + else onArchiverChange() + + return show } - return checkIfFeatureOn({ getValue, model }, 'archiver') -} -async function checkHostnameOrIP({ commit, model, getValue }) { - const tls = getValue(model, '/spec/admin/tls/default') - const expose = getValue(model, '/spec/admin/expose/default') - if (tls && expose) { - if (hostName) { + function showArchiver() { + // watchDependency('model#/spec/mode') + const dbmode = getValue(model, '/spec/mode') + + if (dbmode === 'Standalone') { commit('wizard/model$update', { - path: '/spec/hostName', - value: hostName, + path: '/spec/admin/archiver/enable/default', + value: false, force: true, }) + return false + } + return checkIfFeatureOn('archiver') + } + + function checkHostnameOrIP() { + const tls = getValue(model, '/spec/admin/tls/default') + const expose = getValue(model, '/spec/admin/expose/default') + if (tls && expose) { + if (hostName) { + commit('wizard/model$update', { + path: '/spec/hostName', + value: hostName, + force: true, + }) + } else { + commit('wizard/model$update', { + path: '/spec/ip', + value: ip, + force: true, + }) + } } else { + commit('wizard/model$update', { + path: '/spec/hostName', + value: '', + force: true, + }) commit('wizard/model$update', { path: '/spec/ip', - value: ip, + value: '', force: true, }) } - } else { - commit('wizard/model$update', { - path: '/spec/hostName', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/ip', - value: '', - force: true, - }) } -} -function onArchiverChange({ model, getValue, commit }) { - const isArchiverOn = getValue(model, '/spec/admin/archiver/enable/default') - const stClass = getValue(model, '/spec/admin/storageClasses/default') - const found = archiverMap.find((item) => item.storageClass === stClass) + function onArchiverChange() { + const isArchiverOn = getValue(model, '/spec/admin/archiver/enable/default') + const stClass = getValue(model, '/spec/admin/storageClasses/default') + const found = archiverMap.find((item) => item.storageClass === stClass) - if (isArchiverOn && found?.annotation) - commit('wizard/model$update', { - path: '/spec/archiverName', - value: found.annotation, - force: true, - }) - else - commit('wizard/model$update', { - path: '/spec/archiverName', - value: '', - force: true, - }) -} + if (isArchiverOn && found?.annotation) + commit('wizard/model$update', { + path: '/spec/archiverName', + value: found.annotation, + force: true, + }) + else + commit('wizard/model$update', { + path: '/spec/archiverName', + value: '', + force: true, + }) + } -async function getArchiverName({ axios, storeGet }) { - try { - archiverCalled = true - const params = storeGet('/route/params') - const { user, cluster, group, resource } = params - const url = `/clusters/${user}/${cluster}/proxy/storage.k8s.io/v1/storageclasses` - const resp = await axios.get(url) - - resp.data?.items?.forEach((item) => { - const annotations = item.metadata?.annotations - const classname = item.metadata?.name - const annotationKeyToFind = `${resource}.${group}/archiver` - archiverMap.push({ storageClass: classname, annotation: annotations[annotationKeyToFind] }) - return resp.data - }) - } catch (e) { - console.log(e) + async function getArchiverName() { + try { + archiverCalled = true + const params = storeGet('/route/params') + const { user, cluster, group, resource } = params + const url = `/clusters/${user}/${cluster}/proxy/storage.k8s.io/v1/storageclasses` + const resp = await axios.get(url) + + resp.data?.items?.forEach((item) => { + const annotations = item.metadata?.annotations + const classname = item.metadata?.name + const annotationKeyToFind = `${resource}.${group}/archiver` + archiverMap.push({ storageClass: classname, annotation: annotations[annotationKeyToFind] }) + return resp.data + }) + } catch (e) { + console.log(e) + } } -} -return { - getArchiverName, - onArchiverChange, - checkHostnameOrIP, - showArchiver, - showArchiverAlert, - showReferSecretSwitch, - onReferSecretChange, - getDefaultValue, - isRancherManaged, - showSecretDropdown, - showReferSecret, - getReferSecrets, - isConfigAvailable, - initBundle, - returnFalse, - setLimits, - setRequests, - toggleTls, - getNamespaces, - updateAlertValue, - getAdminOptions, - isToggleOn, - showAlerts, - getNodeTopology, - clearArbiterHidden, - returnFalse, - showHidden, - isConfigDatabaseOn, - notEqualToDatabaseMode, - filterNodeTopology, - onAuthChange, - setMonitoring, - isMachineNotCustom, - isMachineCustom, - showIssuer, - showArbiter, - clearConfiguration, - showStorageSizeField, - onBackupSwitch, - isVariantAvailable, - fetchJsons, - showAuthPasswordField, - isEqualToModelPathValue, - showAuthSecretField, - getResources, - getMySqlVersions, - onCreateAuthSecretChange, - getSecrets, - getMachineListForOptions, - setMachineToCustom, - updateAgentValue, - getCreateNameSpaceUrl, - ifCapiProviderIsNotEmpty, - ifDedicated, - dedicatedOnChange, - ifZones, - zonesOnChange, - getZones, - getSKU, - showMultiselectZone, - showSelectZone, - setStorageClass, - setReplicaNumber, - setRouterNumber, - setBackup, - showAdditionalSettings, - getDefault, + return { + getArchiverName, + onArchiverChange, + checkHostnameOrIP, + showArchiver, + showArchiverAlert, + showReferSecretSwitch, + onReferSecretChange, + getDefaultValue, + isRancherManaged, + showSecretDropdown, + showReferSecret, + getReferSecrets, + initBundle, + returnFalse, + setLimits, + setRequests, + toggleTls, + getNamespaces, + updateAlertValue, + getAdminOptions, + isToggleOn, + showAlerts, + getNodeTopology, + clearArbiterHidden, + showHidden, + isConfigDatabaseOn, + notEqualToDatabaseMode, + filterNodeTopology, + onAuthChange, + setMonitoring, + isMachineNotCustom, + isMachineCustom, + showIssuer, + showArbiter, + clearConfiguration, + showStorageSizeField, + onBackupSwitch, + isVariantAvailable, + fetchJsons, + showAuthPasswordField, + isEqualToModelPathValue, + showAuthSecretField, + getResources, + getMySqlVersions, + onCreateAuthSecretChange, + getSecrets, + getMachineListForOptions, + setMachineToCustom, + updateAgentValue, + getCreateNameSpaceUrl, + ifCapiProviderIsNotEmpty, + ifDedicated, + dedicatedOnChange, + ifZones, + zonesOnChange, + getZones, + getSKU, + showMultiselectZone, + showSelectZone, + setStorageClass, + setReplicaNumber, + setRouterNumber, + setBackup, + showAdditionalSettings, + getDefault, + } } diff --git a/charts/kubedbcom-ignite-editor-options/ui/create-ui.yaml b/charts/kubedbcom-ignite-editor-options/ui/create-ui.yaml index 5c0335f79f..5202a7f4ef 100644 --- a/charts/kubedbcom-ignite-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-ignite-editor-options/ui/create-ui.yaml @@ -1,243 +1,234 @@ -steps: -- form: - discriminator: - bundleApiLoaded: - default: false - type: boolean +step: +- type: single-step-form + loader: initBundle + elements: + - type: label-element + label: '' + subtitle: Select the Ignite version you want to deploy on Kubernetes. The chosen version determines the Ignite engine features, compatibility, and runtime behavior of your analytical database. + - disableUnselect: true + loader: getAdminOptions|databases/Ignite/versions + if: + type: function + name: isToggleOn|databases/Ignite/versions + label: Database version + schema: schema/properties/spec/properties/admin/properties/databases/properties/Ignite/properties/versions/properties/default + type: select + - init: + type: func + value: getDefault|databases/Ignite/mode + loader: getAdminOptions|databases/Ignite/mode + if: + type: function + name: isToggleOn|databases/Ignite/mode + label: Database mode + isHorizontal: true + watcher: + func: toggleTls + paths: + - schema/properties/spec/properties/mode + schema: schema/properties/spec/properties/mode + type: radio + - if: + type: function + name: isEqualToModelPathValue|Replicaset|/spec/mode + label: Replicaset number + schema: schema/properties/spec/properties/replicas + type: input + - elements: + - type: label-element + label: '' + subtitle: Select a machine profile to allocate CPU and memory resources for your analytical database. Choose 'custom' to manually specify resource requirements or select a predefined profile. + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu + if: + type: function + name: isMachineCustom + label: cpu + watcher: + func: setRequests|cpu + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory + if: + type: function + name: isMachineCustom + label: memory + watcher: + func: setRequests|memory + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + label: Machine_profile + showLabels: true + type: block-layout + - type: horizontal-layout + showLabels: true elements: - - computed: initBundle - if: returnFalse - type: label-element - - disableUnselect: true - fetch: getAdminOptions|databases/Ignite/versions - if: isToggleOn|databases/Ignite/versions - label: - text: labels.database.version - schema: - $ref: schema#/properties/spec/properties/admin/properties/databases/properties/Ignite/properties/versions/properties/default + - loader: getAdminOptions|storageClasses + if: + type: function + name: isToggleOn|storageClasses + label: Storage class + schema: schema/properties/spec/properties/admin/properties/storageClasses/properties/default type: select - - computed: getDefault|databases/Ignite/mode - fetch: getAdminOptions|databases/Ignite/mode - hasDescription: true - if: isToggleOn|databases/Ignite/mode - label: - text: labels.database.mode - onChange: toggleTls - schema: - $ref: schema#/properties/spec/properties/mode - type: radio - - if: isEqualToModelPathValue|Replicaset|/spec/mode - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/replicas + - label: Storage size + schema: schema/properties/spec/properties/persistence/properties/size type: input + - description: Configure Credentials, Deployment Mode etc. + elements: - elements: - - computed: setMachineToCustom - customClass: mt-10 - fetch: getMachineListForOptions - label: - text: labels.machine - schema: - $ref: schema#/properties/spec/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.cpu - onChange: setRequests|cpu - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.memory - onChange: setRequests|memory - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - label: - text: labels.machine_profile - show_label: true - type: single-step-form - - fetch: getAdminOptions|storageClasses - if: isToggleOn|storageClasses - label: - text: labels.storage.class - schema: - $ref: schema#/properties/spec/properties/admin/properties/storageClasses/properties/default + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/annotations + label: Labels & Annotations + showLabels: true + hideBlock: true + type: block-layout + - init: + type: func + value: getDefault|deletionPolicy + customClass: mt-20 + if: + type: function + name: isToggleOn|deletionPolicy + label: Deletion Policy + watcher: + func: setStorageClass + paths: + - schema/properties/spec/properties/deletionPolicy + options: + - description: options.deletionPolicy.delete.description + text: Delete + value: Delete + - description: options.deletionPolicy.halt.description + text: Halt + value: Halt + - description: options.deletionPolicy.wipeOut.description + text: WipeOut + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: DoNotTerminate + value: DoNotTerminate + schema: schema/properties/spec/properties/deletionPolicy + type: select + - if: + type: function + name: getDefaultValue|spec/admin/authCredential/customize + label: Provide Authentication Credentials? + watcher: + func: onAuthChange + paths: + - temp/createAuthSecret + schema: temp/createAuthSecret + type: switch + - if: + type: function + name: showReferSecretSwitch + label: Refer existing Secret? + watcher: + func: onReferSecretChange + paths: + - temp/referSecret + schema: temp/referSecret + type: switch + - loader: getReferSecrets + if: + type: function + name: showSecretDropdown + label: Secret + schema: schema/properties/spec/properties/authSecret/properties/name type: select - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/persistence/properties/size + - if: + type: function + name: showReferSecret + label: password + schema: schema/properties/spec/properties/authSecret/properties/password type: input - - accordion: true - description: - text: Configure Credentials, Deployment Mode etc. - discriminator: - configDatabase: - default: false - type: boolean - createAuthSecret: - default: false - type: boolean - referSecret: - default: false - type: boolean - elements: - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties - type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties - type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - computed: getDefault|deletionPolicy - customClass: mt-20 - if: isToggleOn|deletionPolicy - 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/spec/properties/deletionPolicy - type: select - - if: getDefaultValue|spec/admin/authCredential/customize - label: - text: Provide Authentication Credentials? - onChange: onAuthChange - schema: - $ref: discriminator#/createAuthSecret - type: switch - - if: showReferSecretSwitch - label: - text: Refer existing Secret? - onChange: onReferSecretChange - schema: - $ref: discriminator#/referSecret - type: switch - - fetch: getReferSecrets - if: showSecretDropdown - label: - text: Secret - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/name - type: select - - if: showReferSecret - label: - text: labels.password - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/password - type: input - - computed: isConfigAvailable - if: getDefaultValue|spec/admin/customConfiguration - label: - text: Configure Database? - onChange: clearConfiguration - schema: - $ref: discriminator#/configDatabase - type: switch - - if: isConfigDatabaseOn - label: - text: Configuration - schema: - $ref: schema#/properties/spec/properties/configuration - type: editor - - hasDescription: true - if: isToggleOn|deployment - label: - text: labels.deployment.name - options: - - description: labels.deployment.shared - text: Shared - value: Shared - - description: labels.deployment.dedicated - text: Dedicated - value: Dedicated - schema: - $ref: schema#/properties/spec/properties/admin/properties/deployment/properties/default - type: radio - - if: isToggleOn|clusterTier - isHorizontal: true - label: - text: labels.clusterTier - options: - - text: General Purpose - value: GeneralPurpose - - text: Memory Optimized - value: MemoryOptimized - - text: CPU Optimized - value: CPUOptimized - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/default - type: radio - - disableUnselect: true - fetch: getAdminOptions|clusterTier/placement - if: isToggleOn|clusterTier/placement - label: - text: labels.placement - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default - type: select - - disableUnselect: true - fetch: getNodeTopology - if: isToggleOn|clusterTier/nodeTopology - label: - text: labels.nodeTopology - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default - type: select - hideForm: true - label: - text: Advanced Configuration - show_label: true - type: single-step-form - type: single-step-form + - if: + type: function + name: getDefaultValue|spec/admin/customConfiguration + label: Configure Database? + watcher: + func: clearConfiguration + paths: + - temp/configDatabase + schema: temp/configDatabase + type: switch + - if: + type: function + name: isConfigDatabaseOn + label: Configuration + # hasCopy: true + schema: schema/properties/spec/properties/configuration + type: textarea + - if: + type: function + name: isToggleOn|deployment + label: Deployment name + options: + - description: labels.deployment.shared + text: Shared + value: Shared + - description: labels.deployment.dedicated + text: Dedicated + value: Dedicated + schema: schema/properties/spec/properties/admin/properties/deployment/properties/default + type: radio + - if: + type: function + name: isToggleOn|clusterTier + isHorizontal: true + label: Cluster Tier + options: + - text: General Purpose + value: GeneralPurpose + - text: Memory Optimized + value: MemoryOptimized + - text: CPU Optimized + value: CPUOptimized + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/default + type: radio + - disableUnselect: true + loader: getAdminOptions|clusterTier/placement + if: + type: function + name: isToggleOn|clusterTier/placement + label: Placement + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + type: select + - disableUnselect: true + loader: getNodeTopology + if: + type: function + name: isToggleOn|clusterTier/nodeTopology + label: Node Topology + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + type: select + label: Advanced Configuration + showLabels: true + type: block-layout id: options - title: steps.0.label type: multi-step-form diff --git a/charts/kubedbcom-ignite-editor-options/ui/functions.js b/charts/kubedbcom-ignite-editor-options/ui/functions.js index 26d7b776bd..af857d89c2 100644 --- a/charts/kubedbcom-ignite-editor-options/ui/functions.js +++ b/charts/kubedbcom-ignite-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -315,1063 +317,1118 @@ const modeDetails = { }, } -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) -function showAuthSecretField({ discriminator, getValue, watchDependency }) { - return !showAuthPasswordField({ - discriminator, - getValue, - watchDependency, - }) -} + setDiscriminatorValue('bundleApiLoaded', false) + setDiscriminatorValue('configDatabase', false) + setDiscriminatorValue('createAuthSecret', false) + setDiscriminatorValue('referSecret', false) -async function getResources({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + function showAuthSecretField() { + return !showAuthPasswordField() + } - const resources = (resp && resp.data && resp.data.items) || [] + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return resources -} + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) -async function getMySqlVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + const resources = (resp && resp.data && resp.data.items) || [] - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, - }, - }, + resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true + }) + return resources } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) + async function getMySqlVersions(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - const resources = (resp && resp.data && resp.data.items) || [] + const queryParams = { + filter: { + items: { + metadata: { name: null }, + spec: { version: null, deprecated: null }, + }, + }, + } - // keep only non deprecated versions - const filteredMySqlVersions = resources.filter((item) => item.spec && !item.spec.deprecated) + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: queryParams, + }, + ) - filteredMySqlVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredMySqlVersions -} + const resources = (resp && resp.data && resp.data.items) || [] -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/spec/authSecret/name') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/spec/authSecret/password') + // keep only non deprecated versions + const filteredMySqlVersions = resources.filter((item) => item.spec && !item.spec.deprecated) + + filteredMySqlVersions.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + const specVersion = (item.spec && item.spec.version) || '' + item.text = `${name} (${specVersion})` + item.value = name + return true + }) + return filteredMySqlVersions } -} -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') + function onCreateAuthSecretChange() { + const createAuthSecret = getValue(discriminator, '/createAuthSecret') + if (createAuthSecret) { + commit('wizard/model$delete', '/spec/authSecret/name') + } else if (createAuthSecret === false) { + commit('wizard/model$delete', '/spec/authSecret/password') + } + } - if (owner && cluster && namespace) { - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { - items: { - data: { username: null, password: null }, - metadata: { name: null }, - type: null, + 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') + + if (owner && cluster && namespace) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { + items: { + data: { username: null, password: null }, + metadata: { name: null }, + type: null, + }, }, }, }, - }, - ) + ) - const secrets = (resp && resp.data && resp.data.items) || [] + const secrets = (resp && resp.data && resp.data.items) || [] - const filteredSecrets = secrets.filter((item) => { - const validType = [ - 'kubernetes.io/service-account-token', - 'Opaque', - 'kubernetes.io/basic-auth', - ] - return validType.includes(item.type) - }) + const filteredSecrets = secrets.filter((item) => { + const validType = [ + 'kubernetes.io/service-account-token', + 'Opaque', + 'kubernetes.io/basic-auth', + ] + 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) + 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 [] } - return [] -} -function getMachineListForOptions({ model, getValue }) { - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') let array = [] + function getMachineListForOptions() { + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') - if (available.length) { - array = available.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - else { - let subText = '', - text = '' - const machineData = machinesFromPreset.find((val) => val.id === machine) - if (machineData) { - subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` - text = machineData.name ? machineData.name : machineData.id - } - return { text, subText, value: machine } - } - }) - } else { - array = machineList - .map((machine) => { + if (available.length) { + array = available.map((machine) => { if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + else { + let subText = '', + text = '' + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + text = machineData.name ? machineData.name : machineData.id + } + return { text, subText, value: machine } + } }) - .filter((val) => !!val) + } else { + array = machineList + .map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { text, subText, value: machine } + }) + .filter((val) => !!val) + } + return array } - return array -} -function setMachineToCustom({ getValue, model }) { - const machine = getValue(model, '/spec/admin/machineProfiles/default') - return machine || 'custom' -} + function setMachineToCustom() { + const machine = getValue(model, '/spec/admin/machineProfiles/default') + return machine || 'custom' + } -async function fetchJsons({ axios, itemCtx }) { - let ui = {} - let language = {} - let functions = {} - const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart + async function fetchJsons() { + 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) + 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, + } } - return { - ui: ui.data || {}, - language: language.data || {}, - functions, + function updateAgentValue(val) { + commit('wizard/model$update', { + path: '/spec/monitoring/agent', + value: val ? 'prometheus.io/operator' : '', + force: true, + }) + + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: val ? 'warning' : 'none', + force: true, + }) } -} -function updateAgentValue({ commit }, val) { - commit('wizard/model$update', { - path: '/spec/monitoring/agent', - value: val ? 'prometheus.io/operator' : '', - force: true, - }) - - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: val ? 'warning' : 'none', - force: true, - }) -} + function setReplicaNumber() { + const modelPathValue = getValue(model, '/spec/mode') + if (modelPathValue === 'Topology') { + return 2 + } else return 1 + } -function setReplicaNumber({ model, getValue }) { - const modelPathValue = getValue(model, '/spec/mode') - if (modelPathValue === 'Topology') { - return 2 - } else return 1 -} -function setRouterNumber({ model, getValue }) { - const modelPathValue = getValue(model, '/spec/mode') - if (modelPathValue === 'Topology') { - return 3 - } else return 1 -} + function setRouterNumber() { + const modelPathValue = getValue(model, '/spec/mode') + if (modelPathValue === 'Topology') { + return 3 + } else return 1 + } -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function getCreateNameSpaceUrl() { + 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + const domain = storeGet('/domain') || '' + if (domain.includes('bb.test')) { + return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } } -} -const ifCapiProviderIsNotEmpty = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/provider') - const val = getValue(model, '/form/capi/provider') - if (val) return true -} + const ifCapiProviderIsNotEmpty = () => { + // watchDependency('model#/form/capi/provider') + const val = getValue(model, '/form/capi/provider') + if (val) return true + } -const showMultiselectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') + const showMultiselectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') - if (val === 'capz' && ifDedicated({ model, getValue })) return true -} + if (val === 'capz' && ifDedicated()) return true + } -const showSelectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') - if (val !== 'capz' && ifDedicated({ model, getValue })) return true -} + const showSelectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') + if (val !== 'capz' && ifDedicated()) return true + } -const ifDedicated = ({ model, getValue }) => { - const val = getValue(model, 'form/capi/dedicated') - if (val) return true -} + const ifDedicated = () => { + const val = getValue(model, 'form/capi/dedicated') + if (val) return true + } -const dedicatedOnChange = ({ model, getValue, commit }) => { - const val = getValue(model, 'form/capi/dedicated') - if (!val) { - commit('wizard/model$delete', 'form/capi/zones') - commit('wizard/model$delete', 'form/capi/sku') + const dedicatedOnChange = () => { + const val = getValue(model, 'form/capi/dedicated') + if (!val) { + commit('wizard/model$delete', 'form/capi/zones') + commit('wizard/model$delete', 'form/capi/sku') + } } -} -const ifZones = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/zones') - watchDependency('model#/form/capi/dedicated') - const zones = getValue(model, 'form/capi/zones') || [] - const isDedicated = getValue(model, 'form/capi/dedicated') - if (zones.length && isDedicated) return true -} + const ifZones = () => { + // watchDependency('model#/form/capi/zones') + // watchDependency('model#/form/capi/dedicated') + const zones = getValue(model, 'form/capi/zones') || [] + const isDedicated = getValue(model, 'form/capi/dedicated') + if (zones.length && isDedicated) return true + } -const zonesOnChange = ({ model, getValue, commit }) => { - const zones = getValue(model, 'form/capi/zones') || [] - if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') -} + const zonesOnChange = () => { + const zones = getValue(model, 'form/capi/zones') || [] + if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') + } -async function getZones({ storeGet, axios, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const isDedicated = getValue(model, 'form/capi/dedicated') - if (isDedicated) { - try { - const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) - const val = resp.data.map((item) => { - return { value: item, text: item } - }) - return val - } catch (e) { - console.log(e) - return [] + async function getZones() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const isDedicated = getValue(model, 'form/capi/dedicated') + if (isDedicated) { + try { + const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) + const val = resp.data.map((item) => { + return { value: item, text: item } + }) + return val + } catch (e) { + console.log(e) + return [] + } } } -} -async function getSKU({ storeGet, axios, model, getValue, watchDependency }) { - watchDependency('model#/form/capi/zones') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const zones = getValue(model, 'form/capi/zones') || [] - if (zones.length) { - try { - let url = `clustersv2/${owner}/${cluster}/vms?` - if (typeof zones === 'string') { - url += `zones=${encodeURIComponent(zones)}` - } else { - zones.forEach((item) => { - url += `zones=${encodeURIComponent(item)}&` + async function getSKU() { + // watchDependency('model#/form/capi/zones') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const zones = getValue(model, 'form/capi/zones') || [] + if (zones.length) { + try { + let url = `clustersv2/${owner}/${cluster}/vms?` + if (typeof zones === 'string') { + url += `zones=${encodeURIComponent(zones)}` + } else { + zones.forEach((item) => { + url += `zones=${encodeURIComponent(item)}&` + }) + url = url.slice(0, -1) + } + const resp = await axios.get(url) + const val = resp.data.map((item) => { + return { + value: item.name, + text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, + } }) - url = url.slice(0, -1) + return val + } catch (e) { + console.log(e) + return [] } - const resp = await axios.get(url) - const val = resp.data.map((item) => { - return { - value: item.name, - text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, - } - }) - return val - } catch (e) { - console.log(e) - return [] } } -} - -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} -function setStorageClass({ model, getValue, commit, discriminator, watchDependency }) { - const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' - let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' - const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] - const suffix = '-retain' - - const simpleClassList = storageClassList.filter((item) => { - return !item.endsWith(suffix) - }) - const retainClassList = storageClassList.filter((item) => { - return item.endsWith(suffix) - }) - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] - } else { - storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] - } - - const isChangeable = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'storageClasses', - ) - if (isChangeable && storageClass) { - commit('wizard/model$update', { - path: '/spec/admin/storageClasses/default', - value: storageClass, - force: true, - }) + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false } -} - -function showAlerts({ watchDependency, model, getValue, discriminator }) { - watchDependency('discriminator#/monitoring') - const isMonitorEnabled = getValue(discriminator, '/monitoring') - return ( - isMonitorEnabled && isToggleOn({ getValue, model, discriminator, watchDependency }, 'alert') - ) -} -function onBackupSwitch({ discriminator, getValue, commit }) { - const isBackupOn = getValue(discriminator, '/backup') - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: isBackupOn ? 'KubeStash' : '', - force: true, - }) -} + function setStorageClass() { + const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' + let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' + const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] + const suffix = '-retain' -function clearArbiterHidden({ commit }) { - commit('wizard/model$update', { - path: `/spec/arbiter/enabled`, - value: false, - force: true, - }) - - commit('wizard/model$update', { - path: `/spec/hidden/enabled`, - value: false, - force: true, - }) -} + const simpleClassList = storageClassList.filter((item) => { + return !item.endsWith(suffix) + }) + const retainClassList = storageClassList.filter((item) => { + return item.endsWith(suffix) + }) + if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { + storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] + } else { + storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + } -let placement = [] -let versions = [] -let storageClass = [] -let clusterIssuers = [] -let nodetopologiesShared = [] -let nodetopologiesDedicated = [] -let features = [] -async function initBundle({ commit, model, getValue, axios, storeGet, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - - let db = getValue(model, '/metadata/resource/kind') - db = db.toLowerCase() - let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` - const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - - try { - const resp = await axios.get(url) - features = resp.data.features || [] - placement = resp.data.placementpolicies || [] - versions = resp.data.versions || [] - storageClass = resp.data.storageclasses || [] - clusterIssuers = resp.data.clusterissuers || [] - nodetopologiesDedicated = resp.data.dedicated || [] - nodetopologiesShared = resp.data.shared || [] - - const response = await axios.get(annotationUrl) - const annotations = response.data?.metadata?.annotations || {} - const uidRange = annotations['openshift.io/sa.scc.uid-range'] - if (uidRange) { - const val = uidRange.split('/')[0] + const isChangeable = isToggleOn('storageClasses') + if (isChangeable && storageClass) { commit('wizard/model$update', { - path: '/spec/openshift/securityContext/runAsUser', - value: val, + path: '/spec/admin/storageClasses/default', + value: storageClass, force: true, }) } - } catch (e) { - console.log(e) } - commit('wizard/model$update', { - path: '/spec/deletionPolicy', - value: getDefault({ getValue, model }, 'deletionPolicy'), - force: true, - }) - - if (!getValue(model, `/spec/admin/databases/Ignite/mode/toggle`)) { - let defMode = getDefault({ getValue, model }, 'databases/Ignite/mode') || '' - if (defMode === '') { - const arr = getValue(model, '/spec/databases/Ignite/mode/available') || [] - if (arr.length) defMode = arr[0] - } - commit('wizard/model$update', { - path: '/spec/mode', - value: defMode, - force: true, - }) + function showAlerts() { + // watchDependency('discriminator#/monitoring') + const isMonitorEnabled = getValue(discriminator, '/monitoring') + return isMonitorEnabled && isToggleOn('alert') } - if (!features.includes('tls')) { + function onBackupSwitch() { + const isBackupOn = getValue(discriminator, '/backup') commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: false, + path: '/spec/backup/tool', + value: isBackupOn ? 'KubeStash' : '', force: true, }) } - if (!features.includes('binding')) { + + function clearArbiterHidden() { commit('wizard/model$update', { - path: '/spec/admin/expose/default', + path: `/spec/arbiter/enabled`, value: false, force: true, }) - } - if (!features.includes('monitoring')) { - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: 'none', - force: true, - }) - } - if (!features.includes('backup')) { + commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', + path: `/spec/hidden/enabled`, value: false, force: true, }) - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: '', - force: true, - }) } - setDiscriminatorValue('/bundleApiLoaded', true) -} - -function fetchOptions({ model, getValue, commit }, type) { - let kind = getValue(model, '/metadata/resource/kind') + let placement = [] + let versions = [] + let storageClass = [] + let clusterIssuers = [] + let nodetopologiesShared = [] + let nodetopologiesDedicated = [] + let features = [] + let namespaces = [] + async function initBundle() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + + let db = getValue(model, '/metadata/resource/kind') + db = db.toLowerCase() + let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` + const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - let returnArray = [] - if (type === 'clusterTier/placement') { - returnArray = placement - } else if (type === `databases/${kind}/versions`) { - returnArray = versions - } else if (type === 'storageClasses') { - returnArray = storageClass - } else if (type === 'clusterIssuers') { - returnArray = clusterIssuers - } + try { + const resp = await axios.get(url) + features = resp.data.features || [] + placement = resp.data.placementpolicies || [] + versions = resp.data.versions || [] + storageClass = resp.data.storageclasses || [] + clusterIssuers = resp.data.clusterissuers || [] + nodetopologiesDedicated = resp.data.dedicated || [] + nodetopologiesShared = resp.data.shared || [] + + const response = await axios.get(annotationUrl) + const annotations = response.data?.metadata?.annotations || {} + const uidRange = annotations['openshift.io/sa.scc.uid-range'] + if (uidRange) { + const val = uidRange.split('/')[0] + commit('wizard/model$update', { + path: '/spec/openshift/securityContext/runAsUser', + value: val, + force: true, + }) + } + } catch (e) { + console.log(e) + } - if (returnArray.length === 1) { - const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: path, - value: returnArray[0], + path: '/spec/deletionPolicy', + value: getDefault('deletionPolicy'), force: true, }) - } - return returnArray -} - -function getAdminOptions({ getValue, model, watchDependency, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') + if (!getValue(model, `/spec/admin/databases/Ignite/mode/toggle`)) { + let defMode = getDefault('databases/Ignite/mode') || '' + if (defMode === '') { + const arr = getValue(model, '/spec/databases/Ignite/mode/available') || [] + if (arr.length) defMode = arr[0] + } + commit('wizard/model$update', { + path: '/spec/mode', + value: defMode, + force: true, + }) + } - const options = getValue(model, `/spec/admin/${type}/available`) || [] + if (!features.includes('tls')) { + commit('wizard/model$update', { + path: '/spec/admin/tls/default', + value: false, + force: true, + }) + } + if (!features.includes('binding')) { + commit('wizard/model$update', { + path: '/spec/admin/expose/default', + value: false, + force: true, + }) + } + if (!features.includes('monitoring')) { + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: 'none', + force: true, + }) + } + if (!features.includes('backup')) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: '', + force: true, + }) + } - if (options.length === 0) { - return fetchOptions({ model, getValue, commit }, type) + namespaces = getNamespaces() + setDiscriminatorValue('/bundleApiLoaded', true) } - if (type.endsWith('/mode')) { - return ( - options?.map((item) => ({ - description: modeDetails[item]?.description || '', - text: modeDetails[item]?.text || '', - value: item, - })) || [] - ) - } - return options -} -function checkIfFeatureOn({ getValue, model }, type) { - let val = getValue(model, `/spec/admin/${type}/toggle`) - if (type === 'backup' || type === 'archiver') { - val = getValue(model, `/spec/admin/${type}/enable/toggle`) + function fetchNamespaces() { + // watchDependency('discriminator#/bundleApiLoaded') + return namespaces } - const backupVal = getValue(model, '/spec/backup/tool') - if (type === 'backup') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } else if (type === 'tls') { - return features.includes('tls') && val - } else if (type === 'expose') { - return features.includes('binding') && val - } else if (type === 'monitoring') { - return features.includes('monitoring') && val - } else if (type === 'archiver') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } -} + function fetchOptions(type) { + let kind = getValue(model, '/metadata/resource/kind') + + let returnArray = [] + if (type === 'clusterTier/placement') { + returnArray = placement + } else if (type === `databases/${kind}/versions`) { + returnArray = versions + } else if (type === 'storageClasses') { + returnArray = storageClass + } else if (type === 'clusterIssuers') { + returnArray = clusterIssuers + } -function isToggleOn({ getValue, model, discriminator, watchDependency }, type) { - watchDependency('discriminator#/bundleApiLoaded') - watchDependency('model#/spec/admin/deployment/default') - const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') - let deploymentType = getValue(model, `/spec/admin/deployment/default`) - if ( - type === 'tls' || - type === 'backup' || - type === 'expose' || - type === 'monitoring' || - type === 'archiver' - ) { - return checkIfFeatureOn({ getValue, model }, type) - } else if ( - type === 'clusterTier' || - type === 'clusterTier/placement' || - type === 'clusterTier/nodeTopology' - ) { - if (deploymentType === 'Dedicated' && bundleApiLoaded) return true - else return false - } else if (type === 'deployment') { - const deploymentType = getValue(model, '/spec/admin/deployment/default') - if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + if (returnArray.length === 1) { + const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: '/spec/admin/deployment/default', - value: 'Shared', + path: path, + value: returnArray[0], force: true, }) } - return ( - getValue(model, `/spec/admin/${type}/toggle`) && - nodetopologiesDedicated.length && - bundleApiLoaded - ) - } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded -} -async function getNodeTopology({ model, getValue, axios, storeGet, watchDependency }) { - watchDependency('model#/spec/admin/deployment/default') - watchDependency('model#/spec/admin/clusterTier/default') - const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' - const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' - let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + return returnArray + } - const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + function getAdminOptions(type) { + // watchDependency('discriminator#/bundleApiLoaded') - if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared - else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + const options = getValue(model, `/spec/admin/${type}/available`) || [] - const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) - return filteredList -} + if (options.length === 0) { + return fetchOptions(type) + } + if (type.endsWith('/mode')) { + return ( + options?.map((item) => ({ + description: modeDetails[item]?.description || '', + text: modeDetails[item]?.text || '', + value: item, + })) || [] + ) + } + return options + } + + let backupToolInitialValue = '' + function checkIfFeatureOn(type) { + let val = getValue(model, `/spec/admin/${type}/toggle`) + if (type === 'backup' || type === 'archiver') { + val = getValue(model, `/spec/admin/${type}/enable/toggle`) + } + const backupVal = getValue(model, '/spec/backup/tool') + if (type === 'backup') { + if (backupToolInitialValue === '') { + backupToolInitialValue = + features.includes('backup') && backupVal === 'KubeStash' && val ? 'on' : 'off' + return features.includes('backup') && backupVal === 'KubeStash' && val + } else { + if (backupToolInitialValue === 'on') { + return true + } else { + return false + } + } + } else if (type === 'tls') { + return features.includes('tls') && val + } else if (type === 'expose') { + return features.includes('binding') && val + } else if (type === 'monitoring') { + return features.includes('monitoring') && val + } else if (type === 'archiver') { + return features.includes('backup') && val + } + } + + function isToggleOn(type) { + // watchDependency('discriminator#/bundleApiLoaded') + // watchDependency('model#/spec/admin/deployment/default') + const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') + let deploymentType = getValue(model, `/spec/admin/deployment/default`) + if ( + type === 'tls' || + type === 'backup' || + type === 'expose' || + type === 'monitoring' || + type === 'archiver' + ) { + return checkIfFeatureOn(type) + } else if ( + type === 'clusterTier' || + type === 'clusterTier/placement' || + type === 'clusterTier/nodeTopology' + ) { + if (deploymentType === 'Dedicated' && bundleApiLoaded) return true + else return false + } else if (type === 'deployment') { + const deploymentType = getValue(model, '/spec/admin/deployment/default') + if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + commit('wizard/model$update', { + path: '/spec/admin/deployment/default', + value: 'Shared', + force: true, + }) + } + return ( + getValue(model, `/spec/admin/${type}/toggle`) && + nodetopologiesDedicated.length && + bundleApiLoaded + ) + } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded + } -function filterNodeTopology(list, tier, provider) { - // first filter the list from value that exists from the filtered list got from API - const filteredlist = list + async function getNodeTopology() { + // watchDependency('model#/spec/admin/deployment/default') + // watchDependency('model#/spec/admin/clusterTier/default') + const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' + const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' + let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] - // filter the list based on clusterTier - if (provider === 'EKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('c') - else if (tier === 'MemoryOptimized') return item.startsWith('r') - else return !item.startsWith('c') && !item.startsWith('r') - }) - } else if (provider === 'AKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - else - return ( - !(item.startsWith('f') || item.startsWith('fx')) && - !( + const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + + if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared + else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + + const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) + return filteredList + } + + function filterNodeTopology(list, tier, provider) { + // first filter the list from value that exists from the filtered list got from API + const filteredlist = list + + // filter the list based on clusterTier + if (provider === 'EKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('c') + else if (tier === 'MemoryOptimized') return item.startsWith('r') + else return !item.startsWith('c') && !item.startsWith('r') + }) + } else if (provider === 'AKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('e') || item.startsWith('eb') || item.startsWith('ec') || item.startsWith('m') || item.startsWith('d') ) - ) - }) - } else if (provider === 'GKE') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') - return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - else - return ( - !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && - !( + else + return ( + !(item.startsWith('f') || item.startsWith('fx')) && + !( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + ) + }) + } else if (provider === 'GKE') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') + return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('x4') || item.startsWith('m1') || item.startsWith('m2') || item.startsWith('m3') ) - ) - }) - } else return filteredlist -} + else + return ( + !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && + !( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + ) + }) + } else return filteredlist + } -function returnFalse() { - return false -} + function returnFalse() { + return false + } -function isConfigDatabaseOn({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configDatabase') - return getValue(discriminator, '/configDatabase') -} -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} -function showStorageSizeField({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - const validType = [] - return !validType.includes(modelPathValue) -} -function showHidden({ watchDependency, model, getValue }) { - watchDependency('model#/spec/hidden/enabled') - const isHiddenOn = getValue(model, '/spec/hidden/enabled') || '' - const notStandalone = notEqualToDatabaseMode({ model, getValue, watchDependency }, 'Standalone') - return isHiddenOn && notStandalone -} -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} -function showArbiter({ watchDependency, model, getValue }) { - watchDependency('model#/spec/arbiter/enabled') - const isArbiterOn = getValue(model, '/spec/arbiter/enabled') || '' - const notStandalone = notEqualToDatabaseMode({ model, getValue, watchDependency }, 'Standalone') - return isArbiterOn && notStandalone -} -function clearConfiguration({ discriminator, getValue, commit }) { - const configOn = getValue(discriminator, '/configDatabase') + function isConfigDatabaseOn() { + // watchDependency('discriminator#/configDatabase') + return getValue(discriminator, '/configDatabase') + } - if (!configOn) { - commit('wizard/model$delete', '/spec/configuration') + function notEqualToDatabaseMode(mode) { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + return modelPathValue && modelPathValue !== mode } -} -function showIssuer({ model, getValue, watchDependency, discriminator }) { - watchDependency('model#/spec/admin/tls/default') - const isTlsEnabled = getValue(model, '/spec/admin/tls/default') - const isIssuerToggleEnabled = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'clusterIssuers', - ) - return isTlsEnabled && isIssuerToggleEnabled -} -function onAuthChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/authSecret/password', - value: '', - force: true, - }) -} -function setMonitoring({ getValue, model }) { - const agent = getValue(model, '/spec/admin/monitoring/agent') || '' - return !!agent -} + function showStorageSizeField() { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + const validType = [] + return !validType.includes(modelPathValue) + } -function setBackup({ model, getValue }) { - const backup = getValue(model, '/spec/backup/tool') - const val = getValue(model, '/spec/admin/backup/enable/default') - return backup === 'KubeStash' && features.includes('backup') && val -} + function showHidden() { + // watchDependency('model#/spec/hidden/enabled') + const isHiddenOn = getValue(model, '/spec/hidden/enabled') || '' + const notStandalone = notEqualToDatabaseMode('Standalone') + return isHiddenOn && notStandalone + } -function isMachineCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue === 'custom' -} + function showArbiter() { + // watchDependency('model#/spec/arbiter/enabled') + const isArbiterOn = getValue(model, '/spec/arbiter/enabled') || '' + const notStandalone = notEqualToDatabaseMode('Standalone') + return isArbiterOn && notStandalone + } -function isMachineNotCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue !== 'custom' && !!modelPathValue -} -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], + function clearConfiguration() { + const configOn = getValue(discriminator, '/configDatabase') + + if (!configOn) { + commit('wizard/model$delete', '/spec/configuration') + } + } + + function showIssuer() { + // watchDependency('model#/spec/admin/tls/default') + const isTlsEnabled = getValue(model, '/spec/admin/tls/default') + const isIssuerToggleEnabled = isToggleOn('clusterIssuers') + return isTlsEnabled && isIssuerToggleEnabled + } + + function onAuthChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/spec/authSecret/password', + value: '', + force: true, + }) + } + + function setMonitoring() { + const agent = getValue(model, '/spec/admin/monitoring/agent') || '' + return !!agent + } + + function setBackup() { + const backup = getValue(model, '/spec/backup/tool') + const val = getValue(model, '/spec/admin/backup/enable/default') + return backup === 'KubeStash' && features.includes('backup') && val + } + + function isMachineCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue === 'custom' + } + + function isMachineNotCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue !== 'custom' && !!modelPathValue + } + + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, }, - }, - ) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] + ) + const projects = resp?.data?.status?.projects + if (projects) { + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } + } catch (e) { + console.log(e) } - } catch (e) { - console.log(e) + return [] } - return [] -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } -function updateAlertValue({ commit, model, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const alert = isMonitorEnabled ? 'warning' : 'none' - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: alert, - force: true, - }) - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} + function updateAlertValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const alert = isMonitorEnabled ? 'warning' : 'none' + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: alert, + force: true, + }) + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: agent, + force: true, + }) + } -function setLimits({ model, getValue, commit, watchDependency }, resource, type) { - const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' - watchDependency(`model#${path}`) - const selectedMachine = getValue(model, path) || 'custom' - const reqCommitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - const comparePath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - - const resourceValue = getValue(model, comparePath) - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - - let cpu = '', - memory = '' - if (available.length && selectedMachine !== 'custom') { - const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) - if (machineData) { - cpu = machineData.limits.cpu - memory = machineData.limits.memory + function setLimits(resource, type) { + const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' + // watchDependency(`model#${path}`) + const selectedMachine = getValue(model, path) || 'custom' + const reqCommitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + const comparePath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + + const resourceValue = getValue(model, comparePath) + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + let cpu = '', + memory = '' + if (available.length && selectedMachine !== 'custom') { + const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) + if (machineData) { + cpu = machineData.limits.cpu + memory = machineData.limits.memory + } + } else { + if (selectedMachine === 'custom') { + cpu = resourceValue + memory = resourceValue + } else { + cpu = machines[selectedMachine].resources.limits.cpu + memory = machines[selectedMachine].resources.limits.memory + } } - } else { - if (selectedMachine === 'custom') { - cpu = resourceValue - memory = resourceValue + + if (resource === 'memory') { + commit('wizard/model$update', { + path: reqCommitPath, + value: memory, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: memory, + force: true, + }) + return memory } else { - cpu = machines[selectedMachine].resources.limits.cpu - memory = machines[selectedMachine].resources.limits.memory + commit('wizard/model$update', { + path: reqCommitPath, + value: cpu, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: cpu, + force: true, + }) + return cpu } } - if (resource === 'memory') { + function setRequests(resource, type) { + const modelPath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + + const fullpath = `/spec/podResources/machine` + const modelPathValue = getValue(model, fullpath) + commit('wizard/model$update', { - path: reqCommitPath, - value: memory, + path: commitPath, + value: val, force: true, }) + + if (modelPathValue === 'custom') { + return + } + let commitCpuMemory, ModelPathValue + if (resource && type) { + const fullPath = `/spec/${type}/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/${type}/podResources/resources/requests/${resource}` + } else { + const fullPath = `/spec/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/podResources/resources/requests/${resource}` + } + let cpuMemoryValue + array.forEach((item) => { + if (item.value === ModelPathValue) { + // Parse subText like "CPU: 2, Memory: 2Gi" + const subText = item.subText || '' + if (resource === 'cpu') { + // Extract CPU value + const cpuMatch = subText.match(/CPU:\s*([^,]+)/) + cpuMemoryValue = cpuMatch ? cpuMatch[1].trim() : '' + } else if (resource === 'memory') { + // Extract Memory value + const memoryMatch = subText.match(/Memory:\s*(.+)/) + cpuMemoryValue = memoryMatch ? memoryMatch[1].trim() : '' + } + } + }) commit('wizard/model$update', { - path: comparePath, - value: memory, + path: commitCpuMemory, + value: cpuMemoryValue, force: true, }) - return memory - } else { + return cpuMemoryValue + } + + function toggleTls() { + let modelPathValue = getValue(model, '/spec/mode') commit('wizard/model$update', { - path: reqCommitPath, - value: cpu, + path: '/spec/admin/tls/default', + value: modelPathValue !== 'Standalone', force: true, }) commit('wizard/model$update', { - path: comparePath, - value: cpu, + path: '/spec/admin/tls/toggle', + value: modelPathValue !== 'Standalone', force: true, }) - return cpu } -} -function setRequests({ getValue, model, commit }, resource, type) { - const modelPath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - const val = getValue(model, modelPath) - commitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - commit('wizard/model$update', { - path: commitPath, - value: val, - force: true, - }) -} - -function toggleTls({ commit, model, getValue }) { - let modelPathValue = getValue(model, '/spec/mode') - commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: modelPathValue !== 'Standalone', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/admin/tls/toggle', - value: modelPathValue !== 'Standalone', - force: true, - }) -} + function showAdditionalSettings() { + // watchDependency('discriminator#/bundleApiLoaded') + return features.length + } -function showAdditionalSettings({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return features.length -} + function getDefault(type) { + const val = getValue(model, `/spec/admin/${type}/default`) || '' + return val + } -function getDefault({ getValue, model }, type) { - const val = getValue(model, `/spec/admin/${type}/default`) || '' - return val -} + async function getReferSecrets() { + const referSecret = getValue(discriminator, '/referSecret') + if (!referSecret) { + return [] + } -function isConfigAvailable({ getValue, model }) { - const val = getValue(model, '/spec/configuration') - return val !== '' -} + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/metadata/release/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` -async function getReferSecrets({ getValue, model, storeGet, axios, discriminator }) { - const referSecret = getValue(discriminator, '/referSecret') - if (!referSecret) { - return [] + const options = [] + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + return options } - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/metadata/release/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - - const options = [] - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) - } catch (e) { - console.log(e) + function showAuthPasswordField() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !modelPathValue && showReferSecret() } - return options -} - -function showAuthPasswordField({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} -function showSecretDropdown({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showSecretDropdown() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !!modelPathValue && showReferSecret() + } -function showReferSecret({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/createAuthSecret') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue -} + function showReferSecret() { + const modelPathValue = getValue(discriminator, '/createAuthSecret') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue + } -function getDefaultValue({ getValue, model }, path) { - const val = getValue(model, `/${path}`) || '' - return val -} + function getDefaultValue(path) { + const val = getValue(model, `/${path}`) || '' + return val + } -function showReferSecretSwitch({ model, getValue, watchDependency, discriminator }) { - const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showReferSecretSwitch() { + const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue && showReferSecret() + } -function onReferSecretChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) -} + function onReferSecretChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + } -return { - showReferSecretSwitch, - onReferSecretChange, - getDefaultValue, - isRancherManaged, - showSecretDropdown, - showReferSecret, - getReferSecrets, - isConfigAvailable, - initBundle, - returnFalse, - setLimits, - setRequests, - toggleTls, - getNamespaces, - updateAlertValue, - getAdminOptions, - isToggleOn, - showAlerts, - getNodeTopology, - clearArbiterHidden, - returnFalse, - showHidden, - isConfigDatabaseOn, - notEqualToDatabaseMode, - filterNodeTopology, - onAuthChange, - setMonitoring, - isMachineNotCustom, - isMachineCustom, - showIssuer, - showArbiter, - clearConfiguration, - showStorageSizeField, - onBackupSwitch, - isVariantAvailable, - fetchJsons, - showAuthPasswordField, - isEqualToModelPathValue, - showAuthSecretField, - getResources, - getMySqlVersions, - onCreateAuthSecretChange, - getSecrets, - getMachineListForOptions, - setMachineToCustom, - updateAgentValue, - getCreateNameSpaceUrl, - ifCapiProviderIsNotEmpty, - ifDedicated, - dedicatedOnChange, - ifZones, - zonesOnChange, - getZones, - getSKU, - showMultiselectZone, - showSelectZone, - setStorageClass, - setReplicaNumber, - setRouterNumber, - setBackup, - showAdditionalSettings, - getDefault, + return { + showReferSecretSwitch, + onReferSecretChange, + getDefaultValue, + isRancherManaged, + showSecretDropdown, + showReferSecret, + getReferSecrets, + initBundle, + returnFalse, + setLimits, + setRequests, + toggleTls, + getNamespaces, + updateAlertValue, + getAdminOptions, + isToggleOn, + showAlerts, + getNodeTopology, + clearArbiterHidden, + showHidden, + isConfigDatabaseOn, + notEqualToDatabaseMode, + filterNodeTopology, + onAuthChange, + setMonitoring, + isMachineNotCustom, + isMachineCustom, + showIssuer, + showArbiter, + clearConfiguration, + showStorageSizeField, + onBackupSwitch, + isVariantAvailable, + fetchJsons, + showAuthPasswordField, + isEqualToModelPathValue, + showAuthSecretField, + getResources, + getMySqlVersions, + onCreateAuthSecretChange, + getSecrets, + getMachineListForOptions, + setMachineToCustom, + updateAgentValue, + getCreateNameSpaceUrl, + ifCapiProviderIsNotEmpty, + ifDedicated, + dedicatedOnChange, + ifZones, + zonesOnChange, + getZones, + getSKU, + showMultiselectZone, + showSelectZone, + setStorageClass, + setReplicaNumber, + setRouterNumber, + setBackup, + showAdditionalSettings, + getDefault, + fetchNamespaces, + } } diff --git a/charts/kubedbcom-kafka-editor-options/ui/create-ui.yaml b/charts/kubedbcom-kafka-editor-options/ui/create-ui.yaml index 150979e7ee..4209e2ef96 100644 --- a/charts/kubedbcom-kafka-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-kafka-editor-options/ui/create-ui.yaml @@ -1,413 +1,428 @@ -steps: -- form: - discriminator: - bundleApiLoaded: - default: false - type: boolean - elements: - - computed: initBundle - if: returnFalse - type: label-element - - disableUnselect: true - fetch: getAdminOptions|databases/Kafka/versions - if: isToggleOn|databases/Kafka/versions - label: - text: labels.database.version - schema: - $ref: schema#/properties/spec/properties/admin/properties/databases/properties/Kafka/properties/versions/properties/default - type: select - - computed: getDefault|databases/Kafka/mode - fetch: getAdminOptions|databases/Kafka/mode - hasDescription: true - if: isToggleOn|databases/Kafka/mode - label: - text: labels.database.mode - schema: - $ref: schema#/properties/spec/properties/mode - type: radio - - elements: - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/replicas - type: input - if: isEqualToModelPathValue|Combined|/spec/mode - type: single-step-form +step: +- type: single-step-form + loader: initBundle + elements: + - type: label-element + label: '' + subtitle: Select the Kafka version you want to deploy on Kubernetes. The chosen version determines the Kafka engine features, compatibility, and runtime behavior of your message broker cluster. + - disableUnselect: true + loader: getAdminOptions|databases/Kafka/versions + if: + type: function + name: isToggleOn|databases/Kafka/versions + label: Database version + schema: schema/properties/spec/properties/admin/properties/databases/properties/Kafka/properties/versions/properties/default + type: select + - init: + type: func + value: getDefault|databases/Kafka/mode + loader: getAdminOptions|databases/Kafka/mode + if: + type: function + name: isToggleOn|databases/Kafka/mode + label: Database mode + isHorizontal: true + schema: schema/properties/spec/properties/mode + type: radio + - elements: + - label: Replicaset number + schema: schema/properties/spec/properties/replicas + type: input + customClass: mb-20 + if: + type: function + name: isEqualToModelPathValue|Combined|/spec/mode + type: block-layout + - elements: - elements: - - elements: - - label: - text: labels.controller_nodes - type: label-element - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/topology/properties/controller/properties/replicas - type: input - - elements: - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/topology/properties/controller/properties/persistence/properties/size + - type: label-element + label: '' + subtitle: Controller nodes manage cluster metadata and coordinate partition leadership. Configure replicas, storage, and resource allocation for reliable cluster coordination. + - type: horizontal-layout + showLabels: true + elements: + - label: Replicaset number + schema: schema/properties/spec/properties/topology/properties/controller/properties/replicas + type: input + - label: Storage size + schema: schema/properties/spec/properties/topology/properties/controller/properties/persistence/properties/size type: input - schema: - $ref: schema#/properties/spec/properties/topology/properties/controller/properties/persistence - type: single-step-form - - elements: - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/topology/properties/controller/properties/podResources/properties/machine + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/topology/properties/controller/properties/podResources/properties/machine type: select - - computed: setLimits|cpu|topology/controller - disabled: isMachineNotCustom|topology/controller - if: isMachineCustom|topology/controller - label: - text: labels.cpu - onChange: setRequests|cpu|topology/controller - schema: - $ref: schema#/properties/spec/properties/topology/properties/controller/properties/podResources/properties/resources/properties/requests/properties/cpu + - init: + type: func + value: setLimits|cpu|topology/controller + disable: isMachineNotCustom|topology/controller + if: + type: function + name: isMachineCustom|topology/controller + label: cpu + loader: setLimits|cpu|topology/controller + watcher: + func: setRequests|cpu|topology/controller + paths: + - schema/properties/spec/properties/topology/properties/controller/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/topology/properties/controller/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/controller/properties/podResources/properties/resources/properties/requests/properties/cpu type: input - - computed: setLimits|memory|topology/controller - disabled: isMachineNotCustom|topology/controller - if: isMachineCustom|topology/controller - label: - text: labels.memory - onChange: setRequests|memory|topology/controller - schema: - $ref: schema#/properties/spec/properties/topology/properties/controller/properties/podResources/properties/resources/properties/requests/properties/memory + - init: + type: func + value: setLimits|memory|topology/controller + disable: isMachineNotCustom|topology/controller + if: + type: function + name: isMachineCustom|topology/controller + label: memory + loader: setLimits|memory|topology/controller + watcher: + func: setRequests|memory|topology/controller + paths: + - schema/properties/spec/properties/topology/properties/controller/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/topology/properties/controller/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/controller/properties/podResources/properties/resources/properties/requests/properties/memory type: input - label: - text: labels.machine_profile - show_label: true - type: single-step-form - schema: - $ref: schema#/properties/spec/properties/topology/properties/controller - type: single-step-form - - elements: - - label: - text: labels.broker_nodes - type: label-element - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/topology/properties/broker/properties/replicas - type: input - - elements: - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/topology/properties/broker/properties/persistence/properties/size + label: Controller nodes + showLabels: true + type: block-layout + - elements: + - type: label-element + label: '' + subtitle: Broker nodes handle message storage and serve client requests. Configure replicas, storage capacity, and resource allocation to handle your message throughput and retention requirements. + - type: horizontal-layout + showLabels: true + elements: + - label: Replicaset number + schema: schema/properties/spec/properties/topology/properties/broker/properties/replicas + type: input + - label: Storage size + schema: schema/properties/spec/properties/topology/properties/broker/properties/persistence/properties/size type: input - schema: - $ref: schema#/properties/spec/properties/topology/properties/broker/properties/persistence - type: single-step-form - - elements: - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/topology/properties/broker/properties/podResources/properties/machine + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/topology/properties/broker/properties/podResources/properties/machine type: select - - computed: setLimits|cpu|topology/broker - disabled: isMachineNotCustom|topology/broker - if: isMachineCustom|topology/broker - label: - text: labels.cpu - onChange: setRequests|cpu|topology/broker - schema: - $ref: schema#/properties/spec/properties/topology/properties/broker/properties/podResources/properties/resources/properties/requests/properties/cpu + - init: + type: func + value: setLimits|cpu|topology/broker + disable: isMachineNotCustom|topology/broker + if: + type: function + name: isMachineCustom|topology/broker + label: cpu + loader: setLimits|cpu|topology/broker + watcher: + func: setRequests|cpu|topology/broker + paths: + - schema/properties/spec/properties/topology/properties/broker/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/topology/properties/broker/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/broker/properties/podResources/properties/resources/properties/requests/properties/cpu type: input - - computed: setLimits|memory|topology/broker - disabled: isMachineNotCustom|topology/broker - if: isMachineCustom|topology/broker - label: - text: labels.memory - onChange: setRequests|memory|topology/broker - schema: - $ref: schema#/properties/spec/properties/topology/properties/broker/properties/podResources/properties/resources/properties/requests/properties/memory + - init: + type: func + value: setLimits|memory|topology/broker + disable: isMachineNotCustom|topology/broker + if: + type: function + name: isMachineCustom|topology/broker + label: memory + loader: setLimits|memory|topology/broker + watcher: + func: setRequests|memory|topology/broker + paths: + - schema/properties/spec/properties/topology/properties/broker/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/topology/properties/broker/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/broker/properties/podResources/properties/resources/properties/requests/properties/memory type: input - label: - text: labels.machine_profile - show_label: true - type: single-step-form - schema: - $ref: schema#/properties/spec/properties/topology/properties/broker - type: single-step-form - if: isEqualToModelPathValue|Topology|/spec/mode - schema: - $ref: schema#/properties/spec/properties/topology - type: single-step-form + label: Broker nodes + showLabels: true + type: block-layout + if: + type: function + name: isEqualToModelPathValue|Topology|/spec/mode + type: block-layout + - elements: + - type: label-element + label: '' + subtitle: Select a machine profile to allocate CPU and memory resources for your database. Choose 'custom' to manually specify resource requirements or select a predefined profile. + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: cpu + loader: setLimits|cpu + watcher: + func: setRequests|cpu + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: memory + loader: setLimits|memory + watcher: + func: setRequests|memory + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + if: + type: function + name: notEqualToDatabaseMode|Topology + label: Machine_profile + showLabels: true + type: block-layout + - elements: + - type: horizontal-layout + showLabels: true + elements: + - loader: getAdminOptions|storageClasses + label: Storage class + schema: schema/properties/spec/properties/admin/properties/storageClasses/properties/default + type: select + - if: + type: function + name: isEqualToModelPathValue|Combined|/spec/mode + label: Storage size + schema: schema/properties/spec/properties/persistence/properties/size + type: input + if: + type: function + name: isEqualToModelPathValue|Combined|/spec/mode + type: block-layout + - description: Configure Credentials, Deployment Mode etc. + elements: - elements: - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.cpu - onChange: setRequests|cpu - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.memory - onChange: setRequests|memory - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - if: notEqualToDatabaseMode|Topology - label: - text: labels.machine_profile - show_label: true - type: single-step-form - - fetch: getAdminOptions|storageClasses - label: - text: labels.storage.class - schema: - $ref: schema#/properties/spec/properties/admin/properties/storageClasses/properties/default + - type: label-element + label: '' + subtitle: Add custom labels and annotations to your database resources for organization, monitoring, and integration with other Kubernetes tools and services. + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/annotations + label: Labels & Annotations + showLabels: true + hideBlock: true + type: block-layout + - init: + type: func + value: getDefault|deletionPolicy + customClass: mt-20 + if: + type: function + name: isToggleOn|deletionPolicy + label: Deletion Policy + watcher: + func: setStorageClass + paths: + - schema/properties/spec/properties/deletionPolicy + options: + - description: options.deletionPolicy.wipeOut.description + text: WipeOut + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: DoNotTerminate + value: DoNotTerminate + schema: schema/properties/spec/properties/deletionPolicy type: select - - if: isEqualToModelPathValue|Combined|/spec/mode - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/persistence/properties/size + - if: + type: function + name: getDefaultValue|spec/admin/authCredential/customize + label: Provide Authentication Credentials? + watcher: + func: onAuthChange + paths: + - temp/createAuthSecret + schema: temp/createAuthSecret + type: switch + - if: + type: function + name: showReferSecretSwitch + label: Refer existing Secret? + watcher: + func: onReferSecretChange + paths: + - temp/referSecret + schema: temp/referSecret + type: switch + - loader: getReferSecrets + if: + type: function + name: showSecretDropdown + label: Secret + schema: schema/properties/spec/properties/authSecret/properties/name + type: select + - if: + type: function + name: showReferSecret + label: password + schema: schema/properties/spec/properties/authSecret/properties/password type: input - - accordion: true - description: - text: Configure Credentials, Deployment Mode etc. - discriminator: - configDatabase: - default: false - type: boolean - createAuthSecret: - default: false - type: boolean - referSecret: - default: false - type: boolean - elements: - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties - type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties - type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - computed: getDefault|deletionPolicy - customClass: mt-20 - if: isToggleOn|deletionPolicy - label: - text: labels.deletionPolicy - onChange: setStorageClass + - if: + type: function + name: getDefaultValue|spec/admin/customConfiguration + label: Configure Database? + watcher: + func: clearConfiguration + paths: + - temp/configDatabase + schema: temp/configDatabase + type: switch + - if: + type: function + name: isConfigDatabaseOn + label: Configuration + # hasCopy: true + schema: schema/properties/spec/properties/configuration + type: textarea + - if: + type: function + name: isToggleOn|deployment + label: Deployment name + options: + - description: labels.deployment.shared + text: Shared + value: Shared + - description: labels.deployment.dedicated + text: Dedicated + value: Dedicated + schema: schema/properties/spec/properties/admin/properties/deployment/properties/default + type: radio + - if: + type: function + name: isToggleOn|clusterTier + isHorizontal: true + label: Cluster Tier + options: + - text: General Purpose + value: GeneralPurpose + - text: Memory Optimized + value: MemoryOptimized + - text: CPU Optimized + value: CPUOptimized + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/default + type: radio + - disableUnselect: true + loader: getAdminOptions|clusterTier/placement + if: + type: function + name: isToggleOn|clusterTier/placement + label: Placement + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + type: select + - disableUnselect: true + loader: getNodeTopology + if: + type: function + name: isToggleOn|clusterTier/nodeTopology + label: Node Topology + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + type: select + label: Advanced Configuration + showLabels: true + type: block-layout + - description: Enable Backup, Monitoring, TLS etc. + elements: + - elements: + - init: + type: func + value: setMonitoring + label: Enable Monitoring? + watcher: + func: updateAlertValue + paths: + - temp/monitoring + schema: temp/monitoring + type: switch + - customClass: mt-10 + if: + type: function + name: showAlerts + label: Alert Options options: - - 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/spec/properties/deletionPolicy + - text: None + value: none + - text: Critical + value: critical + - text: Warning + value: warning + - text: Info + value: info + schema: schema/properties/form/properties/alert/properties/enabled type: select - - if: getDefaultValue|spec/admin/authCredential/customize - label: - text: Provide Authentication Credentials? - onChange: onAuthChange - schema: - $ref: discriminator#/createAuthSecret - type: switch - - if: showReferSecretSwitch - label: - text: Refer existing Secret? - onChange: onReferSecretChange - schema: - $ref: discriminator#/referSecret + if: + type: function + name: isToggleOn|monitoring + type: block-layout + - elements: + - if: + type: function + name: isToggleOn|tls + label: Enable TLS? + schema: schema/properties/spec/properties/admin/properties/tls/properties/default type: switch - - fetch: getReferSecrets - if: showSecretDropdown - label: - text: Secret - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/name + - loader: getAdminOptions|clusterIssuers + if: + type: function + name: showIssuer + label: Cluster Issuers + validation: + type: required + schema: schema/properties/spec/properties/admin/properties/clusterIssuers/properties/default type: select - - if: showReferSecret - label: - text: labels.password - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/password - type: input - - computed: isConfigAvailable - if: getDefaultValue|spec/admin/customConfiguration - label: - text: Configure Database? - onChange: clearConfiguration - schema: - $ref: discriminator#/configDatabase + type: block-layout + - elements: + - label: Expose via Gateway? + schema: schema/properties/spec/properties/admin/properties/expose/properties/default type: switch - - if: isConfigDatabaseOn - label: - text: Configuration - schema: - $ref: schema#/properties/spec/properties/configuration - type: editor - - hasDescription: true - if: isToggleOn|deployment - label: - text: labels.deployment.name - options: - - description: labels.deployment.shared - text: Shared - value: Shared - - description: labels.deployment.dedicated - text: Dedicated - value: Dedicated - schema: - $ref: schema#/properties/spec/properties/admin/properties/deployment/properties/default - type: radio - - if: isToggleOn|clusterTier - isHorizontal: true - label: - text: labels.clusterTier - options: - - text: General Purpose - value: GeneralPurpose - - text: Memory Optimized - value: MemoryOptimized - - text: CPU Optimized - value: CPUOptimized - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/default - type: radio - - disableUnselect: true - fetch: getAdminOptions|clusterTier/placement - if: isToggleOn|clusterTier/placement - label: - text: labels.placement - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default - type: select - - disableUnselect: true - fetch: getNodeTopology - if: isToggleOn|clusterTier/nodeTopology - label: - text: labels.nodeTopology - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default - type: select - hideForm: true - label: - text: Advanced Configuration - show_label: true - type: single-step-form - - accordion: true - description: - text: Enable Backup, Monitoring, TLS etc. - discriminator: - backup: - default: false - type: boolean - elements: - - discriminator: - monitoring: - default: false - type: boolean - elements: - - computed: setMonitoring - label: - text: labels.enable_monitoring - onChange: updateAlertValue - schema: - $ref: discriminator#/monitoring - type: switch - - customClass: mt-10 - if: showAlerts - label: - text: labels.alert.options - options: - - text: None - value: none - - text: Critical - value: critical - - text: Warning - value: warning - - text: Info - value: info - schema: - $ref: schema#/properties/form/properties/alert/properties/enabled - sortable: true - type: select - if: isToggleOn|monitoring - type: single-step-form - - elements: - - if: isToggleOn|tls - label: - text: Enable TLS? - schema: - $ref: schema#/properties/spec/properties/admin/properties/tls/properties/default - type: switch - - fetch: getAdminOptions|clusterIssuers - if: showIssuer - label: - text: labels.clusterIssuers - required: true - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterIssuers/properties/default - type: select - type: single-step-form - - elements: - - label: - text: Expose via Gateway? - schema: - $ref: schema#/properties/spec/properties/admin/properties/expose/properties/default - type: switch - if: isToggleOn|expose - type: single-step-form - if: showAdditionalSettings - label: - text: Additional Options - show_label: true - type: single-step-form - type: single-step-form + if: + type: function + name: isToggleOn|expose + type: block-layout + if: + type: function + name: showAdditionalSettings + label: Additional Options + showLabels: true + type: block-layout id: options - title: steps.0.label + # title: steps.0.label type: multi-step-form diff --git a/charts/kubedbcom-kafka-editor-options/ui/functions.js b/charts/kubedbcom-kafka-editor-options/ui/functions.js index 33e520182b..d0d556d625 100644 --- a/charts/kubedbcom-kafka-editor-options/ui/functions.js +++ b/charts/kubedbcom-kafka-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -315,727 +317,777 @@ const modeDetails = { }, } -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) -function showStorageSizeField({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - const validType = ['Standalone', 'Replicaset'] - return validType.includes(modelPathValue) -} + setDiscriminatorValue('bundleApiLoaded', false) + setDiscriminatorValue('configDatabase', false) + setDiscriminatorValue('createAuthSecret', false) + setDiscriminatorValue('referSecret', false) + setDiscriminatorValue('backup', false) + setDiscriminatorValue('monitoring', false) + + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } + + function showStorageSizeField() { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + const validType = ['Standalone', 'Replicaset'] + return validType.includes(modelPathValue) + } -function getMachineListForOptions({ model, getValue }) { - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') let array = [] + function getMachineListForOptions() { + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') - if (available.length) { - array = available.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - else { - let subText = '', - text = '' - const machineData = machinesFromPreset.find((val) => val.id === machine) - if (machineData) { - subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` - text = machineData.name ? machineData.name : machineData.id - } - return { text, subText, value: machine } - } - }) - } else { - array = machineList - .map((machine) => { + if (available.length) { + array = available.map((machine) => { if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + else { + let subText = '', + text = '' + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + text = machineData.name ? machineData.name : machineData.id + } + return { text, subText, value: machine } + } }) - .filter((val) => !!val) + } else { + array = machineList + .map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { text, subText, value: machine } + }) + .filter((val) => !!val) + } + return array } - return array -} -function setLimits({ model, getValue, commit, watchDependency }, resource, type) { - const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' - watchDependency(`model#${path}`) - const selectedMachine = getValue(model, path) || 'custom' - const reqCommitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - const comparePath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - - const resourceValue = getValue(model, comparePath) - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - - let cpu = '', - memory = '' - if (available.length && selectedMachine !== 'custom') { - const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) - if (machineData) { - cpu = machineData.limits.cpu - memory = machineData.limits.memory + function setLimits(resource, type) { + const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' + // watchDependency(`model#${path}`) + const selectedMachine = getValue(model, path) || 'custom' + const reqCommitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + const comparePath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + + const resourceValue = getValue(model, comparePath) + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + let cpu = '', + memory = '' + if (available.length && selectedMachine !== 'custom') { + const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) + if (machineData) { + cpu = machineData.limits.cpu + memory = machineData.limits.memory + } + } else { + if (selectedMachine === 'custom') { + cpu = resourceValue + memory = resourceValue + } else { + cpu = machines[selectedMachine].resources.limits.cpu + memory = machines[selectedMachine].resources.limits.memory + } } - } else { - if (selectedMachine === 'custom') { - cpu = resourceValue - memory = resourceValue + + if (resource === 'memory') { + commit('wizard/model$update', { + path: reqCommitPath, + value: memory, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: memory, + force: true, + }) + return memory } else { - cpu = machines[selectedMachine].resources.limits.cpu - memory = machines[selectedMachine].resources.limits.memory + commit('wizard/model$update', { + path: reqCommitPath, + value: cpu, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: cpu, + force: true, + }) + return cpu } } - if (resource === 'memory') { - commit('wizard/model$update', { - path: reqCommitPath, - value: memory, - force: true, - }) + function setRequests(resource, type) { + const modelPath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + + const fullpath = `/spec/podResources/machine` + const modelPathValue = getValue(model, fullpath) + commit('wizard/model$update', { - path: comparePath, - value: memory, + path: commitPath, + value: val, force: true, }) - return memory - } else { - commit('wizard/model$update', { - path: reqCommitPath, - value: cpu, - force: true, + + if (modelPathValue === 'custom') { + return + } + let commitCpuMemory, ModelPathValue + if (resource && type) { + const fullPath = `/spec/${type}/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/${type}/podResources/resources/requests/${resource}` + } else { + const fullPath = `/spec/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/podResources/resources/requests/${resource}` + } + let cpuMemoryValue + array.forEach((item) => { + if (item.value === ModelPathValue) { + // Parse subText like "CPU: 2, Memory: 2Gi" + const subText = item.subText || '' + if (resource === 'cpu') { + // Extract CPU value + const cpuMatch = subText.match(/CPU:\s*([^,]+)/) + cpuMemoryValue = cpuMatch ? cpuMatch[1].trim() : '' + } else if (resource === 'memory') { + // Extract Memory value + const memoryMatch = subText.match(/Memory:\s*(.+)/) + cpuMemoryValue = memoryMatch ? memoryMatch[1].trim() : '' + } + } }) commit('wizard/model$update', { - path: comparePath, - value: cpu, + path: commitCpuMemory, + value: cpuMemoryValue, force: true, }) - return cpu + return cpuMemoryValue } -} - -function setRequests({ getValue, model, commit }, resource, type) { - const modelPath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - const val = getValue(model, modelPath) - commitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - commit('wizard/model$update', { - path: commitPath, - value: val, - force: true, - }) -} -function setMachineToCustom({ getValue, model }) { - const machine = getValue(model, '/spec/admin/machineProfiles/default') - return machine || 'custom' -} - -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + function setMachineToCustom() { + const machine = getValue(model, '/spec/admin/machineProfiles/default') + return machine || 'custom' } -} -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} + function getCreateNameSpaceUrl() { + const user = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function setStorageClass({ model, getValue, commit, discriminator, watchDependency }) { - const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' - let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' - const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] - const suffix = '-retain' - - const simpleClassList = storageClassList.filter((item) => { - return !item.endsWith(suffix) - }) - const retainClassList = storageClassList.filter((item) => { - return item.endsWith(suffix) - }) - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] - } else { - storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + const domain = storeGet('/domain') || '' + if (domain.includes('bb.test')) { + return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } } - const isChangeable = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'storageClasses', - ) - if (isChangeable && storageClass) { - commit('wizard/model$update', { - path: '/spec/admin/storageClasses/default', - value: storageClass, - force: true, - }) + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false } -} -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], - }, - }, - ) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace + function setStorageClass() { + const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' + let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' + const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] + const suffix = '-retain' + + const simpleClassList = storageClassList.filter((item) => { + return !item.endsWith(suffix) + }) + const retainClassList = storageClassList.filter((item) => { + return item.endsWith(suffix) + }) + if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { + storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] } else { - return resp.data?.status?.namespaces || [] + storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] } - } catch (e) { - console.log(e) - } - return [] -} - -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} -let placement = [] -let versions = [] -let storageClass = [] -let clusterIssuers = [] -let nodetopologiesShared = [] -let nodetopologiesDedicated = [] -let features = [] -async function initBundle({ commit, model, getValue, axios, storeGet, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - - let db = getValue(model, '/metadata/resource/kind') - db = db.toLowerCase() - let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` - const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - - try { - const resp = await axios.get(url) - features = resp.data.features || [] - placement = resp.data.placementpolicies || [] - versions = resp.data.versions || [] - storageClass = resp.data.storageclasses || [] - clusterIssuers = resp.data.clusterissuers || [] - nodetopologiesDedicated = resp.data.dedicated || [] - nodetopologiesShared = resp.data.shared || [] - - const response = await axios.get(annotationUrl) - const annotations = response.data?.metadata?.annotations || {} - const uidRange = annotations['openshift.io/sa.scc.uid-range'] - if (uidRange) { - const val = uidRange.split('/')[0] + const isChangeable = isToggleOn('storageClasses') + if (isChangeable && storageClass) { commit('wizard/model$update', { - path: '/spec/openshift/securityContext/runAsUser', - value: val, + path: '/spec/admin/storageClasses/default', + value: storageClass, force: true, }) } - } catch (e) { - console.log(e) } - commit('wizard/model$update', { - path: '/spec/deletionPolicy', - value: getDefault({ getValue, model }, 'deletionPolicy'), - force: true, - }) - - if (!getValue(model, `/spec/admin/databases/Kafka/mode/toggle`)) { - let defMode = getDefault({ getValue, model }, 'databases/Kafka/mode') || '' - if (defMode === '') { - const arr = getValue(model, '/spec/databases/Kafka/mode/available') || [] - if (arr.length) defMode = arr[0] + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, + }, + ) + if (resp.data?.status?.projects) { + const projects = resp.data?.status?.projects + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } + } catch (e) { + console.log(e) } - commit('wizard/model$update', { - path: '/spec/mode', - value: defMode, - force: true, - }) + return [] } - if (!features.includes('tls')) { - commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: false, - force: true, - }) + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found } - if (!features.includes('binding')) { - commit('wizard/model$update', { - path: '/spec/admin/expose/default', - value: false, - force: true, - }) - } - if (!features.includes('monitoring')) { - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: 'none', - force: true, - }) - } - if (!features.includes('backup')) { - commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, - force: true, - }) - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: '', - force: true, - }) - } - - setDiscriminatorValue('/bundleApiLoaded', true) -} -function fetchOptions({ model, getValue, commit }, type) { - let kind = getValue(model, '/metadata/resource/kind') - - let returnArray = [] - if (type === 'clusterTier/placement') { - returnArray = placement - } else if (type === `databases/${kind}/versions`) { - returnArray = versions - } else if (type === 'storageClasses') { - returnArray = storageClass - } else if (type === 'clusterIssuers') { - returnArray = clusterIssuers - } + let placement = [] + let versions = [] + let storageClass = [] + let clusterIssuers = [] + let nodetopologiesShared = [] + let nodetopologiesDedicated = [] + let features = [] + async function initBundle() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + + let db = getValue(model, '/metadata/resource/kind') + db = db.toLowerCase() + let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` + const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` + + try { + const resp = await axios.get(url) + features = resp.data.features || [] + placement = resp.data.placementpolicies || [] + versions = resp.data.versions || [] + storageClass = resp.data.storageclasses || [] + clusterIssuers = resp.data.clusterissuers || [] + nodetopologiesDedicated = resp.data.dedicated || [] + nodetopologiesShared = resp.data.shared || [] + + const response = await axios.get(annotationUrl) + const annotations = response.data?.metadata?.annotations || {} + const uidRange = annotations['openshift.io/sa.scc.uid-range'] + if (uidRange) { + const val = uidRange.split('/')[0] + commit('wizard/model$update', { + path: '/spec/openshift/securityContext/runAsUser', + value: val, + force: true, + }) + } + } catch (e) { + console.log(e) + } - if (returnArray.length === 1) { - const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: path, - value: returnArray[0], + path: '/spec/deletionPolicy', + value: getDefault('deletionPolicy'), force: true, }) - } - return returnArray -} - -function getAdminOptions({ getValue, model, watchDependency, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') + if (!getValue(model, `/spec/admin/databases/Kafka/mode/toggle`)) { + let defMode = getDefault('databases/Kafka/mode') || '' + if (defMode === '') { + const arr = getValue(model, '/spec/databases/Kafka/mode/available') || [] + if (arr.length) defMode = arr[0] + } + commit('wizard/model$update', { + path: '/spec/mode', + value: defMode, + force: true, + }) + } - const options = getValue(model, `/spec/admin/${type}/available`) || [] + if (!features.includes('tls')) { + commit('wizard/model$update', { + path: '/spec/admin/tls/default', + value: false, + force: true, + }) + } + if (!features.includes('binding')) { + commit('wizard/model$update', { + path: '/spec/admin/expose/default', + value: false, + force: true, + }) + } + if (!features.includes('monitoring')) { + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: 'none', + force: true, + }) + } + if (!features.includes('backup')) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: '', + force: true, + }) + } - if (options.length === 0) { - return fetchOptions({ model, getValue, commit }, type) - } - if (type.endsWith('/mode')) { - return ( - options?.map((item) => ({ - description: modeDetails[item]?.description || '', - text: modeDetails[item]?.text || '', - value: item, - })) || [] - ) + setDiscriminatorValue('/bundleApiLoaded', true) } - return options -} -function checkIfFeatureOn({ getValue, model }, type) { - let val = getValue(model, `/spec/admin/${type}/toggle`) - if (type === 'backup' || type === 'archiver') { - val = getValue(model, `/spec/admin/${type}/enable/toggle`) - } - const backupVal = getValue(model, '/spec/backup/tool') - - if (type === 'backup') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } else if (type === 'tls') { - return features.includes('tls') && val - } else if (type === 'expose') { - return features.includes('binding') && val - } else if (type === 'monitoring') { - return features.includes('monitoring') && val - } else if (type === 'archiver') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } -} + function fetchOptions(type) { + let kind = getValue(model, '/metadata/resource/kind') + + let returnArray = [] + if (type === 'clusterTier/placement') { + returnArray = placement + } else if (type === `databases/${kind}/versions`) { + returnArray = versions + } else if (type === 'storageClasses') { + returnArray = storageClass + } else if (type === 'clusterIssuers') { + returnArray = clusterIssuers + } -function isToggleOn({ getValue, model, discriminator, watchDependency }, type) { - watchDependency('discriminator#/bundleApiLoaded') - watchDependency('model#/spec/admin/deployment/default') - const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') - let deploymentType = getValue(model, `/spec/admin/deployment/default`) - if ( - type === 'tls' || - type === 'backup' || - type === 'expose' || - type === 'monitoring' || - type === 'archiver' - ) { - return checkIfFeatureOn({ getValue, model }, type) - } else if ( - type === 'clusterTier' || - type === 'clusterTier/placement' || - type === 'clusterTier/nodeTopology' - ) { - if (deploymentType === 'Dedicated' && bundleApiLoaded) return true - else return false - } else if (type === 'deployment') { - const deploymentType = getValue(model, '/spec/admin/deployment/default') - if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + if (returnArray.length === 1) { + const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: '/spec/admin/deployment/default', - value: 'Shared', + path: path, + value: returnArray[0], force: true, }) } - return ( - getValue(model, `/spec/admin/${type}/toggle`) && - nodetopologiesDedicated.length && - bundleApiLoaded - ) - } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded -} -async function getNodeTopology({ model, getValue, axios, storeGet, watchDependency }) { - watchDependency('model#/spec/admin/deployment/default') - watchDependency('model#/spec/admin/clusterTier/default') - const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' - const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' - let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + return returnArray + } - const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + function getAdminOptions(type) { + // watchDependency('discriminator#/bundleApiLoaded') - if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared - else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + const options = getValue(model, `/spec/admin/${type}/available`) || [] - const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) - return filteredList -} + if (options.length === 0) { + return fetchOptions(type) + } + if (type.endsWith('/mode')) { + return ( + options?.map((item) => ({ + description: modeDetails[item]?.description || '', + text: modeDetails[item]?.text || '', + value: item, + })) || [] + ) + } + return options + } -function filterNodeTopology(list, tier, provider) { - // first filter the list from value that exists from the filtered list got from API - const filteredlist = list + let backupToolInitialValue = '' + function checkIfFeatureOn(type) { + let val = getValue(model, `/spec/admin/${type}/toggle`) + if (type === 'backup' || type === 'archiver') { + val = getValue(model, `/spec/admin/${type}/enable/toggle`) + } + const backupVal = getValue(model, '/spec/backup/tool') + if (type === 'backup') { + if (backupToolInitialValue === '') { + backupToolInitialValue = + features.includes('backup') && backupVal === 'KubeStash' && val ? 'on' : 'off' + return features.includes('backup') && backupVal === 'KubeStash' && val + } else { + if (backupToolInitialValue === 'on') { + return true + } else { + return false + } + } + } else if (type === 'tls') { + return features.includes('tls') && val + } else if (type === 'expose') { + return features.includes('binding') && val + } else if (type === 'monitoring') { + return features.includes('monitoring') && val + } else if (type === 'archiver') { + return features.includes('backup') && val + } + } - // filter the list based on clusterTier - if (provider === 'EKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('c') - else if (tier === 'MemoryOptimized') return item.startsWith('r') - else return !item.startsWith('c') && !item.startsWith('r') - }) - } else if (provider === 'AKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - else - return ( - !(item.startsWith('f') || item.startsWith('fx')) && - !( + function isToggleOn(type) { + // watchDependency('discriminator#/bundleApiLoaded') + // watchDependency('model#/spec/admin/deployment/default') + const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') + let deploymentType = getValue(model, `/spec/admin/deployment/default`) + if ( + type === 'tls' || + type === 'backup' || + type === 'expose' || + type === 'monitoring' || + type === 'archiver' + ) { + return checkIfFeatureOn(type) + } else if ( + type === 'clusterTier' || + type === 'clusterTier/placement' || + type === 'clusterTier/nodeTopology' + ) { + if (deploymentType === 'Dedicated' && bundleApiLoaded) return true + else return false + } else if (type === 'deployment') { + const deploymentType = getValue(model, '/spec/admin/deployment/default') + if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + commit('wizard/model$update', { + path: '/spec/admin/deployment/default', + value: 'Shared', + force: true, + }) + } + return ( + getValue(model, `/spec/admin/${type}/toggle`) && + nodetopologiesDedicated.length && + bundleApiLoaded + ) + } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded + } + + async function getNodeTopology() { + // watchDependency('model#/spec/admin/deployment/default') + // watchDependency('model#/spec/admin/clusterTier/default') + const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' + const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' + let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + + const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + + if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared + else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + + const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) + return filteredList + } + + function filterNodeTopology(list, tier, provider) { + // first filter the list from value that exists from the filtered list got from API + const filteredlist = list + + // filter the list based on clusterTier + if (provider === 'EKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('c') + else if (tier === 'MemoryOptimized') return item.startsWith('r') + else return !item.startsWith('c') && !item.startsWith('r') + }) + } else if (provider === 'AKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('e') || item.startsWith('eb') || item.startsWith('ec') || item.startsWith('m') || item.startsWith('d') ) - ) - }) - } else if (provider === 'GKE') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') - return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - else - return ( - !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && - !( + else + return ( + !(item.startsWith('f') || item.startsWith('fx')) && + !( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + ) + }) + } else if (provider === 'GKE') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') + return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('x4') || item.startsWith('m1') || item.startsWith('m2') || item.startsWith('m3') ) - ) - }) - } else return filteredlist -} + else + return ( + !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && + !( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + ) + }) + } else return filteredlist + } -function returnFalse() { - return false -} + function returnFalse() { + return false + } -function isMachineCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue === 'custom' -} + function isMachineCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue === 'custom' + } -function isMachineNotCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue !== 'custom' && !!modelPathValue -} + function isMachineNotCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue !== 'custom' && !!modelPathValue + } -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} + function notEqualToDatabaseMode(mode) { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + return modelPathValue && modelPathValue !== mode + } -function onAuthChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/authSecret/password', - value: '', - force: true, - }) -} + function onAuthChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/spec/authSecret/password', + value: '', + force: true, + }) + } -function clearConfiguration({ discriminator, getValue, commit }) { - const configOn = getValue(discriminator, '/configDatabase') + function clearConfiguration() { + const configOn = getValue(discriminator, '/configDatabase') - if (!configOn) { - commit('wizard/model$delete', '/spec/configuration') + if (!configOn) { + commit('wizard/model$delete', '/spec/configuration') + } } -} -function isConfigDatabaseOn({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configDatabase') - return getValue(discriminator, '/configDatabase') -} + function isConfigDatabaseOn() { + // watchDependency('discriminator#/configDatabase') + return getValue(discriminator, '/configDatabase') + } -function showIssuer({ model, getValue, watchDependency, discriminator }) { - watchDependency('model#/spec/admin/tls/default') - const isTlsEnabled = getValue(model, '/spec/admin/tls/default') - const isIssuerToggleEnabled = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'clusterIssuers', - ) - return isTlsEnabled && isIssuerToggleEnabled -} + function showIssuer() { + // watchDependency('model#/spec/admin/tls/default') + const isTlsEnabled = getValue(model, '/spec/admin/tls/default') + const isIssuerToggleEnabled = isToggleOn('clusterIssuers') + return isTlsEnabled && isIssuerToggleEnabled + } -function setMonitoring({ getValue, model }) { - const agent = getValue(model, '/spec/admin/monitoring/agent') || '' - return !!agent -} + function setMonitoring() { + const agent = getValue(model, '/spec/admin/monitoring/agent') || '' + return !!agent + } -function updateAlertValue({ commit, model, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const alert = isMonitorEnabled ? 'warning' : 'none' - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: alert, - force: true, - }) - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} + function updateAlertValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const alert = isMonitorEnabled ? 'warning' : 'none' + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: alert, + force: true, + }) + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: agent, + force: true, + }) + } -function showAlerts({ watchDependency, model, getValue, discriminator }) { - watchDependency('discriminator#/monitoring') - const isMonitorEnabled = getValue(discriminator, '/monitoring') - return ( - isMonitorEnabled && isToggleOn({ getValue, model, discriminator, watchDependency }, 'alert') - ) -} + function showAlerts() { + // watchDependency('discriminator#/monitoring') + const isMonitorEnabled = getValue(discriminator, '/monitoring') + return isMonitorEnabled && isToggleOn('alert') + } -function setBackup({ model, getValue }) { - const backup = getValue(model, '/spec/backup/tool') - const val = getValue(model, '/spec/admin/backup/enable/default') - return backup === 'KubeStash' && features.includes('backup') && val -} + function setBackup() { + const backup = getValue(model, '/spec/backup/tool') + const val = getValue(model, '/spec/admin/backup/enable/default') + return backup === 'KubeStash' && features.includes('backup') && val + } -function onBackupSwitch({ discriminator, getValue, commit }) { - const isBackupOn = getValue(discriminator, '/backup') - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: isBackupOn ? 'KubeStash' : '', - force: true, - }) -} + function onBackupSwitch() { + const isBackupOn = getValue(discriminator, '/backup') + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: isBackupOn ? 'KubeStash' : '', + force: true, + }) + } -function showAdditionalSettings({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return features.length -} + function showAdditionalSettings() { + // watchDependency('discriminator#/bundleApiLoaded') + return features.length + } -function getDefault({ getValue, model }, type) { - const val = getValue(model, `/spec/admin/${type}/default`) || '' - return val -} + function getDefault(type) { + const val = getValue(model, `/spec/admin/${type}/default`) || '' + return val + } -function isConfigAvailable({ getValue, model }) { - const val = getValue(model, '/spec/configuration') - return val !== '' -} + async function getReferSecrets() { + const referSecret = getValue(discriminator, '/referSecret') + if (!referSecret) { + return [] + } -async function getReferSecrets({ getValue, model, storeGet, axios, discriminator }) { - const referSecret = getValue(discriminator, '/referSecret') - if (!referSecret) { - return [] + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/metadata/release/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` + + const options = [] + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + return options } - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/metadata/release/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - - const options = [] - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) - } catch (e) { - console.log(e) + function showAuthPasswordField() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !modelPathValue && showReferSecret() } - return options -} - -function showAuthPasswordField({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} -function showSecretDropdown({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showSecretDropdown() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !!modelPathValue && showReferSecret() + } -function showReferSecret({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/createAuthSecret') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue -} + function showReferSecret() { + const modelPathValue = getValue(discriminator, '/createAuthSecret') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue + } -function getDefaultValue({ getValue, model }, path) { - const val = getValue(model, `/${path}`) || '' - return val -} + function getDefaultValue(path) { + const val = getValue(model, `/${path}`) || '' + return val + } -function showReferSecretSwitch({ model, getValue, watchDependency, discriminator }) { - const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showReferSecretSwitch() { + const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue && showReferSecret() + } -function onReferSecretChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) -} + function onReferSecretChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + } -return { - showReferSecretSwitch, - onReferSecretChange, - getDefaultValue, - isRancherManaged, - showSecretDropdown, - showReferSecret, - getReferSecrets, - isConfigAvailable, - showAdditionalSettings, - initBundle, - returnFalse, - isVariantAvailable, - showAuthPasswordField, - isEqualToModelPathValue, - showStorageSizeField, - getMachineListForOptions, - setLimits, - setRequests, - setMachineToCustom, - getCreateNameSpaceUrl, - setStorageClass, - getNamespaces, - isToggleOn, - getAdminOptions, - getNodeTopology, - filterNodeTopology, - isMachineNotCustom, - isMachineCustom, - notEqualToDatabaseMode, - onAuthChange, - clearConfiguration, - isConfigDatabaseOn, - showIssuer, - setMonitoring, - updateAlertValue, - showAlerts, - onBackupSwitch, - setBackup, - getDefault, + return { + showReferSecretSwitch, + onReferSecretChange, + getDefaultValue, + isRancherManaged, + showSecretDropdown, + showReferSecret, + getReferSecrets, + showAdditionalSettings, + initBundle, + returnFalse, + isVariantAvailable, + showAuthPasswordField, + isEqualToModelPathValue, + showStorageSizeField, + getMachineListForOptions, + setLimits, + setRequests, + setMachineToCustom, + getCreateNameSpaceUrl, + setStorageClass, + getNamespaces, + isToggleOn, + getAdminOptions, + getNodeTopology, + filterNodeTopology, + isMachineNotCustom, + isMachineCustom, + notEqualToDatabaseMode, + onAuthChange, + clearConfiguration, + isConfigDatabaseOn, + showIssuer, + setMonitoring, + updateAlertValue, + showAlerts, + onBackupSwitch, + setBackup, + getDefault, + } } diff --git a/charts/kubedbcom-kafka-editor/ui/edit-ui.yaml b/charts/kubedbcom-kafka-editor/ui/edit-ui.yaml index 320333487c..d9f6481358 100644 --- a/charts/kubedbcom-kafka-editor/ui/edit-ui.yaml +++ b/charts/kubedbcom-kafka-editor/ui/edit-ui.yaml @@ -1,1311 +1,1006 @@ -steps: -- form: - elements: - - disabled: true - label: - text: labels.database.name - onChange: onNameChange - schema: - $ref: schema#/properties/metadata/properties/release/properties/name - type: input - - disabled: true - fetch: getResources|core|v1|namespaces - label: - text: labels.namespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/metadata/properties/release/properties/namespace - type: select - - disableUnselect: true - disabled: true - fetch: getKafkaVersions|catalog.kubedb.com|v1alpha1|kafkaversions - label: - text: labels.database.version - onChange: onVersionChange - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/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/kubedbComKafka/properties/metadata/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/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/kubedbComKafka/properties/metadata/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/metadata/properties/annotations/additionalProperties - type: input - - hasDescription: true - label: - text: labels.deletionPolicy - options: - - 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/kubedbComKafka/properties/spec/properties/deletionPolicy - type: radio - - disabled: true - label: - text: labels.disable_security_question - onChange: onDisableSecurityChange - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/disableSecurity - type: switch - - elements: - - label: - text: labels.database.admin_secret - type: label-element - - disabled: true - label: - text: labels.secret - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/authSecret/properties/name - type: input - if: isSecurityEnabled - type: single-step-form - type: single-step-form - id: basic - title: steps.0.label -- form: - discriminator: - activeDatabaseMode: - type: string +type: multi-step-form +step: + - type: single-step-form + id: compute-autoscaler + loader: getDbDetails elements: - - label: - text: labels.to_update_disabled_section - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - params: - cluster: - $ref: store#/route/params/cluster - dbname: - $ref: model#/metadata/release/name - domain: - $ref: store#/domain - group: - $ref: model#/metadata/resource/group - kind: - $ref: model#/metadata/resource/kind - namespace: - $ref: model#/metadata/release/namespace - owner: - $ref: store#/route/params/user - resource: - $ref: model#/metadata/resource/name - version: - $ref: model#/metadata/resource/version - path: ${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/kafkaopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations - - computed: setDatabaseMode - disabled: true - hasDescription: true - label: - text: labels.database.mode - onChange: deleteDatabaseModePath - options: - - description: options.database.mode.Combined.description - text: options.database.mode.Combined.label - value: Combined - - description: options.database.mode.Dedicated.description - text: options.database.mode.Dedicated.label - value: Dedicated - schema: - $ref: discriminator#/activeDatabaseMode - type: radio - - elements: - - disabled: true - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/replicas - type: input - - disabled: true - label: - text: labels.storage.size - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/storage/properties/resources/properties/requests/properties/storage - type: input - - disabled: true - label: - text: labels.storage.class - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/storage/properties/storageClassName - type: input - if: isEqualToDatabaseMode|Combined - type: single-step-form - - element: + - type: block-layout + if: + type: function + name: isConsole elements: - - disabled: true - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/topology/properties/$dyn/properties/replicas - type: input - - disabled: true - elements: - - elements: - - elements: - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/topology/properties/$dyn/properties/storage/properties/resources/properties/requests/properties/storage - type: input - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/topology/properties/$dyn/properties/storage/properties/resources/properties/requests - type: single-step-form - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/topology/properties/$dyn/properties/storage/properties/resources - type: single-step-form - - label: - text: labels.storage.class - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/topology/properties/$dyn/properties/storage/properties/storageClassName - type: input - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/topology/properties/$dyn/properties/storage - type: single-step-form - - disabled: true - label: - text: labels.suffix - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/topology/properties/$dyn/properties/suffix - type: input - - disabled: true - label: - text: labels.resources - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/topology/properties/$dyn/properties/resources - type: resource-input-form - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/topology/properties/$dyn - show_label: true - type: single-step-form - if: isEqualToDatabaseMode|Dedicated - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/topology - type: array-input-form - type: single-step-form - id: topology - title: steps.1.label -- form: - elements: - - if: showTlsRecommendation - label: - text: labels.tls_recommended_text - type: label-element - - label: - text: labels.to_update_tls - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - params: - cluster: - $ref: store#/route/params/cluster - dbname: - $ref: model#/metadata/release/name - domain: - $ref: store#/domain - group: - $ref: model#/metadata/resource/group - kind: - $ref: model#/metadata/resource/kind - namespace: - $ref: model#/metadata/release/namespace - owner: - $ref: store#/route/params/user - resource: - $ref: model#/metadata/resource/name - version: - $ref: model#/metadata/resource/version - path: ${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/kafkaopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=ReconfigureTLS - - disabled: true - label: - text: labels.enable_tls - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/enableSSL - type: switch - - disabled: true - elements: - - elements: - - computed: setApiGroupEdit - disabled: true - label: - text: labels.api_group - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup - type: input - - label: - text: labels.kind - options: - - text: Issuer - value: Issuer - - text: ClusterIssuer - value: ClusterIssuer - required: returnFalse - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/tls/properties/issuerRef/properties/kind - type: select - - allowUserDefinedOption: true - fetch: getIssuerRefsName - label: - text: labels.name - required: returnFalse - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/tls/properties/issuerRef/properties/name - type: select - label: - text: labels.issuer_ref - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/tls/properties/issuerRef - type: single-step-form - - alias: reusable_certificates - chart: - name: uibytebuildersdev-component-certificates - version: v0.29.0 - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/tls/properties/certificates - type: reusable-element - if: showTlsConfigureSection - type: single-step-form - type: single-step-form - id: tls - if: isSecurityEnabled - title: steps.2.label -- form: - discriminator: - enableMonitoring: - default: true - type: boolean - elements: - - label: - text: labels.to_update_exporter_resources - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - function: getOpsRequestUrl|VerticalScaling - - computed: isValueExistInModel|/resources/kubedbComKafka/spec/monitor - 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 + - type: input + label: Name + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/metadata/properties/name + - type: select + label: Select Namespace + loader: getNamespaces + if: + type: function + name: isRancherManaged + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/metadata/properties/namespace + - type: select + label: Select Db + loader: getDbs + validation: + type: required + refresh: true + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/databaseRef/properties/name + watcher: + func: initMetadata + paths: + - schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/databaseRef/properties/name + + - type: radio + if: + type: function + name: isConsole + label: Select Type + validation: + type: required + schema: temp/properties/autoscalingType + watcher: + func: initMetadata + paths: + - temp/properties/autoscalingType 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/kubedbComKafka/properties/spec/properties/monitor/properties/agent - type: radio - - elements: - - label: - text: labels.scrapping_interval - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval - type: input - if: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComKafka/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/kubedbComKafka/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/kubedbComKafka/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: - - if: returnFalse - label: - text: labels.resources - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/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/kubedbComKafka/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/kubedbComKafka/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup - type: input - - label: - text: labels.port - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/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/kubedbComKafka/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args/items - type: input - label: - text: labels.args - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args - type: list-input-form - - alias: reusable_env - chart: - name: uibytebuildersdev-component-env - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/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.3.label -- form: - elements: - - alias: reusable_service_templates - chart: - name: uibytebuildersdev-component-service-templates - version: v0.29.0 - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/serviceTemplates - type: reusable-element - type: single-step-form - id: networking - title: steps.4.label -- form: - elements: - - alias: pod_template_standalone - chart: - name: uibytebuildersdev-component-pod-template - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - topology: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/topology - functionCallbacks: - isEditWizard: - $ref: functions#/returnTrue - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComKafka/properties/spec/properties/podTemplate - type: reusable-element - type: single-step-form - id: pod-template - title: steps.5.label -- form: - discriminator: - dbDetails: - default: false - type: boolean - elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: Select Db - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: Select Type - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - discriminator: - topologyMachines: - default: [] - type: array - elements: - - fetch: fetchTopologyMachines - if: returnFalse - schema: - $ref: discriminator#/topologyMachines - type: input - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComKafkaAutoscaler/spec/compute/broker/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/broker/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/broker/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/broker/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-broker-max: - type: string - allowedMachine-broker-min: - type: string + - text: Compute + value: compute + description: Scale your CPU Memory based on resource usage + - text: Storage + value: storage + description: Expand your database size based on volume usage + + - type: block-layout + showLabels: false + loader: fetchTopologyMachines + elements: + # topology mode - broker and controller + - type: block-layout + label: Topology + if: + type: function + name: dbTypeEqualsTo|topology + showLabels: false + # schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute elements: - - computed: setAllowedMachine|broker|min - disableUnselect: true - fetch: getMachines|broker|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|broker - schema: - $ref: discriminator#/properties/allowedMachine-broker-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/broker/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/broker/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|broker|max - disableUnselect: true - fetch: getMachines|broker|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|broker - schema: - $ref: discriminator#/properties/allowedMachine-broker-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/broker/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/broker/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|broker - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/broker/properties/controlledResources - type: multiselect - label: - text: Broker - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/broker - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComKafkaAutoscaler/spec/compute/controller/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/controller/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/controller/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/controller/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-controller-max: - type: string - allowedMachine-controller-min: - type: string + # Broker section + - type: switch + label: Trigger + fullwidth: true + schema: temp/properties/compute/properties/broker/properties/trigger + watcher: + func: onTriggerChange|compute/broker + paths: + - temp/properties/compute/properties/broker/properties/trigger + init: + type: func + value: setTrigger|autoscalingKubedbComKafkaAutoscaler/spec/compute/broker/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + customClass: width-300 + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/broker/properties/podLifeTimeThreshold + - type: block-layout + label: Broker + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/broker + elements: + - type: threshold-input + label: ResourceDiff Percentage + customClass: width-300 + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/broker/properties/resourceDiffPercentage + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-broker-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|broker|min + loader: + name: getMachines|broker|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-broker-max + watcher: + func: onMachineChange|broker + paths: + - temp/properties/allowedMachine-broker-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/broker/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/broker/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-broker-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|broker|max + loader: + name: getMachines|broker|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-broker-min + watcher: + func: onMachineChange|broker + paths: + - temp/properties/allowedMachine-broker-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/broker/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/broker/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|compute/broker + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/broker/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/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/broker/properties/containerControlledValues + + # Controller section + - type: switch + label: Trigger + fullwidth: true + schema: temp/properties/compute/properties/controller/properties/trigger + watcher: + func: onTriggerChange|compute/controller + paths: + - temp/properties/compute/properties/controller/properties/trigger + init: + type: func + value: setTrigger|autoscalingKubedbComKafkaAutoscaler/spec/compute/controller/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + customClass: width-300 + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/controller/properties/podLifeTimeThreshold + - type: block-layout + label: Controller + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/controller + elements: + - type: threshold-input + label: ResourceDiff Percentage + customClass: width-300 + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/controller/properties/resourceDiffPercentage + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-controller-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|controller|min + loader: + name: getMachines|controller|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-controller-max + watcher: + func: onMachineChange|controller + paths: + - temp/properties/allowedMachine-controller-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/controller/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/controller/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-controller-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|controller|max + loader: + name: getMachines|controller|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-controller-min + watcher: + func: onMachineChange|controller + paths: + - temp/properties/allowedMachine-controller-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/controller/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/controller/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|compute/controller + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/controller/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/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/controller/properties/containerControlledValues + + # combined mode - node only + - type: block-layout + label: Combined + if: + type: function + name: dbTypeEqualsTo|combined + showLabels: false + # schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute elements: - - computed: setAllowedMachine|controller|min - disableUnselect: true - fetch: getMachines|controller|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|controller - schema: - $ref: discriminator#/properties/allowedMachine-controller-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/controller/properties/minAllowed/properties/cpu - type: input - - label: - text: Memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/controller/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|controller|max - disableUnselect: true - fetch: getMachines|controller|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|controller - schema: - $ref: discriminator#/properties/allowedMachine-controller-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/controller/properties/maxAllowed/properties/cpu - type: input - - label: - text: Memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/controller/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|controller - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/controller/properties/controlledResources - type: multiselect - label: - text: Controller - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/controller - show_label: true - type: single-step-form - if: dbTypeEqualsTo|topology - label: - text: Topology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute - type: single-step-form - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComKafkaAutoscaler/spec/compute/node/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/node/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/node/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/node/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-node-max: - type: string - allowedMachine-node-min: - type: string + # Node section + - type: switch + label: Trigger + fullwidth: true + schema: temp/properties/compute/properties/node/properties/trigger + watcher: + func: onTriggerChange|compute/node + paths: + - temp/properties/compute/properties/node/properties/trigger + init: + type: func + value: setTrigger|autoscalingKubedbComKafkaAutoscaler/spec/compute/node/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + customClass: width-300 + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/node/properties/podLifeTimeThreshold + - type: block-layout + label: Node + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/node + elements: + - type: threshold-input + label: ResourceDiff Percentage + customClass: width-300 + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/node/properties/resourceDiffPercentage + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-node-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|node|min + loader: + name: getMachines|node|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-node-max + watcher: + func: onMachineChange|node + paths: + - temp/properties/allowedMachine-node-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/node/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/node/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-node-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|node|max + loader: + name: getMachines|node|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-node-min + watcher: + func: onMachineChange|node + paths: + - temp/properties/allowedMachine-node-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/node/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/node/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|compute/node + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/node/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/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/node/properties/containerControlledValues + + - type: block-layout + label: Node Topology + if: + type: function + name: hasNoAnnotations + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/nodeTopology elements: - - computed: setAllowedMachine|node|min - disableUnselect: true - fetch: getMachines|node|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|node - schema: - $ref: discriminator#/properties/allowedMachine-node-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/node/properties/minAllowed/properties/cpu - type: input - - label: - text: Memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/node/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|node|max - disableUnselect: true - fetch: getMachines|node|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|node - schema: - $ref: discriminator#/properties/allowedMachine-node-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/node/properties/maxAllowed/properties/cpu - type: input - - label: - text: Memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/node/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|node - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/node/properties/controlledResources - type: multiselect - label: - text: Node - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/node - show_label: true - type: single-step-form - if: dbTypeEqualsTo|combined - label: - text: Combined - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute - type: single-step-form - - elements: - - fetch: fetchNodeTopology - label: - text: Select Node Topology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name - type: select - - if: isNodeTopologySelected - label: - text: ScaleUp Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage - type: input - - if: isNodeTopologySelected - label: - text: ScaleDown Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage - type: input - if: hasNoAnnotations - label: - text: NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/nodeTopology - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: compute-autoscaler - title: steps.6.label -- form: - discriminator: - dbDetails: - default: false - type: boolean + - type: select + label: Select Node Topology + loader: fetchNodeTopology + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name + - type: threshold-input + label: ScaleUp Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage + - type: threshold-input + label: ScaleDown Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage + + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + # schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/opsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: storage-autoscaler + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - computed: getDbDetails - if: returnFalse - type: input - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: Select Db - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: Select Type - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComKafkaAutoscaler/spec/storage/broker/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/broker/properties/trigger - type: select - - label: - text: Expansion Mode + - type: block-layout + showLabels: false + elements: + - type: block-layout + showLabels: true + if: + type: function + name: isConsole + elements: + - type: input + label: Name + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/metadata/properties/name + - type: select + label: SelectNamespace + loader: getNamespaces + hasGroup: isRancherManaged + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/metadata/properties/namespace + - type: select + label: Select Db + loader: getDbs + refresh: true + validation: + type: required + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/databaseRef/properties/name + watcher: + func: initMetadata + paths: + - schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/databaseRef/properties/name + - type: radio + label: Select Type + validation: + type: required + isHorizontal: true + schema: discriminator/properties/autoscalingType options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/broker/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/broker/properties/usageThreshold - type: input - - addFormLabel: ScalingRules - element: - elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/broker/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/broker/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComKafkaAutoscaler/spec/storage/broker/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/broker/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComKafkaAutoscaler/spec/storage/broker/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/broker/properties/upperBound - type: input - if: dbTypeEqualsTo|topology - label: - text: Broker - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/broker - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComKafkaAutoscaler/spec/storage/controller/trigger - label: - text: Trigger + - text: Compute + value: compute + description: Scale your CPU Memory based on resource usage + - text: Storage + value: storage + description: Expand your database size based on volume usage + if: + type: function + name: isConsole + watcher: + func: initMetadata + paths: + - discriminator/properties/autoscalingType + # Broker mode + - type: switch + label: Trigger + fullwidth: true + if: + type: function + name: dbTypeEqualsTo|topology + schema: temp/properties/storage/properties/broker/properties/trigger + watcher: + func: onTriggerChange|storage/broker + paths: + - temp/properties/storage/properties/broker/properties/trigger + init: + type: func + value: setTrigger|autoscalingKubedbComKafkaAutoscaler/spec/storage/broker/trigger + - type: label-element + 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. + if: + type: function + name: dbTypeEqualsTo|topology + - type: select + label: Mode + description: Select how the storage expansion should be handled. + if: + type: function + name: dbTypeEqualsTo|topology options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/controller/properties/trigger - type: select - - label: - text: Expansion Mode + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/broker/properties/expansionMode + - type: block-layout + label: Broker + showLabels: true + loader: getDbDetails + if: + type: function + name: dbTypeEqualsTo|topology + elements: + - type: threshold-input + label: UsageThreshold (%) + subtitle: Set the storage usage percentage that triggers automatic expansion + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/broker/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/broker/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComKafka/spec/topology/broker/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComKafkaAutoscaler/spec/storage/broker/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/broker/properties/scalingRules + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/broker/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComKafkaAutoscaler/spec/storage/broker/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/broker/properties/upperBound + # Controller mode + - type: switch + label: Trigger + fullwidth: true + schema: temp/properties/storage/properties/controller/properties/trigger + if: + type: function + name: dbTypeEqualsTo|topology + watcher: + func: onTriggerChange|storage/controller + paths: + - temp/properties/storage/properties/controller/properties/trigger + init: + type: func + value: setTrigger|autoscalingKubedbComKafkaAutoscaler/spec/storage/controller/trigger + - type: label-element + 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. + if: + type: function + name: dbTypeEqualsTo|topology + - type: select + label: Mode + description: Select how the storage expansion should be handled. + if: + type: function + name: dbTypeEqualsTo|topology options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/controller/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/controller/properties/usageThreshold - type: input - - addFormLabel: ScalingRules - element: - elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/controller/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/controller/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComKafkaAutoscaler/spec/storage/controller/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/controller/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComKafkaAutoscaler/spec/storage/controller/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/controller/properties/upperBound - type: input - if: dbTypeEqualsTo|topology - label: - text: Controller - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/controller - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComKafkaAutoscaler/spec/storage/node/trigger - label: - text: Trigger + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/controller/properties/expansionMode + - type: block-layout + label: Controller + showLabels: true + loader: getDbDetails + if: + type: function + name: dbTypeEqualsTo|topology + elements: + - type: threshold-input + label: UsageThreshold (%) + subtitle: Set the storage usage percentage that triggers automatic expansion + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/controller/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/controller/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComKafka/spec/topology/controller/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComKafkaAutoscaler/spec/storage/controller/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/controller/properties/scalingRules + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/controller/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComKafkaAutoscaler/spec/storage/controller/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/controller/properties/upperBound + # Node mode + - type: switch + label: Trigger + fullwidth: true + schema: temp/properties/storage/properties/node/properties/trigger + if: + type: function + name: dbTypeEqualsTo|combined + watcher: + func: onTriggerChange|storage/node + paths: + - temp/properties/storage/properties/node/properties/trigger + init: + type: func + value: setTrigger|autoscalingKubedbComKafkaAutoscaler/spec/storage/node/trigger + - type: label-element + 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. + if: + type: function + name: dbTypeEqualsTo|combined + - type: select + label: Mode + description: Select how the storage expansion should be handled. + if: + type: function + name: dbTypeEqualsTo|combined options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/node/properties/trigger - type: select - - label: - text: Expansion Mode + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/node/properties/expansionMode + - type: block-layout + label: Node + showLabels: true + loader: getDbDetails + if: + type: function + name: dbTypeEqualsTo|combined + elements: + - type: threshold-input + label: Usage Threshold (%) + subtitle: Set the storage usage percentage that triggers automatic expansion + customClass: width-300 + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/node/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/node/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComKafka/spec/topology/node/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComKafkaAutoscaler/spec/storage/node/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/node/properties/scalingRules + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/node/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComKafkaAutoscaler/spec/storage/node/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/node/properties/upperBound + # Ops Request Options + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: monitoring + loader: initMonitoring + elements: + - type: label-element + label: To update Exporter Resource section click on Create OpsRequest + - type: anchor + label: Create OpsRequest + schema: temp/properties/opsRequestUrl + init: + type: func + value: getOpsRequestUrl|scale-vertically + - type: switch + label: Enable Monitoring + fullwidth: true + schema: temp/properties/enableMonitoring + init: + type: func + value: isValueExistInModel|/resources/kubedbComKafka/spec/monitor + watcher: + func: onEnableMonitoringChange + paths: + - temp/properties/enableMonitoring + - type: block-layout + if: + type: function + name: showMonitoringSection + elements: + - type: radio + label: Select a Monitoring Method + schema: schema/properties/resources/properties/kubedbComKafka/properties/spec/properties/monitor/properties/agent + isHorizontal: true options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/node/properties/expansionMode - type: select - - label: - text: Usage Threshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/node/properties/usageThreshold - type: input - - addFormLabel: Scaling Rules - element: + - text: Prometheus Operator + value: prometheus.io/operator + description: Inject metric exporter sidecar and creates a ServiceMonitor + - text: Custom ServiceMonitor + value: prometheus.io + description: Injects the metric exporter sidecar and let you customize ServiceMonitor + - text: Custom Scrapper + value: prometheus.io/builtin + description: Inject metric exporter sidecar and add Prometheus annotations to the stats Service + init: + type: static + value: prometheus.io/operator + watcher: + func: onAgentChange + paths: + - schema/properties/resources/properties/kubedbComKafka/properties/spec/properties/monitor/properties/agent + - type: block-layout + label: ServiceMonitor Configuration + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComKafka/spec/monitor/agent + elements: + - label: Scrapping Interval + schema: schema/properties/resources/properties/kubedbComKafka/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval + type: input + - type: block-layout + label: Service Monitor + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComKafka/spec/monitor/agent + elements: + - type: array-object-form + label: Endpoints + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/endpoints elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/node/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/node/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: Scaling Rules - onChange: handleUnit|autoscalingKubedbComKafkaAutoscaler/spec/storage/node/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/node/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComKafkaAutoscaler/spec/storage/node/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/storage/properties/node/properties/upperBound - type: input - if: dbTypeEqualsTo|combined - label: - text: Node - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/compute/properties/node - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComKafkaAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: storage-autoscaler - title: steps.7.label -- form: - discriminator: - binding: - default: false - type: boolean + - type: switch + label: Honor labels + fullwidth: true + schema: honorLabels + - type: input + label: Interval + schema: interval + validation: + type: required + - type: input + label: Path + schema: path + validation: + type: required + - type: input + label: Port + schema: port + validation: + type: required + - type: select + multiple: true + label: Match Namespaces + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/namespaceSelector/properties/matchNames + loader: getResources|core|v1|namespaces + if: + type: function + name: returnFalse + - type: block-layout + showLabels: false + # schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector + if: + type: function + name: returnFalse + elements: + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector/properties/matchLabels + - type: object-item + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/metadata/properties/labels + label : Labels + buttonClass: is-light is-outlined + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComKafka/spec/monitor/agent + # individualItemDisabilityCheck: disableLableChecker + - type: label-element + label: Exporter Configuration + schema: '' + - type: switch + label: Customize Exporter Sidecar + fullwidth: true + schema: temp/properties/customizeExporter + init: + type: static + value: true + watcher: + func: onCustomizeExporterChange + paths: + - temp/properties/customizeExporter + - type: block-layout + label: Customer Exporter Section + showLabels: false + if: + type: function + name: showCustomizeExporterSection + elements: + - type: machine-compare + label: Resources + schema: schema/properties/resources/properties/kubedbComKafka/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/resources + if: + type: function + name: returnFalse + - type: label-element + label: Security Context + schema: '' + - type: input + schema: schema/properties/resources/properties/kubedbComKafka/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsUser + label: Run as User + - type: input + schema: schema/properties/resources/properties/kubedbComKafka/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup + label: Run as Group + - type: input + schema: schema/properties/resources/properties/kubedbComKafka/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/port + label: Port + - type: array-item-form + label: Args + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/kubedbComKafka/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args + init: + type: static + value: ['--compatible-mode'] + element: + type: input + label: Args + # isSubsection: true + - type: block-layout + label: Metadata + showLabels: false + elements: + - type: array-object-form + init: + type: func + value: initEnvArray + label: Environment Variables + buttonClass: is-light is-outlined + watcher: + func: onEnvArrayChange + paths: + - temp/properties/env + schema: temp/properties/env + elements: + - type: input + label: Name + schema: name + validation: + type: required + - type: radio + label: Value From + schema: temp/properties/valueFromType + validation: + type: required + init: + type: func + value: setValueFrom + options: + - text: Input + value: input + - text: Secret + value: secret + - text: ConfigMap + value: configMap + watcher: + func: onValueFromChange + paths: + - temp/properties/valueFromType + - type: input + label: Value + schema: value + validation: + type: required + if: + name: isEqualToTemp|input + type: function + - type: select + if: + type: function + name: isEqualToTemp|configMap + label: ConfigMap Name + schema: valueFrom/properties/configMapKeyRef/properties/name + loader: + name: resourceNames|core|v1|configmaps + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: ConfigMap Key + schema: valueFrom/properties/configMapKeyRef/properties/key + if: + type: function + name: isEqualToTemp|configMap + loader: + name: getConfigMapKeys + watchPaths: + - schema/resources/kubedbComKafka/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/configMapKeyRef/name + - schema/metadata/release/namespace + - type: select + label: Secret Name + schema: valueFrom/properties/secretKeyRef/properties/name + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecrets + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: Secret Key + schema: valueFrom/properties/secretKeyRef/properties/key + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecretKeys + watchPaths: + - schema/resources/kubedbComKafka/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/secretKeyRef/name + - schema/metadata/release/namespace + + + - type: single-step-form + id: binding elements: - - computed: isBindingAlreadyOn - label: - text: Expose Database - onChange: addOrRemoveBinding - schema: - $ref: discriminator#/properties/binding - type: switch - type: single-step-form - id: binding - title: Gateway Binding -type: multi-step-form + - type: switch + label: Expose Database + schema: temp/properties/binding + fullwidth: true + init: + type: func + value: isBindingAlreadyOn + watcher: + func: addOrRemoveBinding + paths: + - temp/properties/binding \ No newline at end of file diff --git a/charts/kubedbcom-kafka-editor/ui/functions.js b/charts/kubedbcom-kafka-editor/ui/functions.js index ec52e22474..d41e0b28f4 100644 --- a/charts/kubedbcom-kafka-editor/ui/functions.js +++ b/charts/kubedbcom-kafka-editor/ui/functions.js @@ -1,1585 +1,1051 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + // ************************* common functions ******************************************** // eslint-disable-next-line no-empty-pattern -async function fetchJsons({ axios, itemCtx, setDiscriminatorValue }, discriminatorPath) { - 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) - } - - if (discriminatorPath) { - setDiscriminatorValue(discriminatorPath, { - ui: ui.data || {}, - language: language.data || {}, - functions, - }) - } - - return { - ui: ui.data || {}, - language: language.data || {}, - functions, - } -} - -function disableLableChecker({ itemCtx }) { - const { key } = itemCtx - if (key.startsWith('app.kubernetes.io') || key.includes('helm')) return true - else return false -} - -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} - -async function getResources({ axios, storeGet }, 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 [] - } -} - -function isEqualToDiscriminatorPath( - { discriminator, getValue, watchDependency }, - value, - discriminatorPath, -) { - watchDependency('discriminator#' + discriminatorPath) - const discriminatorValue = getValue(discriminator, discriminatorPath) - return discriminatorValue === value -} - -function setValueFromModel({ getValue, model }, path) { - return getValue(model, path) -} - -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 -} - -async function getResourceList(axios, storeGet, { 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 } }, - }, - }) +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + /********** Initialize Discriminator **************/ + + setDiscriminatorValue('binding', true) + 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 autoscaleType = '' + let dbDetails = {} + let instance = {} + + function isKubedb() { + return !!storeGet('/route/params/actions') } - return ans -} - -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - 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) - }) - } + function isConsole() { + const isKube = isKubedb() - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + if (isKube) { + const dbName = storeGet('/route/params/name') || '' + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComKafkaAutoscaler/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/autoscalingKubedbComKafkaAutoscaler/metadata/name', + value: modifiedName, + force: true, + }) + const namespace = storeGet('/route/query/namespace') || '' + if (namespace) { + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComKafkaAutoscaler/metadata/namespace', + value: namespace, + force: true, + }) + } } - }) -} -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) - - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) + return !isKube } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + async function getDbDetails() { + const annotations = + getValue(model, '/resources/autoscalingKubedbComKafkaAutoscaler/metadata/annotations') || {} + instance = annotations['kubernetes.io/instance-type'] + const owner = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + const namespace = + storeGet('/route/query/namespace') || + getValue(model, '/resources/autoscalingKubedbComKafkaAutoscaler/metadata/namespace') || + '' + const name = + storeGet('/route/params/name') || + getValue(model, '/resources/autoscalingKubedbComKafkaAutoscaler/spec/databaseRef/name') || + '' + + if (namespace && name) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/kafkas/${name}`, + ) + dbDetails = resp.data || {} + setDiscriminatorValue('/dbDetails', true) + } catch (e) { + console.log(e) + } } - }) -} - -function returnTrue() { - return true -} - -function returnStringYes() { - return 'yes' -} -function isDedicatedModeSelected({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComKafka/spec/topology') - isDedicatedSelected = getValue(model, '/resources/kubedbComKafka/spec/topology') - - return !!isDedicatedSelected -} - -function isCombinedModeSelected({ model, getValue, watchDependency }) { - return !isDedicatedSelected({ model, getValue, watchDependency }) -} - -function isDiscriminatorEqualTo( - { discriminator, getValue, watchDependency }, - discriminatorPath, - value, -) { - watchDependency('discriminator#' + discriminatorPath) - const pathValue = getValue(discriminator, discriminatorPath) - - return value === pathValue -} - -// ************************* Basic Info ********************************************** - -async function getKafkaVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null, authPlugin: null }, - }, - }, - } - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) - - const resources = (resp && resp.data && resp.data.items) || [] - - // keep only non deprecated versions - const filteredKafkaVersions = resources.filter((item) => item.spec && !item.spec.deprecated) - - filteredKafkaVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredKafkaVersions -} - -function isSecurityEnabled({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComKafka/spec/disableSecurity') - const value = getValue(model, '/resources/kubedbComKafka/spec/disableSecurity') - return !value -} - -function onDisableSecurityChange({ model, getValue, commit }) { - const disableSecurity = getValue(model, '/resources/kubedbComKafka/spec/disableSecurity') - - if (disableSecurity) { - commit('wizard/model$delete', '/resources/kubedbComKafka/spec/authSecret') - commit('wizard/model$delete', '/resources/secret_admin_cred') - commit('wizard/model$delete', '/resources/kubedbComKafka/spec/tls') - } -} - -function onEnableSSLChange({ model, getValue, commit }) { - const enabelSSL = getValue(model, '/resources/kubedbComKafka/spec/enableSSL') - - if (enabelSSL === false) { - removeCertificatesOfAliases({ model, getValue, commit }, ['server', 'client']) - } -} - -function removeCertificatesOfAliases({ model, getValue, commit }, aliasesToRemove) { - const certificates = getValue(model, '/resources/kubedbComKafka/spec/tls/certificates') || [] - const updatedCertificates = certificates.filter((item) => !aliasesToRemove.includes(item.alias)) - commit('wizard/model$update', { - path: '/resources/kubedbComKafka/spec/tls/certificates', - value: updatedCertificates, - force: true, - }) -} - -/************************************* Database Secret Section ********************************************/ - -function getCreateAuthSecret({ model, getValue }) { - const authSecret = getValue(model, '/resources/kubedbComKafka/spec/authSecret') - - return !authSecret -} - -function showExistingSecretSection({ getValue, watchDependency, discriminator }) { - watchDependency('discriminator#/createAuthSecret') - - const hasAuthSecretName = getValue(discriminator, '/createAuthSecret') - return !hasAuthSecretName -} - -function showPasswordSection({ getValue, watchDependency, discriminator }) { - return !showExistingSecretSection({ - getValue, - watchDependency, - discriminator, - }) -} - -function setAuthSecretPassword({ model, getValue }) { - const encodedPassword = getValue(model, '/resources/secret_admin_cred/data/password') - return encodedPassword ? decodePassword({}, encodedPassword) : '' -} - -function onAuthSecretPasswordChange({ getValue, discriminator, commit }) { - const stringPassword = getValue(discriminator, '/password') - - if (stringPassword) { commit('wizard/model$update', { - path: '/resources/secret_admin_cred/data/password', - value: encodePassword({}, stringPassword), + path: `/metadata/release/name`, + value: name, force: true, }) commit('wizard/model$update', { - path: '/resources/secret_admin_cred/data/username', - value: encodePassword({}, 'admin'), + path: `/metadata/release/namespace`, + value: namespace, force: true, }) - } else { - commit('wizard/model$delete', '/resources/secret_admin_cred') - } -} - -// eslint-disable-next-line no-empty-pattern -function encodePassword({}, value) { - return btoa(value) -} - -// eslint-disable-next-line no-empty-pattern -function decodePassword({}, value) { - return atob(value) -} - -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/resources/kubedbComKafka/spec/authSecret') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/resources/secret_admin_cred') - } -} - -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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) + commit('wizard/model$update', { + path: `/resources/autoscalingKubedbComKafkaAutoscaler/spec/databaseRef/name`, + value: name, + force: true, }) - - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + commit('wizard/model$update', { + path: `/resources/autoscalingKubedbComKafkaAutoscaler/metadata/labels`, + value: dbDetails.metadata.labels, + force: true, }) - return filteredSecrets - } catch (e) { - console.log(e) - return [] } -} - -function showSecretSection({ model, getValue, watchDependency, storeGet }) { - const steps = storeGet('/wizard/configureOptions') - return ( - !steps.includes('internal-users') && isSecurityEnabled({ model, getValue, watchDependency }) - ) -} - -// ********************* Database Mode *********************** -function isNotCombinedMode({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - return mode !== 'Combined' -} + function initMetadata() { + const dbName = + getValue(model, '/resources/autoscalingKubedbComKafkaAutoscaler/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/autoscalingKubedbComKafkaAutoscaler/metadata/name', + value: modifiedName, + force: true, + }) -function setDatabaseMode({ model, getValue }) { - isDedicatedSelected = getValue(model, '/resources/kubedbComKafka/spec/topology') - if (isDedicatedSelected) { - return 'Dedicated' - } else { - return 'Combined' + // delete the other type object from model + if (type === 'compute') + commit('wizard/model$delete', '/resources/autoscalingKubedbComKafkaAutoscaler/spec/storage') + if (type === 'storage') + commit('wizard/model$delete', '/resources/autoscalingKubedbComKafkaAutoscaler/spec/compute') } -} - -let storageClassList = [] -async function getStorageClassNames( - { axios, storeGet, commit, setDiscriminatorValue, getValue, model }, - path, -) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/storage.k8s.io/v1/storageclasses`, - { - params: { - filter: { items: { metadata: { name: null, annotations: 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 - }) - if (!path) { - setDiscriminatorValue('/storageClasses', resources) + async function fetchTopologyMachines() { + const instance = hasAnnotations() + + 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 [] + } + } } - storageClassList = resources - const initialStorageClass = getValue(model, path) - if (!initialStorageClass) setStorageClass({ model, getValue, commit }, path) - return resources -} - -function setStorageClass({ model, getValue, commit }, path) { - const deletionPolicy = getValue(model, '/resource/kubedbComKafka/spec/deletionPolicy') || '' - let storageClass = getValue(model, path) || '' - const suffix = '-retain' - - const simpleClassList = storageClassList.filter((item) => { - return !item.metadata?.name?.endsWith(suffix) - }) - - const retainClassList = storageClassList.filter((item) => { - return item.metadata?.name?.endsWith(suffix) - }) - - const defaultSimpleList = simpleClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] - ) - }) + function dbTypeEqualsTo(type) { + // watchDependency('discriminator#/dbDetails') - const defaultRetainList = retainClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] - ) - }) - - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - if (simpleClassList.length > 1) { - const found = defaultSimpleList.length ? defaultSimpleList[0] : simpleClassList[0] - storageClass = found.value - } else if (simpleClassList.length === 1) { - storageClass = simpleClassList[0]?.value - } else { - const found = defaultRetainList.length - ? defaultRetainList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found - } - } else { - if (retainClassList.length > 1) { - const found = defaultRetainList.length ? defaultRetainList[0] : retainClassList[0] - storageClass = found.value - } else if (retainClassList.length === 1) { - storageClass = retainClassList[0]?.value - } else { - const found = defaultSimpleList.length - ? defaultSimpleList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found + const { spec } = dbDetails || {} + const { topology } = spec || {} + let verd = '' + if (topology) verd = 'topology' + else { + verd = 'combined' } + clearSpecModel(verd) + return type === verd && spec } - if (storageClass && path) { - commit('wizard/model$update', { - path: path, - value: storageClass, - force: true, - }) + function clearSpecModel(dbtype) { + if (dbtype === 'standalone') { + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComKafkaAutoscaler/spec/${autoscaleType}/cluster`, + ) + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComKafkaAutoscaler/spec/${autoscaleType}/sentinel`, + ) + } else if (dbtype === 'cluster') { + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComKafkaAutoscaler/spec/${autoscaleType}/standalone`, + ) + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComKafkaAutoscaler/spec/${autoscaleType}/sentinel`, + ) + } else if (dbtype === 'sentinel') { + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComKafkaAutoscaler/spec/${autoscaleType}/standalone`, + ) + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComKafkaAutoscaler/spec/${autoscaleType}/cluster`, + ) + } } -} -function deleteDatabaseModePath({ discriminator, getValue, commit }) { - const mode = getValue(discriminator, '/activeDatabaseMode') - if (mode === 'Dedicated') { - commit('wizard/model$delete', '/resources/kubedbComKafka/spec/replicas') - commit('wizard/model$delete', '/resources/kubedbComKafka/spec/storage') - commit('wizard/model$delete', '/resources/kubedbComKafka/spec/podTemplate') - } else if (mode === 'Combined') { - commit('wizard/model$delete', '/resources/kubedbComKafka/spec/topology') + function setTrigger(path) { + let value = getValue(model, `/resources/${path}`) + if (value) return value + return 'On' } -} -function isEqualToDatabaseMode({ getValue, watchDependency, discriminator }, value) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - - return mode === value -} - -function getStorageClassNamesFromDiscriminator( - { model, discriminator, getValue, watchDependency, commit }, - path, -) { - watchDependency('discriminator#/storageClasses') - const options = getValue(discriminator, '/storageClasses') || [] - - setStorageClass({ model, getValue, commit }, path) - return options -} + function hasAnnotations() { + const annotations = + getValue(model, '/resources/autoscalingKubedbComKafkaAutoscaler/metadata/annotations') || {} + const instance = annotations['kubernetes.io/instance-type'] -// ************************** TLS ******************************************* - -function setApiGroup() { - return 'cert-manager.io' -} - -function setApiGroupEdit({ model, getValue }) { - const kind = getValue(model, '/resources/kubedbComKafka/spec/tls/issuerRef/kind') - const name = getValue(model, '/resources/kubedbComKafka/spec/tls/issuerRef/name') - return kind && name ? 'cert-manager.io' : '' -} - -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - watchDependency('model#/resources/kubedbComKafka/spec/tls/issuerRef/apiGroup') - watchDependency('model#/resources/kubedbComKafka/spec/tls/issuerRef/kind') - watchDependency('model#/metadata/release/namespace') - const apiGroup = getValue(model, '/resources/kubedbComKafka/spec/tls/issuerRef/apiGroup') - const kind = getValue(model, '/resources/kubedbComKafka/spec/tls/issuerRef/kind') - const namespace = getValue(model, '/metadata/release/namespace') - - let url - if (kind === 'Issuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/namespaces/${namespace}/issuers` - } else if (kind === 'ClusterIssuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/clusterissuers` + return !!instance } - try { - const resp = await axios.get(url) - - const resources = (resp && resp.data && resp.data.items) || [] + function setAllowedMachine(type, minmax) { + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = {} + } - 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 [] + const machine = parsedInstance[type] || '' + const mx = machine?.includes(',') ? machine.split(',')[1] : '' + const mn = machine?.includes(',') ? machine.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: '', + } } -} -async function hasIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await getIssuerRefsName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !!(resp && resp.length) -} - -async function hasNoIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await hasIssuerRefName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !resp -} - -function setClusterAuthMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComKafka/spec/clusterAuthMode') - return val || 'x509' -} - -function setSSLMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComKafka/spec/sslMode') - return val || 'requireSSL' -} + function getMachines(type, minmax) { + // watchDependency('discriminator#/topologyMachines') + const depends = minmax === 'min' ? 'max' : 'min' + const dependantPath = `/allowedMachine-${type}-${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, + }, + } + }) -function showTlsConfigureSection({ watchDependency, model, getValue }) { - watchDependency('model#/resources/kubedbComKafka/spec/enableSSL') - const configureStatus = getValue(model, '/resources/kubedbComKafka/spec/enableSSL') - return configureStatus -} + const filteredMachine = machines?.filter((item, ind) => + minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, + ) -function onTlsConfigureChange({ model, getValue, commit }) { - const configureStatus = getValue(model, '/resources/kubedbComKafka/spec/enableSSL') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComKafka/spec/tls', - value: { issuerRef: {}, certificates: [] }, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComKafka/spec/tls') + return dependantIndex === -1 ? machines : filteredMachine } -} - -async function showTlsRecommendation({ axios, storeGet }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const url = `/clusters/${owner}/${cluster}/proxy/cert-manager.io/v1/issuers` + function onMachineChange(type) { + const annoPath = '/resources/autoscalingKubedbComKafkaAutoscaler/metadata/annotations' + const annotations = getValue(model, annoPath) || {} + const instance = annotations['kubernetes.io/instance-type'] + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = {} + } - try { - await axios.get(url, { - params: { filter: { items: { metadata: { name: null } } } }, - }) - return false - } catch (err) { - // if any error response status is 404 or not - if (err.response && err.response.status === 404) { - resp = false + // Now discriminator values are objects with { machine, cpu, memory } + const minMachineObj = getValue(discriminator, `/allowedMachine-${type}-min`) + const maxMachineObj = getValue(discriminator, `/allowedMachine-${type}-max`) + const minMachine = minMachineObj?.machine || '' + const maxMachine = maxMachineObj?.machine || '' + const minMaxMachine = `${minMachine},${maxMachine}` + + parsedInstance[type] = minMaxMachine + const instanceString = JSON.stringify(parsedInstance) + annotations['kubernetes.io/instance-type'] = instanceString + + // 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/autoscalingKubedbComKafkaAutoscaler/spec/compute/${type}` + + if (minMachine && maxMachine && instance !== instanceString) { + 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, + }) } - console.log(err) - return true } -} - -async function getAliasOptions({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComKafka/spec/enableSSL') - watchDependency('model#/resources/kubedbComKafka/spec/monitor') - - const enableSSL = getValue(model, '/resources/kubedbComKafka/spec/enableSSL') - - // always include transport cert alias - const aliases = [] - if (enableSSL) { - aliases.push('server') - aliases.push('client') + function hasNoAnnotations() { + return !hasAnnotations() } - return aliases -} - -/****** Monitoring *********/ - -function showMonitoringSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/enableMonitoring') - const configureStatus = getValue(discriminator, '/enableMonitoring') - return configureStatus -} - -function onEnableMonitoringChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/enableMonitoring') - if (configureStatus) { + function setControlledResources(type) { + const list = ['cpu', 'memory'] + const path = `/resources/autoscalingKubedbComKafkaAutoscaler/spec/compute/${type}/controlledResources` commit('wizard/model$update', { - path: '/resources/kubedbComKafka/spec/monitor', - value: {}, + path: path, + value: list, force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComKafka/spec/monitor') + return list } - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: configureStatus ? 'warning' : 'none', - force: true, - }) -} - -function isValueExistInModel({ model, getValue }, path) { - const modelValue = getValue(model, path) - return !!modelValue -} - -function onNamespaceChange({ commit, model, getValue }) { - const namespace = getValue(model, '/metadata/release/namespace') - const agent = getValue(model, '/resources/kubedbComKafka/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', - value: [namespace], - force: true, - }) + function showOpsRequestOptions() { + if (isKubedb() === true) return true + // watchDependency('model#/resources/autoscalingKubedbComKafkaAutoscaler/spec/databaseRef/name') + // watchDependency('discriminator#/autoscalingType') + return ( + !!getValue(model, '/resources/autoscalingKubedbComKafkaAutoscaler/spec/databaseRef/name') && + !!getValue(discriminator, '/autoscalingType') + ) } -} - -function onLabelChange({ commit, model, getValue }) { - const labels = getValue(model, '/resources/kubedbComKafka/spec/metadata/labels') - const agent = getValue(model, '/resources/kubedbComKafka/spec/monitor/agent') + function setApplyToIfReady() { + return 'IfReady' + } - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value } -} -function onNameChange({ commit, model, getValue }) { - const dbName = getValue(model, '/metadata/release/name') + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - const agent = getValue(model, '/resources/kubedbComKafka/spec/monitor/agent') + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) - const labels = getValue(model, '/resources/kubedbComKafka/spec/metadata/labels') + const resources = (resp && resp.data && resp.data.items) || [] - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) + 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 [] + } } - const scheduleBackup = getValue(model, '/resources/stashAppscodeComBackupConfiguration') + async function getNamespaces() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - if (scheduleBackup) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, - force: true, + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_repo') - if (creatingNewRepo) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: `${dbName}-repo`, - force: true, - }) - } - } - const prePopulateDatabase = getValue(model, '/resources/stashAppscodeComRestoreSession_init') + const resources = (resp && resp.data && resp.data.items) || [] - if (prePopulateDatabase) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_init_repo') - if (creatingNewRepo) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: `${dbName}-init-repo`, - force: true, + } + + 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 [] } - // to reset configSecret name field - const hasSecretConfig = getValue(model, '/resources/secret_user_config') - if (hasSecretConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComKafka/spec/configSecret/name', - value: `${dbName}-config`, - force: true, + function isNodeTopologySelected() { + // watchDependency( + // 'model#/resources/autoscalingKubedbComKafkaAutoscaler/spec/compute/nodeTopology/name', + // ) + const nodeTopologyName = + getValue( + model, + '/resources/autoscalingKubedbComKafkaAutoscaler/spec/compute/nodeTopology/name', + ) || '' + return !!nodeTopologyName.length + } + + async function getDbs() { + // watchDependency('model#/resources/autoscalingKubedbComKafkaAutoscaler/metadata/namespace') + const namespace = getValue( + model, + '/resources/autoscalingKubedbComKafkaAutoscaler/metadata/namespace', + ) + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises`, + { + 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 returnFalse() { - return false -} + async function getNamespacedResourceList( + axios, + storeGet, + { namespace, group, version, resource }, + ) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function onAgentChange({ commit, model, getValue }) { - const agent = getValue(model, '/resources/kubedbComKafka/spec/monitor/agent') + 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) + } - if (!agent) { - removeCertificatesOfAliases({ model, getValue, commit }, ['metrics-exporter']) + return ans } - if (agent === 'prometheus.io') { + function removeCertificatesOfAliases(aliasesToRemove) { + const certificates = getValue(model, '/resources/kubedbComKafka/spec/tls/certificates') || [] + const updatedCertificates = certificates.filter((item) => !aliasesToRemove.includes(item.alias)) commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', - value: [], + path: '/resources/kubedbComKafka/spec/tls/certificates', + value: updatedCertificates, force: true, }) - - onNamespaceChange({ commit, model, getValue }) - onLabelChange({ commit, model, getValue }) - } else { - commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') } -} -//////////////////// service monitor /////////////////// + /************* Monitoring *************/ -function isEqualToServiceMonitorType({ rootModel, watchDependency }, value) { - watchDependency('rootModel#/spec/type') - return rootModel && rootModel.spec && rootModel.spec.type === value -} + function showMonitoringSection() { + // watchDependency('discriminator#/enableMonitoring') + const configureStatus = getValue(discriminator, '/enableMonitoring') + return configureStatus + } -//////////////////// custom config ///////////////// -function onConfigurationSourceChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSource') - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_user_config') - commit('wizard/model$delete', '/resources/config_secret') - } else { - const value = getValue(model, '/resources/secret_user_config') - if (!value) { + function onEnableMonitoringChange() { + const configureStatus = getValue(discriminator, '/enableMonitoring') + if (configureStatus) { commit('wizard/model$update', { - path: '/resources/secret_user_config', + path: '/resources/kubedbComKafka/spec/monitor', value: {}, force: true, }) + } else { + commit('wizard/model$delete', '/resources/kubedbComKafka/spec/monitor') } - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` + + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: '/resources/kubedbComKafka/spec/configSecret/name', - value: configSecretName, + path: '/form/alert/enabled', + value: configureStatus ? 'warning' : 'none', force: true, }) } -} -function setConfigurationSource({ model, getValue }) { - const modelValue = getValue(model, '/resources/secret_user_config') - if (modelValue) { - return 'create-new-config' + function isValueExistInModel(path) { + const modelValue = getValue(model, path) || null + return !!modelValue } - return 'use-existing-config' -} -function setConfigFiles({ model, getValue, watchDependency, setDiscriminatorValue }) { - watchDependency('model#/resources/secret_user_config/stringData') - const configFiles = getValue(model, '/resources/secret_user_config/stringData') + // function onNamespaceChange() { + // const namespace = getValue(model, '/metadata/release/namespace') + // const agent = getValue(model, '/resources/kubedbComKafka/spec/monitor/agent') + // if (agent === 'prometheus.io') { + // commit('wizard/model$update', { + // path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + // value: [namespace], + // force: true, + // }) + // } + // } - const files = [] + function onLabelChange() { + const labels = getValue(model, '/resources/kubedbComKafka/spec/metadata/labels') - for (const item in configFiles) { - const obj = {} - obj.key = item - obj.value = configFiles[item] - files.push(obj) - } + const agent = getValue(model, '/resources/kubedbComKafka/spec/monitor/agent') - setDiscriminatorValue('/configFiles', files) + if (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', + value: labels, + force: true, + }) + } + } - return files -} + function onAgentChange() { + const agent = getValue(model, '/resources/kubedbComKafka/spec/monitor/agent') -function onConfigFilesChange({ discriminator, getValue, commit }) { - const files = getValue(discriminator, '/configFiles') + if (!agent) { + removeCertificatesOfAliases(['metrics-exporter']) + } - const configFiles = {} + if (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', + value: [], + force: true, + }) - if (files) { - files.forEach((item) => { - const { key, value } = item - configFiles[key] = value - }) + onNamespaceChange() + onLabelChange() + } else { + commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') + } } - commit('wizard/model$update', { - path: '/resources/secret_user_config/stringData', - value: configFiles, - force: true, - }) -} - -function onSetCustomConfigChange({ discriminator, getValue, commit }) { - const value = getValue(discriminator, '/setCustomConfig') - - if (value === 'no') { - commit('wizard/model$delete', '/resources/kubedbComKafka/spec/configSecret') - commit('wizard/model$delete', '/resources/secret_user_config') + 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/kafkaopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=${reqType}` } -} - -function initSetCustomConfig({ model, getValue }) { - const configSecret = getValue(model, '/resources/kubedbComKafka/spec/configSecret/name') - - if (configSecret) return 'yes' - else return 'no' -} - -function getOpsRequestUrl({ storeGet, model, getValue, mode }, 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 + `/create-opsrequest-${reqType.toLowerCase()}?namespace=${namespace}` - - if (mode === 'standalone-step') return pathConstructedForKubedb - else - return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/kafkaopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=${reqType}` -} - -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + function onNamespaceChange() { + const namespace = getValue( + model, + '/resources/autoscalingKubedbComKafkaAutoscaler/metadata/namespace', + ) + if (!namespace) { + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComKafkaAutoscaler/spec/databaseRef/name', + ) + } } -} - -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} - -///////////////////////// Autoscaler /////////////////// -let autoscaleType = '' -let dbDetails = {} -function isConsole({ storeGet, commit }) { - const isKube = isKubedb({ storeGet }) + function showCustomizeExporterSection() { + // watchDependency('discriminator#/customizeExporter') + const configureStatus = getValue(discriminator, '/customizeExporter') + return configureStatus + } - if (isKube) { - const dbName = storeGet('/route/params/name') || '' - commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComKafkaAutoscaler/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/autoscalingKubedbComKafkaAutoscaler/metadata/name', - value: modifiedName, - force: true, - }) - const namespace = storeGet('/route/query/namespace') || '' - if (namespace) { + function onCustomizeExporterChange() { + const configureStatus = getValue(discriminator, '/customizeExporter') + if (configureStatus) { commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComKafkaAutoscaler/metadata/namespace', - value: namespace, + path: '/resources/kubedbComKafka/spec/monitor/prometheus/exporter', + value: {}, force: true, }) + } else { + commit('wizard/model$delete', '/resources/kubedbComKafka/spec/monitor/prometheus/exporter') } } - return !isKube -} - -function isKubedb({ storeGet }) { - return !!storeGet('/route/params/actions') -} + function setValueFrom() { + if (isConfigMapTypeValueFrom()) { + return 'configMap' + } else if (isSecretTypeValueFrom()) { + return 'secret' + } else { + return 'input' + } + } -function showOpsRequestOptions({ model, getValue, watchDependency, storeGet, discriminator }) { - if (isKubedb({ storeGet }) === true) return true - watchDependency('model#/resources/autoscalingKubedbComKafkaAutoscaler/spec/databaseRef/name') - watchDependency('discriminator#/autoscalingType') - return ( - !!getValue(model, '/resources/autoscalingKubedbComKafkaAutoscaler/spec/databaseRef/name') && - !!getValue(discriminator, '/autoscalingType') - ) -} + function isConfigMapTypeValueFrom() { + const valueFrom = getValue(discriminator, '/valueFrom') + return !!(valueFrom && valueFrom.configMapKeyRef) + } -async function getNamespaces({ axios, storeGet }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function isSecretTypeValueFrom() { + const valueFrom = getValue(discriminator, '/valueFrom') + return !!(valueFrom && valueFrom.secretKeyRef) + } - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + 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, + }) + } + } - const resources = (resp && resp.data && resp.data.items) || [] + // 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, + }) - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) } - }) -} - -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - watchDependency('model#/resources/autoscalingKubedbComKafkaAutoscaler/metadata/namespace') - const namespace = getValue( - model, - '/resources/autoscalingKubedbComKafkaAutoscaler/metadata/namespace', - ) - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + 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/kubedbComKafka/spec/monitor/prometheus/exporter/env/${index}/valueFrom/configMapKeyRef/name`, + ) - const resources = (resp && resp.data && resp.data.items) || [] + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/configMapKeyRef/name') - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + if (!configMapName) return [] -async function getDbDetails({ commit, setDiscriminatorValue, axios, storeGet, getValue, model }) { - const owner = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - const namespace = - storeGet('/route/query/namespace') || - getValue(model, '/resources/autoscalingKubedbComKafkaAutoscaler/metadata/namespace') || - '' - const name = - storeGet('/route/params/name') || - getValue(model, '/resources/autoscalingKubedbComKafkaAutoscaler/spec/databaseRef/name') || - '' - - if (namespace && name) { try { const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/kafkas/${name}`, + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/configmaps/${configMapName}`, ) - dbDetails = resp.data || {} - setDiscriminatorValue('/dbDetails', true) + + 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 [] } } - commit('wizard/model$update', { - path: `/metadata/release/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/metadata/release/namespace`, - value: namespace, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComKafkaAutoscaler/spec/databaseRef/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComKafkaAutoscaler/metadata/labels`, - value: dbDetails.metadata.labels, - force: true, - }) -} - -async function dbTypeEqualsTo({ watchDependency, commit }, type) { - watchDependency('discriminator#/dbDetails') - - const { spec } = dbDetails || {} - const { topology } = spec || {} - let verd = '' - if (topology) verd = 'topology' - else { - verd = 'combined' - } - clearSpecModel({ commit }, verd) - return type === verd && spec -} + 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') -function clearSpecModel({ commit }, dbtype) { - if (dbtype === 'standalone') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComKafkaAutoscaler/spec/${autoscaleType}/cluster`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComKafkaAutoscaler/spec/${autoscaleType}/sentinel`, - ) - } else if (dbtype === 'cluster') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComKafkaAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComKafkaAutoscaler/spec/${autoscaleType}/sentinel`, - ) - } else if (dbtype === 'sentinel') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComKafkaAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComKafkaAutoscaler/spec/${autoscaleType}/cluster`, - ) - } -} + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }, + ) -function initMetadata({ getValue, discriminator, model, commit, storeGet }) { - const dbName = - getValue(model, '/resources/autoscalingKubedbComKafkaAutoscaler/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/autoscalingKubedbComKafkaAutoscaler/metadata/name', - value: modifiedName, - force: true, - }) + const secrets = (resp && resp.data && resp.data.items) || [] - // delete the other type object from model - if (type === 'compute') - commit('wizard/model$delete', '/resources/autoscalingKubedbComKafkaAutoscaler/spec/storage') - if (type === 'storage') - commit('wizard/model$delete', '/resources/autoscalingKubedbComKafkaAutoscaler/spec/compute') -} + const filteredSecrets = secrets.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) -function onNamespaceChange({ model, getValue, commit }) { - const namespace = getValue( - model, - '/resources/autoscalingKubedbComKafkaAutoscaler/metadata/namespace', - ) - if (!namespace) { - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComKafkaAutoscaler/spec/databaseRef/name', - ) + 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 [] + } } -} -function ifScalingTypeEqualsTo( - { storeGet, watchDependency, getValue, discriminator, model }, - type, -) { - watchDependency('discriminator#/autoscalingType') - watchDependency('model#/resources/autoscalingKubedbComKafkaAutoscaler/spec/databaseRef/name') - - const operation = storeGet('/route/params/actions') || '' - if (operation.length) { - const splitOp = operation.split('-') - if (splitOp.length > 2) autoscaleType = splitOp[2] - } else autoscaleType = getValue(discriminator, '/autoscalingType') || '' - const isDatabaseSelected = !!getValue( - model, - '/resources/autoscalingKubedbComKafkaAutoscaler/spec/databaseRef/name', - ) - return autoscaleType === type && isDatabaseSelected -} + 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/kubedbComKafka/spec/monitor/prometheus/exporter/env/${index}/valueFrom/secretKeyRef/name`, + ) -async function fetchNodeTopology({ axios, storeGet }) { - 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 [] -} + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/secretKeyRef/name') -function isNodeTopologySelected({ watchDependency, model, getValue }) { - watchDependency( - 'model#/resources/autoscalingKubedbComKafkaAutoscaler/spec/compute/nodeTopology/name', - ) - const nodeTopologyName = - getValue( - model, - '/resources/autoscalingKubedbComKafkaAutoscaler/spec/compute/nodeTopology/name', - ) || '' - return !!nodeTopologyName.length -} + if (!secretName) return [] -function setControlledResources({ commit }, type) { - const list = ['cpu', 'memory'] - const path = `/resources/autoscalingKubedbComKafkaAutoscaler/spec/compute/${type}/controlledResources` - commit('wizard/model$update', { - path: path, - value: list, - force: true, - }) - return list -} + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets/${secretName}`, + ) -function setTrigger({ model, getValue }, path) { - let value = getValue(model, `/resources/${path}`) - if (value) return value - return 'On' -} + const secret = (resp && resp.data && resp.data.data) || {} -function setApplyToIfReady() { - return 'IfReady' -} + const secretKeys = Object.keys(secret).map((item) => ({ + text: item, + value: item, + })) -function handleUnit({ commit, model, getValue }, 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, - }) + return secretKeys + } catch (e) { + console.log(e) + return [] } } -} -function isBindingAlreadyOn({ model, getValue }) { - const value = getValue(model, '/resources') - const keys = Object.keys(value) - isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComKafkaBinding') - return isExposeBinding -} + function isBindingAlreadyOn() { + const value = getValue(model, '/resources') + const keys = Object.keys(value) + const isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComKafkaBinding') + return isExposeBinding + } -async function addOrRemoveBinding({ commit, model, getValue, discriminator }) { - const value = getValue(discriminator, `/binding`) - const dbName = getValue(model, '/metadata/release/name') - const dbNamespace = getValue(model, '/metadata/release/namespace') - const labels = getValue(model, '/resources/kubedbComKafka/metadata/labels') - const bindingValues = { - apiVersion: 'catalog.appscode.com/v1alpha1', - kind: 'KafkaBinding', - metadata: { - labels, - name: dbName, - namespace: dbNamespace, - }, - spec: { - sourceRef: { + 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/kubedbComKafka/metadata/labels') + const bindingValues = { + apiVersion: 'catalog.appscode.com/v1alpha1', + kind: 'KafkaBinding', + metadata: { + labels, name: dbName, namespace: dbNamespace, }, - }, - } + spec: { + sourceRef: { + name: dbName, + namespace: dbNamespace, + }, + }, + } - if (value) { - await commit('wizard/model$update', { - path: '/resources/catalogAppscodeComKafkaBinding', - value: bindingValues, - force: true, - }) - } else { - await commit('wizard/model$delete', '/resources/catalogAppscodeComKafkaBinding') + if (value) { + commit('wizard/model$update', { + path: '/resources/catalogAppscodeComKafkaBinding', + value: bindingValues, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/catalogAppscodeComKafkaBinding') + } } -} - -/****** Monitoring *********/ - -function showCustomizeExporterSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/customizeExporter') - const configureStatus = getValue(discriminator, '/customizeExporter') - return configureStatus -} -function onCustomizeExporterChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/customizeExporter') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComKafka/spec/monitor/prometheus/exporter', - value: {}, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComKafka/spec/monitor/prometheus/exporter') + function returnFalse() { + return false } -} - -async function fetchTopologyMachines({ axios, getValue, storeGet, model, setDiscriminatorValue }) { - const instance = hasAnnotations({ model, getValue }) - - 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 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 setAllowedMachine({ model, getValue }, type, minmax) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComKafkaAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - let parsedInstance = {} - try { - if (instance) parsedInstance = JSON.parse(instance) - } catch (e) { - console.log(e) - parsedInstance = {} + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found } - const machine = parsedInstance[type] || '' - const mx = machine?.includes(',') ? machine.split(',')[1] : '' - const mn = machine?.includes(',') ? machine.split(',')[0] : '' - - if (minmax === 'min') return mn - else return mx -} - -async function getMachines({ getValue, watchDependency, discriminator }, type, minmax) { - watchDependency('discriminator#/topologyMachines') - const depends = minmax === 'min' ? 'max' : 'min' - const dependantPath = `/allowedMachine-${type}-${depends}` - - watchDependency(`discriminator#${dependantPath}`) - const dependantMachine = getValue(discriminator, dependantPath) - - const nodeGroups = getValue(discriminator, '/topologyMachines') || [] - - const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) - - const machines = nodeGroups?.map((item) => { - const subText = `CPU: ${item.allocatable.cpu}, Memory: ${item.allocatable.memory}` - const text = item.topologyValue - return { text, subText, value: item.topologyValue } - }) - - const filteredMachine = machines?.filter((item, ind) => - minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, - ) - - return dependantIndex === -1 ? machines : filteredMachine -} - -function hasAnnotations({ model, getValue }, type) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComKafkaAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - - return !!instance -} + function setValueFromDbDetails(path) { + const value = getValue(model, path) + return value + } -function hasNoAnnotations({ model, getValue }) { - return !hasAnnotations({ model, getValue }) -} + 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 + }) -function onMachineChange({ model, getValue, discriminator, commit }, type) { - const annoPath = '/resources/autoscalingKubedbComKafkaAutoscaler/metadata/annotations' - const annotations = getValue(model, annoPath) - const instance = annotations['kubernetes.io/instance-type'] - let parsedInstance = {} - try { - if (instance) parsedInstance = JSON.parse(instance) - } catch (e) { - console.log(e) - parsedInstance = {} + if (filteredEnv.length) + commit('wizard/model$update', { + path: '/resources/kubedbComKafka/spec/monitor/prometheus/exporter/env', + value: filteredEnv, + force: true, + }) } - const minMachine = getValue(discriminator, `/allowedMachine-${type}-min`) - const maxMachine = getValue(discriminator, `/allowedMachine-${type}-max`) - const minMaxMachine = `${minMachine},${maxMachine}` + function initEnvArray() { + const env = getValue(model, '/resources/kubedbComKafka/spec/monitor/prometheus/exporter/env') - parsedInstance[type] = minMaxMachine - const instanceString = JSON.stringify(parsedInstance) - annotations['kubernetes.io/instance-type'] = instanceString + return env || [] + } - const machines = getValue(discriminator, `/topologyMachines`) || [] - const minMachineObj = machines.find((item) => item.topologyValue === minMachine) - const maxMachineObj = machines.find((item) => item.topologyValue === maxMachine) - const minMachineAllocatable = minMachineObj?.allocatable - const maxMachineAllocatable = maxMachineObj?.allocatable - const allowedPath = `/resources/autoscalingKubedbComKafkaAutoscaler/spec/compute/${type}` + function isEqualToTemp(value, index) { + //watchDependency('discriminator#/valueFromType') + const valueFrom = getValue(discriminator, `/env/${index}/temp/valueFromType`) + return valueFrom === value + } - if (minMachine && maxMachine && instance !== instanceString) { - 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 initMonitoring() { + const env = + getValue(model, '/resources/kubedbComKafka/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 { - onCustomizeExporterChange, - showCustomizeExporterSection, - isRancherManaged, - handleUnit, - isConsole, - getNamespaces, - getDbs, - isKubedb, - getDbDetails, - dbTypeEqualsTo, - clearSpecModel, - initMetadata, - onNamespaceChange, - ifScalingTypeEqualsTo, - fetchNodeTopology, - isNodeTopologySelected, - setControlledResources, - setTrigger, - setApplyToIfReady, - showOpsRequestOptions, - isVariantAvailable, - fetchJsons, - disableLableChecker, - isEqualToModelPathValue, - getResources, - isEqualToDiscriminatorPath, - setValueFromModel, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - returnTrue, - returnStringYes, - isDedicatedModeSelected, - isCombinedModeSelected, - isDiscriminatorEqualTo, - getKafkaVersions, - isSecurityEnabled, - onDisableSecurityChange, - onEnableSSLChange, - removeCertificatesOfAliases, - setDatabaseMode, - getStorageClassNames, - getStorageClassNamesFromDiscriminator, - deleteDatabaseModePath, - isEqualToDatabaseMode, - setApiGroup, - setApiGroupEdit, - getIssuerRefsName, - hasIssuerRefName, - hasNoIssuerRefName, - setClusterAuthMode, - setSSLMode, - showTlsConfigureSection, - onTlsConfigureChange, - showTlsRecommendation, - getAliasOptions, - showMonitoringSection, - onEnableMonitoringChange, - isValueExistInModel, - onNamespaceChange, - onLabelChange, - onNameChange, - returnFalse, - onAgentChange, - getCreateAuthSecret, - showExistingSecretSection, - showPasswordSection, - encodePassword, - decodePassword, - onCreateAuthSecretChange, - setAuthSecretPassword, - onAuthSecretPasswordChange, - showSecretSection, - getSecrets, - isEqualToServiceMonitorType, - onConfigurationSourceChange, - setConfigurationSource, - setConfigFiles, - onConfigFilesChange, - onSetCustomConfigChange, - initSetCustomConfig, - getOpsRequestUrl, - getCreateNameSpaceUrl, - setStorageClass, - isBindingAlreadyOn, - addOrRemoveBinding, - getMachines, - setAllowedMachine, - hasAnnotations, - hasNoAnnotations, - fetchTopologyMachines, - onMachineChange, + return { + isKubedb, + isConsole, + getDbDetails, + initMetadata, + fetchTopologyMachines, + dbTypeEqualsTo, + setTrigger, + hasAnnotations, + setAllowedMachine, + getMachines, + onMachineChange, + hasNoAnnotations, + setControlledResources, + showOpsRequestOptions, + setApplyToIfReady, + getNamespaces, + fetchNodeTopology, + isNodeTopologySelected, + getDbs, + + handleUnit, + isRancherManaged, + + getOpsRequestUrl, + isValueExistInModel, + onEnableMonitoringChange, + showMonitoringSection, + onAgentChange, + getResources, + isEqualToModelPathValue, + onCustomizeExporterChange, + showCustomizeExporterSection, + onNamespaceChange, + onLabelChange, + setValueFrom, + onValueFromChange, + resourceNames, + getConfigMapKeys, + getSecrets, + getSecretKeys, + isConfigMapTypeValueFrom, + isSecretTypeValueFrom, + getNamespacedResourceList, + onEnvArrayChange, + initEnvArray, + isEqualToTemp, + initMonitoring, + + isBindingAlreadyOn, + addOrRemoveBinding, + returnFalse, + + setValueFromDbDetails, + } } diff --git a/charts/kubedbcom-mariadb-editor-options/ui/create-ui.yaml b/charts/kubedbcom-mariadb-editor-options/ui/create-ui.yaml index 17b1b14132..b1161f744c 100644 --- a/charts/kubedbcom-mariadb-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-mariadb-editor-options/ui/create-ui.yaml @@ -1,378 +1,383 @@ -steps: -- form: - discriminator: - bundleApiLoaded: - default: false - type: boolean +step: +- type: single-step-form + loader: initBundle + elements: + - type: label-element + label: '' + subtitle: Select the MariaDB version you want to deploy on Kubernetes. The chosen version determines the MariaDB engine features, compatibility, and runtime behavior of your database cluster. + - disableUnselect: true + loader: getAdminOptions|databases/MariaDB/versions + if: + type: function + name: isToggleOn|databases/MariaDB/versions + label: Database version + schema: schema/properties/spec/properties/admin/properties/databases/properties/MariaDB/properties/versions/properties/default + type: select + - init: + type: func + value: getDefault|databases/MariaDB/mode + loader: getAdminOptions|databases/MariaDB/mode + if: + type: function + name: isToggleOn|databases/MariaDB/mode + label: Database mode + isHorizontal: true + schema: schema/properties/spec/properties/mode + type: radio + - if: + type: function + name: EqualToDatabaseMode|Replicaset + label: Replicas + schema: schema/properties/spec/properties/replicas + type: input + - elements: + - type: label-element + label: '' + subtitle: Select a machine profile to allocate CPU and memory resources for your database cluster. Choose 'custom' to manually specify resource requirements or select a predefined profile. + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: CPU + loader: setLimits|cpu + watcher: + func: setRequests|cpu + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: Memory + loader: setLimits|memory + watcher: + func: setRequests|memory + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + label: Machine Profile + showLabels: true + type: block-layout + - elements: + - type: horizontal-layout + showLabels: true + elements: + - loader: getAdminOptions|storageClasses + if: + type: function + name: isToggleOn|storageClasses + label: Storage Class + schema: schema/properties/spec/properties/admin/properties/storageClasses/properties/default + type: select + - label: Storage Size + schema: schema/properties/spec/properties/persistence/properties/size + type: input + type: block-layout + - description: Configure Credentials, Deployment Mode etc. elements: - - computed: initBundle - if: returnFalse - type: label-element - - disableUnselect: true - fetch: getAdminOptions|databases/MariaDB/versions - if: isToggleOn|databases/MariaDB/versions - label: - text: labels.database.version - schema: - $ref: schema#/properties/spec/properties/admin/properties/databases/properties/MariaDB/properties/versions/properties/default - type: select - - computed: getDefault|databases/MariaDB/mode - fetch: getAdminOptions|databases/MariaDB/mode - hasDescription: true - if: isToggleOn|databases/MariaDB/mode - label: - text: labels.database.mode - schema: - $ref: schema#/properties/spec/properties/mode - type: radio - - if: EqualToDatabaseMode|Replicaset - label: - text: labels.replicas - schema: - $ref: schema#/properties/spec/properties/replicas - type: input - elements: - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.cpu - onChange: setRequests|cpu - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.memory - onChange: setRequests|memory - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - label: - text: labels.machine_profile - show_label: true - type: single-step-form - - fetch: getAdminOptions|storageClasses - if: isToggleOn|storageClasses - label: - text: labels.storage.class - schema: - $ref: schema#/properties/spec/properties/admin/properties/storageClasses/properties/default + - type: label-element + label: '' + subtitle: Add custom labels and annotations to your database resources for organization, monitoring, and integration with other Kubernetes tools and services. + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/annotations + label: Labels & Annotations + showLabels: true + hideBlock: true + type: block-layout + - init: + type: func + value: getDefault|deletionPolicy + customClass: mt-20 + if: + type: function + name: isToggleOn|deletionPolicy + label: Deletion Policy + watcher: + func: setStorageClass + paths: + - schema/properties/spec/properties/deletionPolicy + options: + - description: options.deletionPolicy.delete.description + text: Delete + value: Delete + - description: options.deletionPolicy.halt.description + text: Halt + value: Halt + - description: options.deletionPolicy.wipeOut.description + text: WipeOut + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: DoNotTerminate + value: DoNotTerminate + schema: schema/properties/spec/properties/deletionPolicy + type: select + - if: + type: function + name: getDefaultValue|spec/admin/authCredential/customize + label: Provide Authentication Credentials? + watcher: + func: onAuthChange + paths: + - temp/createAuthSecret + schema: temp/createAuthSecret + type: switch + - if: + type: function + name: showReferSecretSwitch + label: Refer existing Secret? + watcher: + func: onReferSecretChange + paths: + - temp/referSecret + schema: temp/referSecret + type: switch + - loader: getReferSecrets + if: + type: function + name: showSecretDropdown + label: Secret + schema: schema/properties/spec/properties/authSecret/properties/name type: select - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/persistence/properties/size + - if: + type: function + name: showReferSecret + label: password + schema: schema/properties/spec/properties/authSecret/properties/password type: input - - accordion: true - description: - text: Configure Credentials, Deployment Mode etc. - discriminator: - configDatabase: - default: false - type: boolean - createAuthSecret: - default: false - type: boolean - recovery: - default: false - type: boolean - referSecret: - default: false - type: boolean - elements: - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties + - if: + type: function + name: getDefaultValue|spec/admin/customConfiguration + label: Configure Database? + watcher: + func: clearConfiguration + paths: + - temp/configDatabase + schema: temp/configDatabase + type: switch + - if: + type: function + name: isConfigDatabaseOn + label: Configuration + # hasCopy: true + schema: schema/properties/spec/properties/configuration + type: textarea + - init: + type: func + value: getDefault|pointInTimeRecovery + if: + type: function + name: isToggleOn|pointInTimeRecovery + label: Point in-time Recovery? + schema: temp/recovery + type: switch + - elements: + - type: label-element + label: '' + subtitle: Configure point-in-time recovery to restore your database to a specific moment. Specify the source database namespace, name, and the exact timestamp for recovery. + - type: horizontal-layout + showLabels: true + elements: + - label: Namespace + watcher: + func: setPointInTimeRecovery + paths: + - temp/refNamespace + forceRequired: true + validation: + type: required + schema: temp/refNamespace type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties + - label: Name + watcher: + func: setPointInTimeRecovery + paths: + - temp/refDBName + validation: + type: required + schema: temp/refDBName type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - computed: getDefault|deletionPolicy - customClass: mt-20 - if: isToggleOn|deletionPolicy - 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/spec/properties/deletionPolicy - type: select - - if: getDefaultValue|spec/admin/authCredential/customize - label: - text: Provide Authentication Credentials? - onChange: onAuthChange - schema: - $ref: discriminator#/createAuthSecret - type: switch - - if: showReferSecretSwitch - label: - text: Refer existing Secret? - onChange: onReferSecretChange - schema: - $ref: discriminator#/referSecret + - customClass: mt-10 + label: Recovery Timestamp + schema: schema/properties/spec/properties/init/properties/archiver/properties/recoveryTimestamp + type: date-time + watcher: + func: onTimestampChange + paths: + - schema/properties/spec/properties/init/properties/archiver/properties/recoveryTimestamp + if: + type: function + name: showRecovery + label: Point in-time Recovery + showLabels: true + type: block-layout + - if: + type: function + name: isToggleOn|deployment + label: Deployment name + options: + - description: labels.deployment.shared + text: Shared + value: Shared + - description: labels.deployment.dedicated + text: Dedicated + value: Dedicated + schema: schema/properties/spec/properties/admin/properties/deployment/properties/default + type: radio + - if: + type: function + name: isToggleOn|clusterTier + isHorizontal: true + label: Cluster Tier + options: + - text: General Purpose + value: GeneralPurpose + - text: Memory Optimized + value: MemoryOptimized + - text: CPU Optimized + value: CPUOptimized + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/default + type: radio + - disableUnselect: true + loader: getAdminOptions|clusterTier/placement + if: + type: function + name: isToggleOn|clusterTier/placement + label: Placement + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + type: select + - disableUnselect: true + loader: getNodeTopology + if: + type: function + name: isToggleOn|clusterTier/nodeTopology + label: Node Topology + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + type: select + label: Advanced Configuration + showLabels: true + type: block-layout + - description: Enable Backup, Monitoring, TLS etc. + elements: + - elements: + - init: + type: func + value: setMonitoring + label: Enable Monitoring? + watcher: + func: updateAlertValue + paths: + - temp/monitoring + schema: temp/monitoring type: switch - - fetch: getReferSecrets - if: showSecretDropdown - label: - text: Secret - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/name + - customClass: mt-10 + if: + type: function + name: showAlerts + label: Alert Options + options: + - text: None + value: none + - text: Critical + value: critical + - text: Warning + value: warning + - text: Info + value: info + schema: schema/properties/form/properties/alert/properties/enabled type: select - - if: showReferSecret - label: - text: labels.password - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/password - type: input - - computed: isConfigAvailable - if: getDefaultValue|spec/admin/customConfiguration - label: - text: Configure Database? - onChange: clearConfiguration - schema: - $ref: discriminator#/configDatabase + if: + type: function + name: isToggleOn|monitoring + type: block-layout + - init: + type: func + value: setBackup + if: + type: function + name: isToggleOn|backup + label: Enable Backup? + watcher: + func: onBackupSwitch + paths: + - temp/backup + schema: temp/backup + type: switch + - elements: + - disable: showArchiverAlert + label: Enable Archiver? + watcher: + func: onArchiverChange + paths: + - schema/properties/spec/properties/admin/properties/archiver/properties/enable/properties/default + schema: schema/properties/spec/properties/admin/properties/archiver/properties/enable/properties/default type: switch - - if: isConfigDatabaseOn - label: - text: Configuration - schema: - $ref: schema#/properties/spec/properties/configuration - type: editor - - computed: getDefault|pointInTimeRecovery - if: isToggleOn|pointInTimeRecovery - label: - text: Point in-time Recovery? - schema: - $ref: discriminator#/recovery + - if: + type: function + name: showArchiverAlert + label: The selected StorageClass does not support Archiver + type: warning + if: + type: function + name: showArchiver + type: block-layout + - elements: + - label: Enable TLS? + schema: schema/properties/spec/properties/admin/properties/tls/properties/default type: switch - - discriminator: - refDBName: - type: string - refNamespace: - type: string - elements: - - label: - text: Namespace - onChange: setPointInTimeRecovery - required: true - schema: - $ref: discriminator#/refNamespace - type: input - - label: - text: Name - onChange: setPointInTimeRecovery - required: true - schema: - $ref: discriminator#/refDBName - type: input - - customClass: mt-10 - label: - text: Recovery Timestamp - schema: - $ref: schema#/properties/spec/properties/init/properties/archiver/properties/recoveryTimestamp - type: input - if: showRecovery - label: - text: Point in-time Recovery - schema: - $ref: schema#/properties/spec/properties/init/properties/archiver - show_label: true - type: single-step-form - - hasDescription: true - if: isToggleOn|deployment - label: - text: labels.deployment.name - options: - - description: labels.deployment.shared - text: Shared - value: Shared - - description: labels.deployment.dedicated - text: Dedicated - value: Dedicated - schema: - $ref: schema#/properties/spec/properties/admin/properties/deployment/properties/default - type: radio - - if: isToggleOn|clusterTier - isHorizontal: true - label: - text: labels.clusterTier - options: - - text: General Purpose - value: GeneralPurpose - - text: Memory Optimized - value: MemoryOptimized - - text: CPU Optimized - value: CPUOptimized - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/default - type: radio - - disableUnselect: true - fetch: getAdminOptions|clusterTier/placement - if: isToggleOn|clusterTier/placement - label: - text: labels.placement - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default - type: select - - disableUnselect: true - fetch: getNodeTopology - if: isToggleOn|clusterTier/nodeTopology - label: - text: labels.nodeTopology - refresh: true - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + - loader: getAdminOptions|clusterIssuers + if: + type: function + name: showIssuer + label: Cluster Issuers + validation: + type: required + schema: schema/properties/spec/properties/admin/properties/clusterIssuers/properties/default type: select - hideForm: true - label: - text: Advanced Configuration - show_label: true - type: single-step-form - - accordion: true - description: - text: Enable Backup, Monitoring, TLS etc. - discriminator: - backup: - default: false - type: boolean - elements: - - discriminator: - monitoring: - default: false - type: boolean - elements: - - computed: setMonitoring - label: - text: labels.enable_monitoring - onChange: updateAlertValue - schema: - $ref: discriminator#/monitoring - type: switch - - customClass: mt-10 - if: showAlerts - label: - text: labels.alert.options - options: - - text: None - value: none - - text: Critical - value: critical - - text: Warning - value: warning - - text: Info - value: info - schema: - $ref: schema#/properties/form/properties/alert/properties/enabled - sortable: true - type: select - if: isToggleOn|monitoring - type: single-step-form - - computed: setBackup - if: isToggleOn|backup - label: - text: Enable Backup? - onChange: onBackupSwitch - schema: - $ref: discriminator#/properties/backup + if: + type: function + name: isToggleOn|tls + type: block-layout + - elements: + - label: Expose via Gateway? + schema: schema/properties/spec/properties/admin/properties/expose/properties/default type: switch - - elements: - - disabled: showArchiverAlert - label: - text: Enable Archiver? - onChange: onArchiverChange - schema: - $ref: schema#/properties/spec/properties/admin/properties/archiver/properties/enable/properties/default - type: switch - - alertInfo: - show: true - type: neutral - if: showArchiverAlert - label: - text: The selected StorageClass does not support Archiver - type: label-element - if: showArchiver - type: single-step-form - - elements: - - label: - text: Enable TLS? - schema: - $ref: schema#/properties/spec/properties/admin/properties/tls/properties/default - type: switch - - fetch: getAdminOptions|clusterIssuers - if: showIssuer - label: - text: labels.clusterIssuers - required: true - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterIssuers/properties/default - type: select - if: isToggleOn|tls - type: single-step-form - - elements: - - label: - text: Expose via Gateway? - schema: - $ref: schema#/properties/spec/properties/admin/properties/expose/properties/default - type: switch - if: isToggleOn|expose - type: single-step-form - if: showAdditionalSettings - label: - text: Additional Options - show_label: true - type: single-step-form - type: single-step-form + if: + type: function + name: isToggleOn|expose + type: block-layout + if: + type: function + name: showAdditionalSettings + label: Additional Options + showLabels: true + type: block-layout id: options - title: steps.0.label type: multi-step-form diff --git a/charts/kubedbcom-mariadb-editor-options/ui/functions.js b/charts/kubedbcom-mariadb-editor-options/ui/functions.js index 3d2f49511d..9e7dc5ac10 100644 --- a/charts/kubedbcom-mariadb-editor-options/ui/functions.js +++ b/charts/kubedbcom-mariadb-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -315,1059 +317,1152 @@ const modeDetails = { }, } -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) + + setDiscriminatorValue('bundleApiLoaded', false) + setDiscriminatorValue('configDatabase', false) + setDiscriminatorValue('createAuthSecret', false) + setDiscriminatorValue('recovery', false) + setDiscriminatorValue('referSecret', false) + setDiscriminatorValue('refDBName', '') + setDiscriminatorValue('refNamespace', '') + setDiscriminatorValue('backup', false) + setDiscriminatorValue('monitoring', false) + + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, }, - }, - ) - const projects = resp?.data?.status?.projects - if (projects) { - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - namespaces = projectsNamespace - } else { - namespaces = resp?.data?.status?.namespaces || [] + ) + const projects = resp?.data?.status?.projects + if (projects) { + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + namespaces = projectsNamespace + } else { + namespaces = resp?.data?.status?.namespaces || [] + } + return namespaces + } catch (e) { + console.log(e) + return [] } - return namespaces - } catch (e) { - console.log(e) - return [] } -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } -function showRecovery({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/recovery') - const isRecoveryOn = getValue(discriminator, '/recovery') || '' - return isRecoveryOn -} + function showRecovery() { + // watchDependency('discriminator#/recovery') + const isRecoveryOn = getValue(discriminator, '/recovery') || '' + return isRecoveryOn + } -function getMachineListForOptions({ model, getValue }) { - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') let array = [] + function getMachineListForOptions() { + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') - if (available.length) { - array = available.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - else { - let subText = '', - text = '' - const machineData = machinesFromPreset.find((val) => val.id === machine) - if (machineData) { - subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` - text = machineData.name ? machineData.name : machineData.id - } - return { text, subText, value: machine } - } - }) - } else { - array = machineList - .map((machine) => { + if (available.length) { + array = available.map((machine) => { if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + else { + let subText = '', + text = '' + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + text = machineData.name ? machineData.name : machineData.id + } + return { text, subText, value: machine } + } }) - .filter((val) => !!val) + } else { + array = machineList + .map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { text, subText, value: machine } + }) + .filter((val) => !!val) + } + return array } - return array -} -function setLimits({ model, getValue, commit, watchDependency }, resource, type) { - const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' - watchDependency(`model#${path}`) - const selectedMachine = getValue(model, path) || 'custom' - const reqCommitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - const comparePath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - - const resourceValue = getValue(model, comparePath) - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - - let cpu = '', - memory = '' - if (available.length && selectedMachine !== 'custom') { - const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) - if (machineData) { - cpu = machineData.limits.cpu - memory = machineData.limits.memory + function setLimits(resource, type) { + const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' + // watchDependency(`model#${path}`) + const selectedMachine = getValue(model, path) || 'custom' + const reqCommitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + const comparePath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + + const resourceValue = getValue(model, comparePath) + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + let cpu = '', + memory = '' + if (available.length && selectedMachine !== 'custom') { + const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) + if (machineData) { + cpu = machineData.limits.cpu + memory = machineData.limits.memory + } + } else { + if (selectedMachine === 'custom') { + cpu = resourceValue + memory = resourceValue + } else { + cpu = machines[selectedMachine].resources.limits.cpu + memory = machines[selectedMachine].resources.limits.memory + } } - } else { - if (selectedMachine === 'custom') { - cpu = resourceValue - memory = resourceValue + + if (resource === 'memory') { + commit('wizard/model$update', { + path: reqCommitPath, + value: memory, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: memory, + force: true, + }) + return memory } else { - cpu = machines[selectedMachine].resources.limits.cpu - memory = machines[selectedMachine].resources.limits.memory + commit('wizard/model$update', { + path: reqCommitPath, + value: cpu, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: cpu, + force: true, + }) + return cpu } } - if (resource === 'memory') { + function setRequests(resource, type) { + const modelPath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + + const fullpath = `/spec/podResources/machine` + const modelPathValue = getValue(model, fullpath) + commit('wizard/model$update', { - path: reqCommitPath, - value: memory, + path: commitPath, + value: val, force: true, }) - commit('wizard/model$update', { - path: comparePath, - value: memory, - force: true, + + if (modelPathValue === 'custom') { + return + } + let commitCpuMemory, ModelPathValue + if (resource && type) { + const fullPath = `/spec/${type}/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/${type}/podResources/resources/requests/${resource}` + } else { + const fullPath = `/spec/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/podResources/resources/requests/${resource}` + } + let cpuMemoryValue + array.forEach((item) => { + if (item.value === ModelPathValue) { + // Parse subText like "CPU: 2, Memory: 2Gi" + const subText = item.subText || '' + if (resource === 'cpu') { + // Extract CPU value + const cpuMatch = subText.match(/CPU:\s*([^,]+)/) + cpuMemoryValue = cpuMatch ? cpuMatch[1].trim() : '' + } else if (resource === 'memory') { + // Extract Memory value + const memoryMatch = subText.match(/Memory:\s*(.+)/) + cpuMemoryValue = memoryMatch ? memoryMatch[1].trim() : '' + } + } }) - return memory - } else { commit('wizard/model$update', { - path: reqCommitPath, - value: cpu, + path: commitCpuMemory, + value: cpuMemoryValue, force: true, }) + return cpuMemoryValue + } + + function setRequests(resource) { + const modelPath = `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + commitPath = `/spec/podResources/resources/limits/${resource}` commit('wizard/model$update', { - path: comparePath, - value: cpu, + path: commitPath, + value: val, force: true, }) - return cpu } -} - -function setRequests({ getValue, model, commit }, resource) { - const modelPath = `/spec/podResources/resources/requests/${resource}` - const val = getValue(model, modelPath) - commitPath = `/spec/podResources/resources/limits/${resource}` - commit('wizard/model$update', { - path: commitPath, - value: val, - force: true, - }) -} -function setMachineToCustom({ getValue, model }) { - const machine = getValue(model, '/spec/admin/machineProfiles/default') - return machine || 'custom' -} - -function isMachineCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue === 'custom' -} + function setMachineToCustom() { + const machine = getValue(model, '/spec/admin/machineProfiles/default') + return machine || 'custom' + } -function isMachineNotCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue !== 'custom' && !!modelPathValue -} + function isMachineCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue === 'custom' + } -function showMonitoringSection({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/monitoringEnabledStatus') - return !!getValue(discriminator, '/monitoringEnabledStatus') -} + function isMachineNotCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue !== 'custom' && !!modelPathValue + } -function setMonitoringStatus({ model, getValue }) { - const status = getValue(model, '/spec/monitoring/agent') - return !!status -} + function updateAlertValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const alert = isMonitorEnabled ? 'warning' : 'none' + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: alert, + force: true, + }) + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: agent, + force: true, + }) + } -function updateAlertValue({ commit, model, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const alert = isMonitorEnabled ? 'warning' : 'none' - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: alert, - force: true, - }) - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} + function getCreateNameSpaceUrl() { + const user = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } + } - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + const ifCapiProviderIsNotEmpty = () => { + // watchDependency('model#/form/capi/provider') + const val = getValue(model, '/form/capi/provider') + if (val) return true } -} -const ifCapiProviderIsNotEmpty = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/provider') - const val = getValue(model, '/form/capi/provider') - if (val) return true -} -const showMultiselectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') + const showMultiselectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') - if (val === 'capz' && ifDedicated({ model, getValue })) return true -} + if (val === 'capz' && ifDedicated()) return true + } -const showSelectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') - if (val !== 'capz' && ifDedicated({ model, getValue })) return true -} + const showSelectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') + if (val !== 'capz' && ifDedicated()) return true + } -const ifDedicated = ({ model, getValue }) => { - const val = getValue(model, 'form/capi/dedicated') - if (val) return true -} + const ifDedicated = () => { + const val = getValue(model, 'form/capi/dedicated') + if (val) return true + } -const dedicatedOnChange = ({ model, getValue, commit }) => { - const val = getValue(model, 'form/capi/dedicated') - if (!val) { - commit('wizard/model$delete', 'form/capi/zones') - commit('wizard/model$delete', 'form/capi/sku') + const dedicatedOnChange = () => { + const val = getValue(model, 'form/capi/dedicated') + if (!val) { + commit('wizard/model$delete', 'form/capi/zones') + commit('wizard/model$delete', 'form/capi/sku') + } } -} -const ifZones = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/zones') - watchDependency('model#/form/capi/dedicated') - const zones = getValue(model, 'form/capi/zones') || [] - const isDedicated = getValue(model, 'form/capi/dedicated') - if (zones.length && isDedicated) return true -} + const ifZones = () => { + // watchDependency('model#/form/capi/zones') + // watchDependency('model#/form/capi/dedicated') + const zones = getValue(model, 'form/capi/zones') || [] + const isDedicated = getValue(model, 'form/capi/dedicated') + if (zones.length && isDedicated) return true + } -const zonesOnChange = ({ model, getValue, commit }) => { - const zones = getValue(model, 'form/capi/zones') || [] - if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') -} + const zonesOnChange = () => { + const zones = getValue(model, 'form/capi/zones') || [] + if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') + } -async function getZones({ storeGet, axios, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const isDedicated = getValue(model, 'form/capi/dedicated') - if (isDedicated) { - try { - const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) - const val = resp.data.map((item) => { - return { value: item, text: item } - }) - return val - } catch (e) { - console.log(e) - return [] + async function getZones() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const isDedicated = getValue(model, 'form/capi/dedicated') + if (isDedicated) { + try { + const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) + const val = resp.data.map((item) => { + return { value: item, text: item } + }) + return val + } catch (e) { + console.log(e) + return [] + } } } -} -async function getSKU({ storeGet, axios, model, getValue, watchDependency }) { - watchDependency('model#/form/capi/zones') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const zones = getValue(model, 'form/capi/zones') || [] - if (zones.length) { - try { - let url = `clustersv2/${owner}/${cluster}/vms?` - if (typeof zones === 'string') { - url += `zones=${encodeURIComponent(zones)}` - } else { - zones.forEach((item) => { - url += `zones=${encodeURIComponent(item)}&` + async function getSKU() { + // watchDependency('model#/form/capi/zones') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const zones = getValue(model, 'form/capi/zones') || [] + if (zones.length) { + try { + let url = `clustersv2/${owner}/${cluster}/vms?` + if (typeof zones === 'string') { + url += `zones=${encodeURIComponent(zones)}` + } else { + zones.forEach((item) => { + url += `zones=${encodeURIComponent(item)}&` + }) + url = url.slice(0, -1) + } + const resp = await axios.get(url) + const val = resp.data.map((item) => { + return { + value: item.name, + text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb]`, + } }) - url = url.slice(0, -1) + return val + } catch (e) { + console.log(e) + return [] } - const resp = await axios.get(url) - const val = resp.data.map((item) => { - return { - value: item.name, - text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, - } - }) - return val - } catch (e) { - console.log(e) - return [] } } -} - -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} - -function setStorageClass({ model, getValue, commit, discriminator, watchDependency }) { - const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' - let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' - const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] - const suffix = '-retain' - const simpleClassList = storageClassList.filter((item) => { - return !item.endsWith(suffix) - }) - - const retainClassList = storageClassList.filter((item) => { - return item.endsWith(suffix) - }) - - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] - } else { - storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false } - const isChangeable = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'storageClasses', - ) - if (isChangeable && storageClass) { - commit('wizard/model$update', { - path: '/spec/admin/storageClasses/default', - value: storageClass, - force: true, + function setStorageClass() { + const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' + let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' + const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] + const suffix = '-retain' + + const simpleClassList = storageClassList.filter((item) => { + return !item.endsWith(suffix) }) - } -} + const retainClassList = storageClassList.filter((item) => { + return item.endsWith(suffix) + }) + + if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { + storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] + } else { + storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + } -let placement = [] -let versions = [] -let storageClass = [] -let clusterIssuers = [] -let nodetopologiesShared = [] -let nodetopologiesDedicated = [] -let features = [] -let namespaces = [] -async function initBundle({ commit, model, getValue, axios, storeGet, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - - let db = getValue(model, '/metadata/resource/kind') - db = db.toLowerCase() - let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` - const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - try { - const resp = await axios.get(url) - features = resp.data.features || [] - placement = resp.data.placementpolicies || [] - versions = resp.data.versions || [] - storageClass = resp.data.storageclasses || [] - clusterIssuers = resp.data.clusterissuers || [] - nodetopologiesDedicated = resp.data.dedicated || [] - nodetopologiesShared = resp.data.shared || [] - const response = await axios.get(annotationUrl) - const annotations = response.data?.metadata?.annotations || {} - const uidRange = annotations['openshift.io/sa.scc.uid-range'] - if (uidRange) { - const val = uidRange.split('/')[0] + const isChangeable = isToggleOn('storageClasses') + if (isChangeable && storageClass) { commit('wizard/model$update', { - path: '/spec/openshift/securityContext/runAsUser', - value: val, + path: '/spec/admin/storageClasses/default', + value: storageClass, force: true, }) } - } catch (e) { - console.log(e) } - commit('wizard/model$update', { - path: '/spec/deletionPolicy', - value: getDefault({ getValue, model }, 'deletionPolicy'), - force: true, - }) - - if (!getValue(model, `/spec/admin/databases/MariaDB/mode/toggle`)) { - let defMode = getDefault({ getValue, model }, 'databases/MariaDB/mode') || '' - if (defMode === '') { - const arr = getValue(model, '/spec/databases/MariaDB/mode/available') || [] - if (arr.length) defMode = arr[0] - } - commit('wizard/model$update', { - path: '/spec/mode', - value: defMode, - force: true, - }) + function EqualToDatabaseMode(mode) { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + return modelPathValue && modelPathValue === mode } - if (!features.includes('tls')) { - commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: false, - force: true, - }) - } - if (!features.includes('binding')) { - commit('wizard/model$update', { - path: '/spec/admin/expose/default', - value: false, - force: true, - }) + function isConfigDatabaseOn() { + // watchDependency('discriminator#/configDatabase') + return getValue(discriminator, '/configDatabase') } - if (!features.includes('monitoring')) { - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: 'none', - force: true, - }) - } - if (!features.includes('backup')) { - commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, - force: true, - }) - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: '', - force: true, - }) + + function clearConfiguration() { + const configOn = getValue(discriminator, '/configDatabase') + + if (!configOn) { + commit('wizard/model$delete', '/spec/configuration') + } } - namespaces = getNamespaces({ axios, storeGet }) - setDiscriminatorValue('/bundleApiLoaded', true) -} -function fetchNamespaces({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return namespaces -} + function returnFalse() { + return false + } -async function getRecoveryNames({ getValue, model, watchDependency, storeGet, axios }, type) { - watchDependency(`model#/spec/init/archiver/${type}/namespace`) - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/spec/init/archiver/${type}/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${namespace}/repositories` - if (type === 'encryptionSecret') - url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - const options = [] - if (namespace) { + let placement = [] + let versions = [] + let storageClass = [] + let clusterIssuers = [] + let nodetopologiesShared = [] + let nodetopologiesDedicated = [] + let features = [] + let namespaces = [] + async function initBundle() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + + let db = getValue(model, '/metadata/resource/kind') + db = db.toLowerCase() + let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` + const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` try { const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) + features = resp.data.features || [] + placement = resp.data.placementpolicies || [] + versions = resp.data.versions || [] + storageClass = resp.data.storageclasses || [] + clusterIssuers = resp.data.clusterissuers || [] + nodetopologiesDedicated = resp.data.dedicated || [] + nodetopologiesShared = resp.data.shared || [] + const response = await axios.get(annotationUrl) + const annotations = response.data?.metadata?.annotations || {} + const uidRange = annotations['openshift.io/sa.scc.uid-range'] + if (uidRange) { + const val = uidRange.split('/')[0] + commit('wizard/model$update', { + path: '/spec/openshift/securityContext/runAsUser', + value: val, + force: true, + }) + } } catch (e) { console.log(e) } - } - return options -} - -function fetchOptions({ model, getValue, commit }, type) { - let kind = getValue(model, '/metadata/resource/kind') - - let returnArray = [] - if (type === 'clusterTier/placement') { - returnArray = placement - } else if (type === `databases/${kind}/versions`) { - returnArray = versions - } else if (type === 'storageClasses') { - returnArray = storageClass - } else if (type === 'clusterIssuers') { - returnArray = clusterIssuers - } - if (returnArray.length === 1) { - const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: path, - value: returnArray[0], + path: '/spec/deletionPolicy', + value: getDefault('deletionPolicy'), force: true, }) + + if (!getValue(model, `/spec/admin/databases/MariaDB/mode/toggle`)) { + let defMode = getDefault('databases/MariaDB/mode') || '' + if (defMode === '') { + const arr = getValue(model, '/spec/databases/MariaDB/mode/available') || [] + if (arr.length) defMode = arr[0] + } + commit('wizard/model$update', { + path: '/spec/mode', + value: defMode, + force: true, + }) + } + + if (!features.includes('tls')) { + commit('wizard/model$update', { + path: '/spec/admin/tls/default', + value: false, + force: true, + }) + } + if (!features.includes('binding')) { + commit('wizard/model$update', { + path: '/spec/admin/expose/default', + value: false, + force: true, + }) + } + if (!features.includes('monitoring')) { + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: 'none', + force: true, + }) + } + if (!features.includes('backup')) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: '', + force: true, + }) + } + namespaces = getNamespaces() + setDiscriminatorValue('/bundleApiLoaded', true) } - return returnArray -} + function fetchNamespaces() { + // watchDependency('discriminator#/bundleApiLoaded') + return namespaces + } -let archiverMap = [] -let archiverCalled = false + async function getRecoveryNames(type) { + // watchDependency(`model#/spec/init/archiver/${type}/namespace`) + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/spec/init/archiver/${type}/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${namespace}/repositories` + if (type === 'encryptionSecret') + url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` + const options = [] + if (namespace) { + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + } + return options + } + + function fetchOptions(type) { + let kind = getValue(model, '/metadata/resource/kind') + + let returnArray = [] + if (type === 'clusterTier/placement') { + returnArray = placement + } else if (type === `databases/${kind}/versions`) { + returnArray = versions + } else if (type === 'storageClasses') { + returnArray = storageClass + } else if (type === 'clusterIssuers') { + returnArray = clusterIssuers + } -function getAdminOptions({ getValue, model, watchDependency, axios, storeGet, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') + if (returnArray.length === 1) { + const path = `/spec/admin/${type}/default` + commit('wizard/model$update', { + path: path, + value: returnArray[0], + force: true, + }) + } - if (type === 'storageClasses' && !archiverCalled) { - getArchiverName({ axios, storeGet }) + return returnArray } - const options = getValue(model, `/spec/admin/${type}/available`) || [] + let archiverMap = [] + let archiverCalled = false + + function getAdminOptions(type) { + // watchDependency('discriminator#/bundleApiLoaded') + + if (type === 'storageClasses' && !archiverCalled) { + getArchiverName() + } + + const options = getValue(model, `/spec/admin/${type}/available`) || [] - if (options.length === 0) { - return fetchOptions({ model, getValue, commit }, type) + if (options.length === 0) { + return fetchOptions(type) + } + if (type.endsWith('/mode')) { + return ( + options?.map((item) => ({ + description: modeDetails[item]?.description || '', + text: modeDetails[item]?.text || '', + value: item, + })) || [] + ) + } + return options } - if (type.endsWith('/mode')) { - return ( - options?.map((item) => ({ - description: modeDetails[item]?.description || '', - text: modeDetails[item]?.text || '', - value: item, - })) || [] - ) + + function showArchiver() { + return checkIfFeatureOn('archiver') } - return options -} -function showArchiver({ getValue, model }) { - return checkIfFeatureOn({ getValue, model }, 'archiver') -} + async function getArchiverName() { + try { + archiverCalled = true + const params = storeGet('/route/params') + const { user, cluster, group, resource } = params + const url = `/clusters/${user}/${cluster}/proxy/storage.k8s.io/v1/storageclasses` + const resp = await axios.get(url) -async function getArchiverName({ axios, storeGet }) { - try { - archiverCalled = true - const params = storeGet('/route/params') - const { user, cluster, group, resource } = params - const url = `/clusters/${user}/${cluster}/proxy/storage.k8s.io/v1/storageclasses` - const resp = await axios.get(url) - - resp.data?.items?.forEach((item) => { - const annotations = item.metadata?.annotations - const classname = item.metadata?.name - const annotationKeyToFind = `${resource}.${group}/archiver` - archiverMap.push({ storageClass: classname, annotation: annotations[annotationKeyToFind] }) - return resp.data - }) - } catch (e) { - console.log(e) + resp.data?.items?.forEach((item) => { + const annotations = item.metadata?.annotations + const classname = item.metadata?.name + const annotationKeyToFind = `${resource}.${group}/archiver` + archiverMap.push({ storageClass: classname, annotation: annotations[annotationKeyToFind] }) + return resp.data + }) + } catch (e) { + console.log(e) + } } -} -function onArchiverChange({ model, getValue, commit }) { - const isArchiverOn = getValue(model, '/spec/admin/archiver/enable/default') + function onArchiverChange() { + const isArchiverOn = getValue(model, '/spec/admin/archiver/enable/default') - const stClass = getValue(model, '/spec/admin/storageClasses/default') - const found = archiverMap.find((item) => item.storageClass === stClass) - const via = getValue(model, '/spec/admin/archiver/via') + const stClass = getValue(model, '/spec/admin/storageClasses/default') + const found = archiverMap.find((item) => item.storageClass === stClass) + const via = getValue(model, '/spec/admin/archiver/via') - if (!isArchiverOn) { - commit('wizard/model$update', { - path: '/spec/archiverName', - value: '', - force: true, - }) - } else { - if (via === 'VolumeSnapshotter') { + if (!isArchiverOn) { commit('wizard/model$update', { path: '/spec/archiverName', - value: found.annotation, + value: '', force: true, }) } else { - const kind = getValue(model, '/metadata/resource/kind') - commit('wizard/model$update', { - path: '/spec/archiverName', - value: kind.toLowerCase(), - force: true, - }) + if (via === 'VolumeSnapshotter') { + commit('wizard/model$update', { + path: '/spec/archiverName', + value: found.annotation, + force: true, + }) + } else { + const kind = getValue(model, '/metadata/resource/kind') + commit('wizard/model$update', { + path: '/spec/archiverName', + value: kind.toLowerCase(), + force: true, + }) + } } } -} -function showArchiverAlert({ watchDependency, model, getValue, commit }) { - watchDependency('model#/spec/admin/storageClasses/default') + function showArchiverAlert() { + // watchDependency('model#/spec/admin/storageClasses/default') - const mode = getValue(model, '/spec/mode') - if (mode === 'Standalone') return false + const mode = getValue(model, '/spec/mode') + if (mode === 'Standalone') return false - const via = getValue(model, '/spec/admin/archiver/via') - - if (via === 'VolumeSnapshotter') { - // toggle archiver to false when storageClass annotation not found - const stClass = getValue(model, '/spec/admin/storageClasses/default') - const found = archiverMap.find((item) => item.storageClass === stClass) - const show = !found?.annotation - if (show) { - commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, - force: true, - }) - return true - } else onArchiverChange({ model, getValue, commit }) - } else onArchiverChange({ model, getValue, commit }) - return false -} + const via = getValue(model, '/spec/admin/archiver/via') -function checkIfFeatureOn({ getValue, model }, type) { - let val = getValue(model, `/spec/admin/${type}/toggle`) - if (type === 'backup' || type === 'archiver') { - val = getValue(model, `/spec/admin/${type}/enable/toggle`) - } - const backupVal = getValue(model, '/spec/backup/tool') - - if (type === 'backup') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } else if (type === 'tls') { - return features.includes('tls') && val - } else if (type === 'expose') { - return features.includes('binding') && val - } else if (type === 'monitoring') { - return features.includes('monitoring') && val - } else if (type === 'archiver') { - return features.includes('backup') && val + if (via === 'VolumeSnapshotter') { + // toggle archiver to false when storageClass annotation not found + const stClass = getValue(model, '/spec/admin/storageClasses/default') + const found = archiverMap.find((item) => item.storageClass === stClass) + const show = !found?.annotation + if (show) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + return true + } else onArchiverChange() + } else onArchiverChange() + return false } -} -function isToggleOn({ getValue, model, discriminator, watchDependency, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') - watchDependency('model#/spec/admin/deployment/default') - const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') - let deploymentType = getValue(model, `/spec/admin/deployment/default`) - if (type === 'tls' || type === 'backup' || type === 'expose' || type === 'monitoring') { - return checkIfFeatureOn({ getValue, model }, type) - } else if ( - type === 'clusterTier' || - type === 'clusterTier/placement' || - type === 'clusterTier/nodeTopology' - ) { - if (deploymentType === 'Dedicated' && bundleApiLoaded) return true - else return false - } else if (type === 'deployment') { - const deploymentType = getValue(model, '/spec/admin/deployment/default') - if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { - commit('wizard/model$update', { - path: '/spec/admin/deployment/default', - value: 'Shared', - force: true, - }) + let backupToolInitialValue = '' + function checkIfFeatureOn(type) { + let val = getValue(model, `/spec/admin/${type}/toggle`) + if (type === 'backup' || type === 'archiver') { + val = getValue(model, `/spec/admin/${type}/enable/toggle`) } - return ( - getValue(model, `/spec/admin/${type}/toggle`) && - nodetopologiesDedicated.length && - bundleApiLoaded - ) - } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded -} + const backupVal = getValue(model, '/spec/backup/tool') + if (type === 'backup') { + if (backupToolInitialValue === '') { + backupToolInitialValue = + features.includes('backup') && backupVal === 'KubeStash' && val ? 'on' : 'off' + return features.includes('backup') && backupVal === 'KubeStash' && val + } else { + if (backupToolInitialValue === 'on') { + return true + } else { + return false + } + } + } else if (type === 'tls') { + return features.includes('tls') && val + } else if (type === 'expose') { + return features.includes('binding') && val + } else if (type === 'monitoring') { + return features.includes('monitoring') && val + } else if (type === 'archiver') { + return features.includes('backup') && val + } + } -async function getNodeTopology({ model, getValue, axios, storeGet, watchDependency }) { - watchDependency('model#/spec/admin/deployment/default') - watchDependency('model#/spec/admin/clusterTier/default') - const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' - const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' - let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + function isToggleOn(type) { + // watchDependency('discriminator#/bundleApiLoaded') + // watchDependency('model#/spec/admin/deployment/default') + const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') + let deploymentType = getValue(model, `/spec/admin/deployment/default`) + if (type === 'tls' || type === 'backup' || type === 'expose' || type === 'monitoring') { + return checkIfFeatureOn(type) + } else if ( + type === 'clusterTier' || + type === 'clusterTier/placement' || + type === 'clusterTier/nodeTopology' + ) { + if (deploymentType === 'Dedicated' && bundleApiLoaded) return true + else return false + } else if (type === 'deployment') { + const deploymentType = getValue(model, '/spec/admin/deployment/default') + if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + commit('wizard/model$update', { + path: '/spec/admin/deployment/default', + value: 'Shared', + force: true, + }) + } + return ( + getValue(model, `/spec/admin/${type}/toggle`) && + nodetopologiesDedicated.length && + bundleApiLoaded + ) + } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded + } - const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + async function getNodeTopology() { + // watchDependency('model#/spec/admin/deployment/default') + // watchDependency('model#/spec/admin/clusterTier/default') + const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' + const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' + let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] - if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared - else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' - const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) - return filteredList -} + if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared + else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + + const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) + return filteredList + } -function filterNodeTopology(list, tier, provider) { - // first filter the list from value that exists from the filtered list got from API - const filteredlist = list + function filterNodeTopology(list, tier, provider) { + // first filter the list from value that exists from the filtered list got from API + const filteredlist = list - // filter the list based on clusterTier - if (provider === 'EKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('c') - else if (tier === 'MemoryOptimized') return item.startsWith('r') - else return !item.startsWith('c') && !item.startsWith('r') - }) - } else if (provider === 'AKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - else - return ( - !(item.startsWith('f') || item.startsWith('fx')) && - !( + // filter the list based on clusterTier + if (provider === 'EKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('c') + else if (tier === 'MemoryOptimized') return item.startsWith('r') + else return !item.startsWith('c') && !item.startsWith('r') + }) + } else if (provider === 'AKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('e') || item.startsWith('eb') || item.startsWith('ec') || item.startsWith('m') || item.startsWith('d') ) - ) - }) - } else if (provider === 'GKE') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') - return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - else - return ( - !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && - !( + else + return ( + !(item.startsWith('f') || item.startsWith('fx')) && + !( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + ) + }) + } else if (provider === 'GKE') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') + return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('x4') || item.startsWith('m1') || item.startsWith('m2') || item.startsWith('m3') ) - ) - }) - } else return filteredlist -} + else + return ( + !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && + !( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + ) + }) + } else return filteredlist + } -function returnFalse() { - return false -} + function showAlerts() { + // watchDependency('discriminator#/monitoring') + const isMonitorEnabled = getValue(discriminator, '/monitoring') + return isMonitorEnabled && isToggleOn('alert') + } -function showAlerts({ watchDependency, model, getValue, discriminator }) { - watchDependency('discriminator#/monitoring') - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const isAlertToggleEnabled = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'alert', - ) - return isMonitorEnabled && isAlertToggleEnabled -} + function showIssuer() { + // watchDependency('model#/spec/admin/tls/default') + const isTlsEnabled = getValue(model, '/spec/admin/tls/default') + const isIssuerToggleEnabled = isToggleOn('clusterIssuers') + return isTlsEnabled && isIssuerToggleEnabled + } -function showIssuer({ model, getValue, watchDependency, discriminator }) { - watchDependency('model#/spec/admin/tls/default') - const isTlsEnabled = getValue(model, '/spec/admin/tls/default') - const isIssuerToggleEnabled = isToggleOn( - { getValue, model, watchDependency, discriminator }, - 'clusterIssuers', - ) - return isTlsEnabled && isIssuerToggleEnabled -} + function onBackupSwitch() { + const isBackupOn = getValue(discriminator, '/backup') + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: isBackupOn ? 'KubeStash' : '', + force: true, + }) + } -function onBackupSwitch({ discriminator, getValue, commit }) { - const isBackupOn = getValue(discriminator, '/backup') - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: isBackupOn ? 'KubeStash' : '', - force: true, - }) -} + function setMonitoring() { + const agent = getValue(model, '/spec/admin/monitoring/agent') || '' + return !!agent + } -function setMonitoring({ getValue, model }) { - const agent = getValue(model, '/spec/admin/monitoring/agent') || '' - return !!agent -} + function setBackup() { + const backup = getValue(model, '/spec/backup/tool') + const val = getValue(model, '/spec/admin/backup/enable/default') + return backup === 'KubeStash' && features.includes('backup') && val + } -function setBackup({ model, getValue }) { - const backup = getValue(model, '/spec/backup/tool') - const val = getValue(model, '/spec/admin/backup/enable/default') - return backup === 'KubeStash' && features.includes('backup') && val -} + function onAuthChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/spec/authSecret/password', + value: '', + force: true, + }) + } -function onAuthChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/authSecret/password', - value: '', - force: true, - }) -} + function onReferSecretChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + } -function isConfigDatabaseOn({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configDatabase') - return getValue(discriminator, '/configDatabase') -} + function showAdditionalSettings() { + // watchDependency('discriminator#/bundleApiLoaded') + return features.length + } -function clearConfiguration({ discriminator, getValue, commit }) { - const configOn = getValue(discriminator, '/configDatabase') + function getDefault(type) { + const val = getValue(model, `/spec/admin/${type}/default`) || '' + return val + } - if (!configOn) { - commit('wizard/model$delete', '/spec/configuration') + function getDefaultValue(path) { + const val = getValue(model, `/${path}`) || '' + return val } -} -function EqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue === mode -} -function showAdditionalSettings({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return features.length -} + function convertToLocal(input) { + const date = new Date(input) -function getDefault({ getValue, model }, type) { - const val = getValue(model, `/spec/admin/${type}/default`) || '' - return val -} + if (isNaN(date.getTime())) { + return null + } + + return date.toString() + } -function convertToLocal(input) { - const date = new Date(input) + function convertToUTC(localTime) { + const date = new Date(localTime) + if (isNaN(date.getTime())) return - if (isNaN(date.getTime())) { - return null + const utcString = date.toISOString() + return utcString } - return date.toString() -} + function onTimestampChange() { + const localTime = getValue(model, '/spec/init/archiver/recoveryTimestamp') + if (!localTime) return -function getComponentLogStats(snapshot) { - if (!snapshot || !snapshot.status || !snapshot.status.components) { - return null + const utcString = convertToUTC(localTime) + + // Only update if the value is valid & not already in UTC format + if (utcString && localTime !== utcString) { + commit('wizard/model$update', { + path: '/spec/init/archiver/recoveryTimestamp', + value: utcString, + force: true, + }) + } } - const components = snapshot.status.components - const appKind = snapshot.spec?.appRef?.kind + function getComponentLogStats(snapshot) { + if (!snapshot || !snapshot.status || !snapshot.status.components) { + return null + } + + const components = snapshot.status.components + const appKind = snapshot.spec?.appRef?.kind - if (appKind === 'MongoDB') { - for (const [key, value] of Object.entries(components)) { - if (key.endsWith('0') && value.logStats) { - return value.logStats + if (appKind === 'MongoDB') { + for (const [key, value] of Object.entries(components)) { + if (key.endsWith('0') && value.logStats) { + return value.logStats + } } } - } - if (components['wal'] && components['wal'].logStats) { - return components['wal'].logStats - } + if (components['wal'] && components['wal'].logStats) { + return components['wal'].logStats + } - return null -} + return null + } -async function setPointInTimeRecovery({ commit, axios, storeGet, discriminator, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const refNamespace = getValue(discriminator, '/refNamespace') - const refDBName = getValue(discriminator, '/refDBName') + async function setPointInTimeRecovery() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const refNamespace = getValue(discriminator, '/refNamespace') + const refDBName = getValue(discriminator, '/refDBName') - try { - const repositoriesUrl = `clusters/${owner}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${refNamespace}/repositories/${refDBName}-full` - const snapshotsUrl = `clusters/${owner}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${refNamespace}/snapshots/${refDBName}-incremental-snapshot` - const repositoriesResp = await axios.get(repositoriesUrl) - const snapshotsResp = await axios.get(snapshotsUrl) + try { + const repositoriesUrl = `clusters/${owner}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${refNamespace}/repositories/${refDBName}-full` + const snapshotsUrl = `clusters/${owner}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${refNamespace}/snapshots/${refDBName}-incremental-snapshot` + const repositoriesResp = await axios.get(repositoriesUrl) + const snapshotsResp = await axios.get(snapshotsUrl) - commit('wizard/model$update', { - path: `/spec/init/archiver/encryptionSecret/name`, - value: repositoriesResp.data?.spec.encryptionSecret.name, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/encryptionSecret/namespace`, - value: repositoriesResp.data?.spec.encryptionSecret.namespace, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/fullDBRepository/name`, - value: `${refDBName}-full`, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/fullDBRepository/namespace`, - value: `${refNamespace}`, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/manifestRepository/name`, - value: `${refDBName}-manifest`, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/manifestRepository/namespace`, - value: `${refNamespace}`, - force: true, - }) + commit('wizard/model$update', { + path: `/spec/init/archiver/encryptionSecret/name`, + value: repositoriesResp.data?.spec.encryptionSecret.name, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/encryptionSecret/namespace`, + value: repositoriesResp.data?.spec.encryptionSecret.namespace, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/fullDBRepository/name`, + value: `${refDBName}-full`, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/fullDBRepository/namespace`, + value: `${refNamespace}`, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/manifestRepository/name`, + value: `${refDBName}-manifest`, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/manifestRepository/namespace`, + value: `${refNamespace}`, + force: true, + }) - const resp = getComponentLogStats(snapshotsResp.data) + const resp = getComponentLogStats(snapshotsResp.data) - commit('wizard/model$update', { - path: `/spec/init/archiver/recoveryTimestamp`, - value: convertToLocal(resp?.end), - force: true, - }) - commit('wizard/model$update', { - path: `/minDate`, - value: convertToLocal(resp?.start), - force: true, - }) - commit('wizard/model$update', { - path: `/maxDate`, - value: convertToLocal(resp?.end), - force: true, - }) - } catch (e) { - commit('wizard/model$update', { - path: `/spec/init/archiver/recoveryTimestamp`, - value: '', - force: true, - }) - commit('wizard/model$update', { - path: `/minDate`, - value: '', - force: true, - }) - commit('wizard/model$update', { - path: `/maxDate`, - value: '', - force: true, - }) - console.log(e) + commit('wizard/model$update', { + path: `/spec/init/archiver/recoveryTimestamp`, + value: convertToUTC(resp?.end), + force: true, + }) + commit('wizard/model$update', { + path: `/minDate`, + value: convertToUTC(resp?.start), + force: true, + }) + commit('wizard/model$update', { + path: `/maxDate`, + value: convertToUTC(resp?.end), + force: true, + }) + } catch (e) { + pointIntimeError = + e.response?.data?.message || 'Invalid name / namespace for recovery timestamp' + commit('wizard/model$update', { + path: `/spec/init/archiver/recoveryTimestamp`, + value: '', + force: true, + }) + commit('wizard/model$update', { + path: `/minDate`, + value: '', + force: true, + }) + commit('wizard/model$update', { + path: `/maxDate`, + value: '', + force: true, + }) + commit('wizard/model$delete', '/spec/init/archiver/encryptionSecret') + commit('wizard/model$delete', '/spec/init/archiver/fullDBRepository') + commit('wizard/model$delete', '/spec/init/archiver/manifestRepository') + console.log(e) + } } -} -function isConfigAvailable({ getValue, model }) { - const val = getValue(model, '/spec/configuration') - return val !== '' -} -async function getReferSecrets({ getValue, model, storeGet, axios, discriminator }) { - const referSecret = getValue(discriminator, '/referSecret') - if (!referSecret) { - return [] + let pointIntimeError = '' + function pointInTimeErrorCheck() { + if (pointIntimeError.length) return pointIntimeError + return } - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/metadata/release/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - - const options = [] - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) - } catch (e) { - console.log(e) - } - return options -} + async function getReferSecrets() { + const referSecret = getValue(discriminator, '/referSecret') + if (!referSecret) { + return [] + } -function showAuthPasswordField({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/metadata/release/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` -function showSecretDropdown({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + const options = [] + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + return options + } -function showReferSecret({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/createAuthSecret') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue -} + function showAuthPasswordField() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !modelPathValue && showReferSecret() + } -function getDefaultValue({ getValue, model }, path) { - const val = getValue(model, `/${path}`) || '' - return val -} + function showSecretDropdown() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !!modelPathValue && showReferSecret() + } -function showReferSecretSwitch({ model, getValue, watchDependency, discriminator }) { - const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showReferSecret() { + const modelPathValue = getValue(discriminator, '/createAuthSecret') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue + } -function onReferSecretChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) -} + function showReferSecretSwitch() { + const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue && showReferSecret() + } -return { - showReferSecretSwitch, - onReferSecretChange, - getDefaultValue, - isRancherManaged, - showSecretDropdown, - showReferSecret, - getReferSecrets, - isConfigAvailable, - setPointInTimeRecovery, - getRecoveryNames, - fetchNamespaces, - showRecovery, - returnFalse, - initBundle, - EqualToDatabaseMode, - isVariantAvailable, - showAuthPasswordField, - getNamespaces, - getMachineListForOptions, - setLimits, - setRequests, - setMachineToCustom, - isMachineNotCustom, - isMachineCustom, - showMonitoringSection, - setMonitoringStatus, - updateAlertValue, - getCreateNameSpaceUrl, - ifCapiProviderIsNotEmpty, - ifDedicated, - dedicatedOnChange, - ifZones, - zonesOnChange, - getZones, - getSKU, - showMultiselectZone, - showSelectZone, - setStorageClass, - getNodeTopology, - filterNodeTopology, - getAdminOptions, - isToggleOn, - showAlerts, - showIssuer, - onBackupSwitch, - setMonitoring, - onAuthChange, - isConfigDatabaseOn, - clearConfiguration, - setBackup, - showAdditionalSettings, - getDefault, - onArchiverChange, - showArchiverAlert, - showArchiver, + return { + onReferSecretChange, + showReferSecretSwitch, + getDefaultValue, + showSecretDropdown, + showReferSecret, + getReferSecrets, + setPointInTimeRecovery, + pointInTimeErrorCheck, + isRancherManaged, + getRecoveryNames, + fetchNamespaces, + showRecovery, + showAdditionalSettings, + returnFalse, + initBundle, + isVariantAvailable, + showAuthPasswordField, + EqualToDatabaseMode, + getNamespaces, + isMachineNotCustom, + isMachineCustom, + getMachineListForOptions, + setLimits, + setRequests, + setMachineToCustom, + updateAlertValue, + getCreateNameSpaceUrl, + ifCapiProviderIsNotEmpty, + ifDedicated, + dedicatedOnChange, + ifZones, + zonesOnChange, + getZones, + getSKU, + showMultiselectZone, + showSelectZone, + setStorageClass, + getNodeTopology, + filterNodeTopology, + getAdminOptions, + isToggleOn, + showAlerts, + showIssuer, + onBackupSwitch, + setMonitoring, + onAuthChange, + isConfigDatabaseOn, + clearConfiguration, + setBackup, + getDefault, + onArchiverChange, + showArchiverAlert, + showArchiver, + onTimestampChange, + } } diff --git a/charts/kubedbcom-mariadb-editor/ui/edit-ui.yaml b/charts/kubedbcom-mariadb-editor/ui/edit-ui.yaml index ca6acab3fd..0682bfbac9 100644 --- a/charts/kubedbcom-mariadb-editor/ui/edit-ui.yaml +++ b/charts/kubedbcom-mariadb-editor/ui/edit-ui.yaml @@ -1,1300 +1,722 @@ -steps: -- form: - elements: - - disabled: true - label: - text: labels.database.name - onChange: onNameChange - schema: - $ref: schema#/properties/metadata/properties/release/properties/name - type: input - - disabled: true - fetch: getResources|core|v1|namespaces - label: - text: labels.namespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/metadata/properties/release/properties/namespace - type: select - - disableUnselect: true - disabled: true - fetch: getMariaDbVersions|catalog.kubedb.com|v1alpha1|mariadbversions - label: - text: labels.database.version - schema: - $ref: schema#/properties/resources/properties/kubedbComMariaDB/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/kubedbComMariaDB/properties/metadata/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/resources/properties/kubedbComMariaDB/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/kubedbComMariaDB/properties/metadata/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/resources/properties/kubedbComMariaDB/properties/metadata/properties/annotations/additionalProperties - type: input - - hasDescription: true - label: - text: labels.deletionPolicy - 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/kubedbComMariaDB/properties/spec/properties/deletionPolicy - type: radio - - disabled: true - label: - text: labels.secret - schema: - $ref: schema#/properties/resources/properties/kubedbComMariaDB/properties/spec/properties/authSecret/properties/name - type: input - type: single-step-form - id: basic - title: steps.0.label -- form: - elements: - - alias: reusable_alert - chart: - name: uibytebuildersdev-component-alert - version: v0.29.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 +type: multi-step-form +step: + - type: single-step-form + id: backupconfiguration + # label: Backup + schema: schema/ elements: - - if: isEqualToDatabaseMode|Cluster - label: - text: labels.to_update_disabled_section - type: label-element - - customClass: mb-20 - if: isEqualToDatabaseMode|Cluster - label: - text: labels.create_opsrequest - type: anchor - url: - params: - cluster: - $ref: store#/route/params/cluster - dbname: - $ref: model#/metadata/release/name - domain: - $ref: store#/domain - group: - $ref: model#/metadata/resource/group - kind: - $ref: model#/metadata/resource/kind - namespace: - $ref: model#/metadata/release/namespace - owner: - $ref: store#/route/params/user - resource: - $ref: model#/metadata/resource/name - version: - $ref: model#/metadata/resource/version - path: ${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/mariadbopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations - - computed: setDatabaseMode - disabled: true - hasDescription: true - label: - text: labels.database.mode - onChange: deleteDatabaseModePath + - type: radio + label: Schedule a Backup? + schema: temp/properties/scheduleBackup + isHorizontal: true options: - - description: options.database.mode.Standalone.description - text: options.database.mode.Standalone.label - value: Standalone - - description: options.database.mode.Cluster.description - text: options.database.mode.Cluster.label - value: Cluster - schema: - $ref: discriminator#/activeDatabaseMode - type: radio - - disabled: true - if: isEqualToDatabaseMode|Cluster - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/resources/properties/kubedbComMariaDB/properties/spec/properties/replicas - type: input - - disabled: true + - text: 'Yes' + value: 'yes' + - text: 'No' + value: 'no' + if: + type: function + name: showScheduleBackup + init: + type: func + value: initScheduleBackupForEdit + watcher: + func: onScheduleBackupChange + paths: + - temp/properties/scheduleBackup + - type: block-layout + label: Backup Form + showLabels: false + loader: initBackupData + if: + type: function + name: showBackupForm elements: - - fetch: getStorageClassNames - label: - text: labels.storage.class - schema: - $ref: schema#/properties/resources/properties/kubedbComMariaDB/properties/spec/properties/storage/properties/storageClassName - type: select - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/resources/properties/kubedbComMariaDB/properties/spec/properties/storage/properties/resources/properties/requests/properties/storage - type: input - type: single-step-form - type: single-step-form - id: topology - title: steps.1.label -- form: - discriminator: - configureTLS: - default: true - type: boolean - elements: - - label: - text: labels.to_update_tls - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - params: - cluster: - $ref: store#/route/params/cluster - dbname: - $ref: model#/metadata/release/name - domain: - $ref: store#/domain - group: - $ref: model#/metadata/resource/group - kind: - $ref: model#/metadata/resource/kind - namespace: - $ref: model#/metadata/release/namespace - owner: - $ref: store#/route/params/user - resource: - $ref: model#/metadata/resource/name - version: - $ref: model#/metadata/resource/version - path: ${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/mariadbopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=ReconfigureTLS - - computed: isValueExistInModel|/resources/kubedbComMariaDB/spec/tls - disabled: true - label: - text: labels.enable_tls - onChange: onTlsConfigureChange - schema: - $ref: discriminator#/configureTLS - type: switch - - disabled: true - elements: - - label: - text: labels.require_ssl_question - schema: - $ref: schema#/properties/resources/properties/kubedbComMariaDB/properties/spec/properties/requireSSL - type: switch - - elements: - - computed: setApiGroup - disabled: true - label: - text: labels.api_group - schema: - $ref: schema#/properties/resources/properties/kubedbComMariaDB/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup - type: input - - label: - text: labels.kind + - type: radio + label: Select Backup Type + schema: temp/properties/backupType + isHorizontal: true options: - - text: Issuer - value: Issuer - - text: ClusterIssuer - value: ClusterIssuer - schema: - $ref: schema#/properties/resources/properties/kubedbComMariaDB/properties/spec/properties/tls/properties/issuerRef/properties/kind - type: select - - allowUserDefinedOption: true - fetch: getIssuerRefsName - label: - text: labels.name - schema: - $ref: schema#/properties/resources/properties/kubedbComMariaDB/properties/spec/properties/tls/properties/issuerRef/properties/name - type: select - label: - text: labels.issuer_ref - schema: - $ref: schema#/properties/resources/properties/kubedbComMariaDB/properties/spec/properties/tls/properties/issuerRef - type: single-step-form - - alias: reusable_certificates - chart: - name: uibytebuildersdev-component-certificates - version: v0.29.0 - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComMariaDB/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: + - text: BackupConfig + value: BackupConfig + description: 'Create, Delete or Modify BackupConfig' + - text: BackupBlueprint + value: BackupBlueprint + description: Enable/Disable BackupBlueprint + if: + type: function + name: isBackupDataLoadedTrue + init: + type: func + value: setBackupType + loader: getTypes + watcher: + func: onBackupTypeChange + paths: + - temp/properties/backupType + - type: block-layout + label: Config + if: + type: function + name: isBackupType|BackupConfig + elements: + - type: select + label: Select Context + schema: temp/properties/backupConfigContext + validation: + type: required + loader: getContext + watcher: + func: onContextChange + paths: + - temp/properties/backupConfigContext + - type: select + label: Select BackupConfig + schema: temp/properties/config + validation: + type: required + if: + type: function + name: showConfigList + loader: getConfigList + watcher: + func: onConfigChange + paths: + - temp/properties/config + - type: input + label: Schedule + schema: temp/properties/schedule + validation: + type: required + if: + type: function + name: showSchedule + loader: + name: getDefaultSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions + watchPaths: + - temp/properties/config + watcher: + func: onInputChangeSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions|schedule + paths: + - temp/properties/schedule + - type: switch + label: Paused + fullwidth: true + schema: schema/properties/resources/properties/coreKubestashComBackupConfiguration/properties/spec/properties/paused + if: + type: function + name: showPause + watcher: + func: setPausedValue + paths: + - temp/properties/config + init: + type: func + value: setPausedValue + - type: block-layout + label: Blueprint + if: + type: function + name: isBackupType|BackupBlueprint + elements: + - type: switch + label: Enable Backup Blueprint + fullwidth: true + schema: temp/properties/blueprintEnabled + init: + type: func + value: setBlueprintSwitch + watcher: + func: onBlueprintChange + paths: + - temp/properties/blueprintEnabled + - type: block-layout + label: Archiver + if: + type: function + name: isBackupType|Archiver + elements: + - type: switch + label: Enable Archiver + fullwidth: true + schema: temp/properties/archiverEnabled + init: + type: func + value: setArchiverSwitch + watcher: + func: onArchiverChange + paths: + - temp/properties/archiverEnabled + + - type: single-step-form + id: compute-autoscaler + loader: getDbDetails elements: - - disabled: disableInitializationSection - discriminator: - prePopulateDatabase: - type: string - elements: - - computed: initPrePopulateDatabase - label: - text: labels.prePopulateDatabase - onChange: onPrePopulateDatabaseChange + - type: block-layout + if: + type: function + name: isConsole + elements: + - type: input + label: Name + schema: schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/metadata/properties/name + - type: select + label: Select Namespace + loader: getNamespaces + if: + type: function + name: isRancherManaged + schema: schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/metadata/properties/namespace + - type: select + label: Select Db + loader: getMariaDbs + validation: + type: required + refresh: true + schema: schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/databaseRef/properties/name + watcher: + func: initMetadata + paths: + - schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/databaseRef/properties/name + + - type: radio + if: + type: function + name: isConsole + label: Select Type + validation: + type: required + schema: temp/properties/autoscalingType + watcher: + func: initMetadata + paths: + - temp/properties/autoscalingType 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 + - text: Compute + value: compute + description: Scale your CPU Memory based on resource usage + - text: Storage + value: storage + description: Expand your database size based on volume usage + + - type: block-layout + showLabels: false + loader: fetchTopologyMachines 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/kubedbComMariaDB/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/kubedbComMariaDB/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/kubedbComMariaDB/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 + # mariadb mode + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComMariaDBAutoscaler/spec/compute/mariadb/trigger + schema: temp/properties/compute/properties/mariadb/properties/trigger + watcher: + func: onTriggerChange|compute/mariadb + paths: + - temp/properties/compute/properties/mariadb/properties/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/mariadb/properties/podLifeTimeThreshold + customClass: width-300 + - type: block-layout + label: Mariadb + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/mariadb 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.29.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 + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/mariadb/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|min + loader: + name: getMachines|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-max + watcher: + func: onMachineChange + paths: + - temp/properties/allowedMachine-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/mariadb/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/mariadb/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|max + loader: + name: getMachines|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-min + watcher: + func: onMachineChange + paths: + - temp/properties/allowedMachine-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/mariadb/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/mariadb/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|mariadb + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/mariadb/properties/controlledResources + + - type: block-layout + label: Node Topology + if: + type: function + name: hasNoAnnotations + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology 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.29.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/kubedbComMariaDB/properties/spec/properties/init/properties/waitForInitialRestore - type: switch - if: showInitializationForm - type: single-step-form - type: single-step-form - type: single-step-form - id: initialization - title: steps.3.label -- form: - discriminator: - repoInitialSelectionStatus: - type: string - scheduleBackup: - default: "yes" - type: string - elements: - - computed: initScheduleBackupForEdit - if: showScheduleBackup - 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: - backupType: - type: string - isBackupDataLoaded: - default: false - type: boolean - elements: - - computed: initBackupData - if: returnFalse - type: input - - computed: setBackupType - fetch: getTypes - hasDescription: true - if: isBackupDataLoadedTrue - label: - text: Select Backup Type - onChange: onBackupTypeChange - schema: - $ref: discriminator#/backupType - type: radio - - discriminator: - backupConfigContext: - type: string - config: - type: string - paused: - default: false - type: boolean - schedule: - type: string - elements: - - fetch: getContext - label: - text: Select Context - onChange: onContextChange - required: true - schema: - $ref: discriminator#/backupConfigContext - type: select - - fetch: getConfigList - if: showConfigList - label: - text: Select BackupConfig - onChange: onConfigChange - required: true - schema: - $ref: discriminator#/config - type: select - - computed: getDefaultSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions - if: showSchedule - label: - text: Schedule - onChange: onInputChangeSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions|schedule - required: true - schema: - $ref: discriminator#/schedule - type: input - - if: showPause - label: - text: Paused - schema: - $ref: schema#/properties/resources/properties/coreKubestashComBackupConfiguration/properties/spec/properties/paused - type: switch - if: isBackupType|BackupConfig - type: single-step-form - - discriminator: - blueprintEnabled: - default: false - type: boolean - elements: - - computed: setBlueprintSwitch - label: - text: Enable Backup Blueprint - onChange: onBlueprintChange - schema: - $ref: discriminator#/blueprintEnabled - type: switch - if: isBackupType|BackupBlueprint - type: single-step-form - - discriminator: - archiverEnabled: - default: false - type: boolean - elements: - - computed: setArchiverSwitch - label: - text: Enable Archiver - onChange: onArchiverChange - schema: - $ref: discriminator#/archiverEnabled - type: switch - if: isBackupType|Archiver - 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 + - type: select + label: Select NodeTopology + loader: fetchNodeTopology + schema: schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name + - type: threshold-input + label: ScaleUp Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage + - type: threshold-input + label: ScaleDown Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage + + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + # schema: schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/opsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: storage-autoscaler elements: - - label: - text: labels.to_update_exporter_resources - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - function: getOpsRequestUrl|VerticalScaling - - computed: isValueExistInModel|/resources/kubedbComMariaDB/spec/monitor - label: - text: labels.enable_monitoring - onChange: onEnableMonitoringChange - schema: - $ref: discriminator#/enableMonitoring - type: switch - - discriminator: - customizeExporter: - default: true - type: boolean + - type: block-layout + showLabels: false 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/kubedbComMariaDB/properties/spec/properties/monitor/properties/agent - type: radio - - elements: - - label: - text: labels.scrapping_interval - schema: - $ref: schema#/properties/resources/properties/kubedbComMariaDB/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval - type: input - if: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComMariaDB/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/kubedbComMariaDB/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/kubedbComMariaDB/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: - - if: returnFalse - label: - text: labels.resources - schema: - $ref: schema#/properties/resources/properties/kubedbComMariaDB/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/kubedbComMariaDB/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/kubedbComMariaDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup - type: input - - label: - text: labels.port - schema: - $ref: schema#/properties/resources/properties/kubedbComMariaDB/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/kubedbComMariaDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args/items - type: input - label: - text: labels.args - schema: - $ref: schema#/properties/resources/properties/kubedbComMariaDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args - type: list-input-form - - alias: reusable_env - chart: - name: uibytebuildersdev-component-env - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComMariaDB/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: - - elements: - - alias: pod_template_standalone - chart: - name: uibytebuildersdev-component-pod-template - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - functionCallbacks: - isEditWizard: - $ref: functions#/returnTrue - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComMariaDB/properties/spec/properties/podTemplate - type: reusable-element - type: single-step-form - 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.29.0 - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComMariaDB/properties/spec/properties/serviceTemplates - type: reusable-element - type: single-step-form - id: networking - title: steps.7.label -- form: - elements: - - elements: - - discriminator: - configuration: - type: string - configurationSource: - default: use-existing-config - type: string - elements: - - label: - text: labels.to_update_config - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - params: - cluster: - $ref: store#/route/params/cluster - dbname: - $ref: model#/metadata/release/name - domain: - $ref: store#/domain - group: - $ref: model#/metadata/resource/group - kind: - $ref: model#/metadata/resource/kind - namespace: - $ref: model#/metadata/release/namespace - owner: - $ref: store#/route/params/user - resource: - $ref: model#/metadata/resource/name - version: - $ref: model#/metadata/resource/version - path: ${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/mariadbopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=Reconfigure - - disabled: true - label: - text: labels.custom_config - onChange: onConfigurationSourceChange + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComMariaDBAutoscaler/spec/storage/mariadb/trigger + schema: temp/properties/storage/properties/mariadb/properties/trigger + watcher: + func: onTriggerChange|storage/mariadb + paths: + - temp/properties/storage/properties/mariadb/properties/trigger + - type: label-element + 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: select + label: Mode + description: Select how the storage expansion should be handled. 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 - disabled: true - fetch: getSecrets - if: isEqualToDiscriminatorPath|use-existing-config|/configurationSource - label: - text: labels.name - schema: - $ref: schema#/properties/resources/properties/kubedbComMariaDB/properties/spec/properties/configSecret/properties/name - type: select - type: single-step-form - type: single-step-form - type: single-step-form - id: custom-config - title: steps.8.label -- form: - discriminator: - dbDetails: - default: false - type: boolean - elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getMariaDbs - label: - text: SelectDb - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: SelectType - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - discriminator: - topologyMachines: - default: [] - type: array - elements: - - fetch: fetchTopologyMachines - if: returnFalse - schema: - $ref: discriminator#/topologyMachines - type: input - - elements: - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComMariaDBAutoscaler/spec/compute/mariadb/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/mariadb/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/mariadb/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/mariadb/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-max: - type: string - allowedMachine-min: - type: string + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/storage/properties/mariadb/properties/expansionMode + - type: block-layout + showLabels: false + elements: + - type: block-layout + label: Mariadb + showLabels: true elements: - - computed: setAllowedMachine|min - disableUnselect: true - fetch: getMachines|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|mariadb - schema: - $ref: discriminator#/properties/allowedMachine-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/mariadb/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/mariadb/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/mariadb/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|max - disableUnselect: true - fetch: getMachines|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|mariadb - schema: - $ref: discriminator#/properties/allowedMachine-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/mariadb/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/mariadb/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/mariadb/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|mariadb - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/mariadb/properties/controlledResources - type: multiselect - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/mariadb - type: single-step-form - label: - text: Mariadb - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/mariadb - show_label: true - type: single-step-form - - elements: - - fetch: fetchNodeTopology - label: - text: Select NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name - type: select - - if: isNodeTopologySelected - label: - text: ScaleUp Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage - type: input - - if: isNodeTopologySelected - label: - text: ScaleDown Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage - type: input - if: hasNoAnnotations - label: - text: NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology - show_label: true - type: single-step-form - if: ifScalingTypeEqualsTo|compute - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: compute-autoscaler - title: steps.9.label -- form: - discriminator: - dbDetails: - default: false - type: boolean + - type: threshold-input + label: UsageThreshold (%) + subtitle: Set the threshold percentage of storage usage to trigger scaling. + schema: schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/storage/properties/mariadb/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/storage/properties/mariadb/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComMariaDB/spec/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComMariaDBAutoscaler/spec/storage/mariadb/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/storage/properties/mariadb/properties/scalingRules + # elements: + # - type: input + # label: AppliesUpto (In Storage units) + # schema: appliesUpto + # - type: input + # label: Threshold (In %, Or In Storage Units) + # schema: threshold + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/storage/properties/mariadb/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComMariaDBAutoscaler/spec/storage/mariadb/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/storage/properties/mariadb/properties/upperBound + - type: block-layout + label: OpsRequest Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: monitoring + loader: initMonitoring elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getMariaDbs - label: - text: SelectDb - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: SelectType - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComMariaDBAutoscaler/spec/storage/mariadb/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/storage/properties/mariadb/properties/trigger - type: select - - label: - text: Expansion Mode + - type: label-element + label: To update Exporter Resource section click on Create OpsRequest + - type: anchor + label: Create OpsRequest + schema: temp/properties/opsRequestUrl + init: + type: func + value: getOpsRequestUrl|scale-vertically + - type: switch + label: Enable Monitoring + fullwidth: true + schema: temp/properties/enableMonitoring + init: + type: func + value: isValueExistInModel|/resources/kubedbComMariaDB/spec/monitor + watcher: + func: onEnableMonitoringChange + paths: + - temp/properties/enableMonitoring + - type: block-layout + if: + type: function + name: showMonitoringSection + elements: + - type: radio + label: Select a Monitoring Method + schema: schema/properties/resources/properties/kubedbComMariaDB/properties/spec/properties/monitor/properties/agent + isHorizontal: true options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/storage/properties/mariadb/properties/expansionMode - type: select - - label: - text: Usage Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/storage/properties/mariadb/properties/usageThreshold - type: input - - addFormLabel: Scaling Rules - element: + - text: Prometheus Operator + value: prometheus.io/operator + description: Inject metric exporter sidecar and creates a ServiceMonitor + - text: Custom ServiceMonitor + value: prometheus.io + description: Injects the metric exporter sidecar and let you customize ServiceMonitor + - text: Custom Scrapper + value: prometheus.io/builtin + description: Inject metric exporter sidecar and add Prometheus annotations to the stats Service + init: + type: static + value: prometheus.io/operator + watcher: + func: onAgentChange + paths: + - schema/properties/resources/properties/kubedbComMariaDB/properties/spec/properties/monitor/properties/agent + - type: block-layout + label: ServiceMonitor Configuration + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComMariaDB/spec/monitor/agent + elements: + - label: Scrapping Interval + schema: schema/properties/resources/properties/kubedbComMariaDB/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval + type: input + - type: block-layout + label: Service Monitor + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComMariaDB/spec/monitor/agent + elements: + - type: array-object-form + label: Endpoints + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/endpoints elements: - - label: - text: Applies Upto - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/storage/properties/mariadb/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/storage/properties/mariadb/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/storage/properties/mariadb/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: Applies Upto - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/storage/properties/mariadb/properties/upperBound - type: input - label: - text: Mariadb - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/compute/properties/mariadb - show_label: true - type: single-step-form - if: ifScalingTypeEqualsTo|storage - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMariaDBAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: storage-autoscaler - title: steps.10.label -- form: - discriminator: - binding: - default: false - type: boolean + - type: switch + label: Honor labels + fullwidth: true + schema: honorLabels + - type: input + label: Interval + schema: interval + validation: + type: required + - type: input + label: Path + schema: path + validation: + type: required + - type: input + label: Port + schema: port + validation: + type: required + - type: select + multiple: true + label: Match Namespaces + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/namespaceSelector/properties/matchNames + loader: getResources|core|v1|namespaces + if: + type: function + name: returnFalse + - type: block-layout + showLabels: false + # schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector + if: + type: function + name: returnFalse + elements: + - type: object-item + label: Labels + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector/properties/matchLabels + - type: object-item + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/metadata/properties/labels + label : Labels + buttonClass: is-light is-outlined + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComMariaDB/spec/monitor/agent + # individualItemDisabilityCheck: disableLableChecker + - type: label-element + label: Exporter Configuration + schema: '' + - type: switch + label: Customize Exporter Sidecar + fullwidth: true + schema: temp/properties/customizeExporter + init: + type: static + value: true + watcher: + func: onCustomizeExporterChange + paths: + - temp/properties/customizeExporter + - type: block-layout + label: Customer Exporter Section + showLabels: false + if: + type: function + name: showCustomizeExporterSection + elements: + - type: machine-compare + label: Resources + schema: schema/properties/resources/properties/kubedbComMariaDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/resources + if: + type: function + name: returnFalse + - type: label-element + label: Security Context + schema: '' + - type: input + schema: schema/properties/resources/properties/kubedbComMariaDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsUser + label: Run as User + - type: input + schema: schema/properties/resources/properties/kubedbComMariaDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup + label: Run as Group + - type: input + schema: schema/properties/resources/properties/kubedbComMariaDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/port + label: Port + - type: array-item-form + label: Args + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/kubedbComMariaDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args + init: + type: static + value: ['--compatible-mode'] + element: + type: input + label: Args + # isSubsection: true + - type: block-layout + label: Metadata + showLabels: false + elements: + - type: array-object-form + init: + type: func + value: initEnvArray + label: Environment Variables + buttonClass: is-light is-outlined + watcher: + func: onEnvArrayChange + paths: + - temp/properties/env + schema: temp/properties/env + elements: + - type: input + label: Name + schema: name + validation: + type: required + - type: radio + label: Value From + schema: temp/properties/valueFromType + validation: + type: required + init: + type: func + value: setValueFrom + options: + - text: Input + value: input + - text: Secret + value: secret + - text: ConfigMap + value: configMap + watcher: + func: onValueFromChange + paths: + - temp/properties/valueFromType + - type: input + label: Value + schema: value + validation: + type: required + if: + name: isEqualToTemp|input + type: function + - type: select + if: + type: function + name: isEqualToTemp|configMap + label: ConfigMap Name + schema: valueFrom/properties/configMapKeyRef/properties/name + loader: + name: resourceNames|core|v1|configmaps + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: ConfigMap Key + schema: valueFrom/properties/configMapKeyRef/properties/key + if: + type: function + name: isEqualToTemp|configMap + loader: + name: getConfigMapKeys + watchPaths: + - schema/resources/kubedbComMariaDB/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/configMapKeyRef/name + - schema/metadata/release/namespace + - type: select + label: Secret Name + schema: valueFrom/properties/secretKeyRef/properties/name + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecrets + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: Secret Key + schema: valueFrom/properties/secretKeyRef/properties/key + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecretKeys + watchPaths: + - schema/resources/kubedbComMariaDB/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/secretKeyRef/name + - schema/metadata/release/namespace + + - type: single-step-form + id: binding elements: - - computed: isBindingAlreadyOn - label: - text: Expose Database - onChange: addOrRemoveBinding - schema: - $ref: discriminator#/properties/binding - type: switch - type: single-step-form - id: binding - title: Gateway Binding -type: multi-step-form + - type: switch + label: Expose Database + schema: temp/properties/binding + fullwidth: true + init: + type: func + value: isBindingAlreadyOn + watcher: + func: addOrRemoveBinding + paths: + - temp/properties/binding \ No newline at end of file diff --git a/charts/kubedbcom-mariadb-editor/ui/functions.js b/charts/kubedbcom-mariadb-editor/ui/functions.js index 4f886a73d9..e4c5202e39 100644 --- a/charts/kubedbcom-mariadb-editor/ui/functions.js +++ b/charts/kubedbcom-mariadb-editor/ui/functions.js @@ -1,2605 +1,1572 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + // ************************* common functions ******************************************** // eslint-disable-next-line no-empty-pattern -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 disableLableChecker({ itemCtx }) { - const { key } = itemCtx - if (key.startsWith('app.kubernetes.io') || key.includes('helm')) return true - else return false -} - -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} - -async function getResources({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, + /********** 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', '') + + /************* Backup Configuration *************/ + + function initScheduleBackupForEdit() { + const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( + getValue, + model, ) - 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 isEqualToDiscriminatorPath( - { discriminator, getValue, watchDependency }, - value, - discriminatorPath, -) { - watchDependency('discriminator#' + discriminatorPath) - const discriminatorValue = getValue(discriminator, discriminatorPath) - return discriminatorValue === value -} - -function setValueFromModel({ getValue, model }, path) { - return getValue(model, path) -} - -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 -} - -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + initRepositoryChoiseForEdit() - 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) + if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' + else return 'no' } - return ans -} - -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - 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 unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - 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, - } - }) -} - -function returnTrue() { - return true -} - -function returnStringYes() { - return 'yes' -} - -// ************************* Basic Info ********************************************** -async function getMariaDbVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, - }, - }, - } - - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, + function initScheduleBackup() { + const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( + getValue, + model, ) - const resources = (resp && resp.data && resp.data.items) || [] - - // keep only non deprecated versions - const filteredMongoDbVersions = resources.filter((item) => item.spec && !item.spec.deprecated) - - filteredMongoDbVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredMongoDbVersions - } catch (e) { - console.log(e) - return [] + if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' + else return 'no' } -} -// ************************* Auth Secret Field ****************************************** -function showAuthPasswordField({ model, getValue, watchDependency }) { - watchDependency('model#/resources') - const modelPathValue = getValue(model, '/resources') - return !!( - modelPathValue && - modelPathValue.secret && - modelPathValue.secret.metadata && - modelPathValue.secret.metadata.name && - !showAuthSecretField({ model, getValue, watchDependency }) - ) -} - -function showAuthSecretField({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComMariaDB/spec') - const modelPathValue = getValue(model, '/resources/kubedbComMariaDB/spec') - return !!(modelPathValue && modelPathValue.authSecret && modelPathValue.authSecret.name) -} - -function showNewSecretCreateField({ model, getValue, watchDependency, commit }) { - const resp = - !showAuthSecretField({ model, getValue, watchDependency }) && - !showAuthPasswordField({ model, getValue, watchDependency }) - const secret = getValue(model, '/resources/secret_auth') - if (resp && !secret) { - commit('wizard/model$update', { - path: '/resources/secret_auth', - value: { - data: { - password: '', - }, - }, - force: true, - }) - } - return resp -} - -// ********************* Database Mode *********************** -function setDatabaseMode({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/resources/kubedbComMariaDB/spec/replicas') - watchDependency('model#/resources/kubedbComMariaDB/spec/replicas') - - if (modelPathValue > 1) { - return 'Cluster' - } else { - return 'Standalone' - } -} - -let storageClassList = [] -async function getStorageClassNames({ axios, storeGet, commit, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/storage.k8s.io/v1/storageclasses`, - { - params: { - filter: { items: { metadata: { name: null, annotations: 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 - }) - storageClassList = resources - const initialStorageClass = getValue( - model, - '/resources/kubedbComMariaDB/spec/storage/storageClassName', - ) - if (!initialStorageClass) setStorageClass({ model, getValue, commit }) - return resources -} - -function setStorageClass({ model, getValue, commit }) { - const deletionPolicy = getValue(model, '/resources/kubedbComMariaDB/spec/deletionPolicy') || '' - let storageClass = - getValue(model, '/resources/kubedbComMariaDB/spec/storage/storageClassName') || '' - const suffix = '-retain' - - const simpleClassList = storageClassList.filter((item) => { - return !item.metadata?.name?.endsWith(suffix) - }) - - const retainClassList = storageClassList.filter((item) => { - return item.metadata?.name?.endsWith(suffix) - }) - - const defaultSimpleList = simpleClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] + function getBackupConfigsAndAnnotations(getValue, model) { + const stashAppscodeComBackupConfiguration = getValue( + model, + '/resources/stashAppscodeComBackupConfiguration', ) - }) + const kubedbComMariaDBAnnotations = + getValue(model, '/resources/kubedbComMariaDB/metadata/annotations') || {} - const defaultRetainList = retainClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] + const isBluePrint = Object.keys(kubedbComMariaDBAnnotations).some( + (k) => + k === 'stash.appscode.com/backup-blueprint' || + k === 'stash.appscode.com/schedule' || + k.startsWith('params.stash.appscode.com/'), ) - }) - - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - if (simpleClassList.length > 1) { - const found = defaultSimpleList.length ? defaultSimpleList[0] : simpleClassList[0] - storageClass = found.value - } else if (simpleClassList.length === 1) { - storageClass = simpleClassList[0]?.value - } else { - const found = defaultRetainList.length - ? defaultRetainList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found - } - } else { - if (retainClassList.length > 1) { - const found = defaultRetainList.length ? defaultRetainList[0] : retainClassList[0] - storageClass = found.value - } else if (retainClassList.length === 1) { - storageClass = retainClassList[0]?.value - } else { - const found = defaultSimpleList.length - ? defaultSimpleList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found - } - } - - if (storageClass) { - commit('wizard/model$update', { - path: '/resources/kubedbComMariaDB/spec/storage/storageClassName', - value: storageClass, - force: true, - }) - } -} - -function deleteDatabaseModePath({ discriminator, getValue, commit, model }) { - const mode = getValue(discriminator, '/activeDatabaseMode') - if (mode === 'Cluster') { - replicas = getValue(model, '/resources/kubedbComMariaDB/spec/replicas') - if (!replicas) { - commit('wizard/model$update', { - path: '/resources/kubedbComMariaDB/spec/replicas', - value: 3, - force: true, - }) - } - } else if (mode === 'Standalone') { - commit('wizard/model$delete', '/resources/kubedbComMariaDB/spec/replicas') - } -} - -function isEqualToDatabaseMode({ getValue, watchDependency, discriminator }, value) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - return mode === value -} - -// ************************** TLS ******************************88 - -function setApiGroup() { - return 'cert-manager.io' -} - -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - watchDependency('model#/resources/kubedbComMariaDB/spec/tls/issuerRef/apiGroup') - watchDependency('model#/resources/kubedbComMariaDB/spec/tls/issuerRef/kind') - watchDependency('model#/metadata/release/namespace') - const apiGroup = getValue(model, '/resources/kubedbComMariaDB/spec/tls/issuerRef/apiGroup') - const kind = getValue(model, '/resources/kubedbComMariaDB/spec/tls/issuerRef/kind') - const namespace = getValue(model, '/metadata/release/namespace') - - let url - if (kind === 'Issuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/namespaces/${namespace}/issuers` - } else if (kind === 'ClusterIssuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/clusterissuers` - } - - if (!url) return [] - - 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 [] - } -} - -async function hasIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await getIssuerRefsName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !!(resp && resp.length) -} - -async function hasNoIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await hasIssuerRefName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !resp -} - -function setSSLMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComMariaDB/spec/sslMode') - return val || 'require' -} - -function showTlsConfigureSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configureTLS') - const configureStatus = getValue(discriminator, '/configureTLS') - return configureStatus -} - -function onTlsConfigureChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/configureTLS') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComMariaDB/spec/tls', - value: { issuerRef: {}, certificates: [] }, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComMariaDB/spec/tls') - commit('wizard/model$delete', '/resources/kubedbComMariaDB/spec/sslMode') - } -} - -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} - -/****** Monitoring *********/ - -function showMonitoringSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/enableMonitoring') - const configureStatus = getValue(discriminator, '/enableMonitoring') - return configureStatus -} - -function onEnableMonitoringChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/enableMonitoring') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComMariaDB/spec/monitor', - value: {}, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComMariaDB/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, getValue }) { - watchDependency('discriminator#/customizeExporter') - const configureStatus = getValue(discriminator, '/customizeExporter') - return configureStatus -} - -function onCustomizeExporterChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/customizeExporter') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComMariaDB/spec/monitor/prometheus/exporter', - value: {}, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComMariaDB/spec/monitor/prometheus/exporter') - } -} - -// ********************************* Initialization & Backup ************************************* -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 = {} - -const stashAppscodeComRestoreSession_init = { - spec: { - repository: { - name: '', - }, - rules: [ - { - snapshots: ['latest'], - }, - ], - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} -const initScript = { - scriptPath: '', - secret: { - secretName: '', - }, -} -const stashAppscodeComRepository_init_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const stashAppscodeComRepository_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const restoreSessionInitRunTimeSettings = { - container: { - resources: { - requests: { - cpu: '', - memory: '', - }, - limits: { - cpu: '', - memory: '', - }, - }, - nice: { - adjustment: null, - }, - ionice: { - class: null, - classData: null, - }, - securityContext: { - privileged: false, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - env: [], - envFrom: [], - }, - pod: { - serviceAccountName: '', - imagePullSecrets: [], - securityContext: { - fsGroup: null, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - }, -} - -const stashAppscodeComBackupConfiguration = { - spec: { - repository: { - name: '', - }, - retentionPolicy: { - keepLast: 5, - name: 'keep-last-5', - prune: true, - }, - schedule: '*/5 * * * *', - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} - -function valueExists(value, getValue, path) { - const val = getValue(value, path) - if (val) return true - else return false -} - -function initPrePopulateDatabase({ getValue, model }) { - const waitForInitialRestore = getValue( - model, - '/resources/kubedbComMariaDB/spec/init/waitForInitialRestore', - ) - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - const script = getValue(model, '/resources/kubedbComMariaDB/spec/init/script') - - return waitForInitialRestore || !!stashAppscodeComRestoreSession_init || !!script ? 'yes' : 'no' -} - -function onPrePopulateDatabaseChange({ commit, getValue, discriminator, model }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - if (prePopulateDatabase === 'no') { - // delete related properties - commit('wizard/model$update', { - path: '/resources/kubedbComMariaDB/spec/init/waitForInitialRestore', - value: false, - }) - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - commit('wizard/model$delete', '/resources/kubedbComMariaDB/spec/init/script') - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else { - const dbName = getValue(model, '/metadata/release/name') - // set stashAppscodeComRestoreSession_init if it doesn't exist - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - force: true, - }) - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) + return { + stashAppscodeComBackupConfiguration, + isBluePrint, } } -} -function initDataSource({ getValue, model }) { - const script = getValue(model, '/resources/kubedbComMariaDB/spec/init/script') - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) + function onScheduleBackupChange() { + const scheduleBackup = getValue(discriminator, '/scheduleBackup') - if (script) return 'script' - else if (stashAppscodeComRestoreSession_init) return 'stashBackup' - else return undefined -} - -function onDataSourceChange({ commit, getValue, discriminator, model }) { - const dataSource = getValue(discriminator, '/dataSource') - - commit('wizard/model$update', { - path: '/resources/kubedbComMariaDB/spec/init/waitForInitialRestore', - value: dataSource === 'stashBackup', - force: true, - }) - - if (dataSource === 'script') { - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') + if (scheduleBackup === 'no') { + // delete stashAppscodeComBackupConfiguration + commit('wizard/model$delete', '/resources/stashAppscodeComBackupConfiguration') + commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') + // delete annotation from kubedbComMariaDB annotation + deleteKubeDbComMariaDbAnnotation(getValue, model, commit) + } else { + const { isBluePrint } = getBackupConfigsAndAnnotations(getValue, model) - // create a new script if there is no script property - if (!valueExists(model, getValue, '/resources/kubedbComMariaDB/spec/init/script')) - commit('wizard/model$update', { - path: '/resources/kubedbComMariaDB/spec/init/script', - value: initScript, - }) - } else if (dataSource === 'stashBackup') { - commit('wizard/model$delete', '/resources/kubedbComMariaDB/spec/init/script') + // create stashAppscodeComBackupConfiguration and initialize it if not exists - // create a new stashAppscodeComRestoreSession_init if there is no stashAppscodeComRestoreSession_init property - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { const dbName = getValue(model, '/metadata/release/name') - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - }) - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) + 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, + }) + } } } -} - -// // for script -function initVolumeType({ getValue, model }) { - const configMap = getValue(model, '/resources/kubedbComMariaDB/spec/init/script/configMap/name') - const secret = getValue(model, '/resources/kubedbComMariaDB/spec/init/script/secret/secretName') - - if (configMap) return 'configMap' - else if (secret) return 'secret' - else return undefined -} -function onVolumeTypeChange({ commit, getValue, discriminator, model }) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - if (sourceVolumeType === 'configMap') { - // add configMap object and delete secret object - commit('wizard/model$delete', '/resources/kubedbComMariaDB/spec/init/script/secret') - - if (!valueExists(model, getValue, '/resources/kubedbComMariaDB/spec/init/script/configMap')) { - commit('wizard/model$update', { - path: '/resources/kubedbComMariaDB/spec/init/script/configMap', - value: { - name: '', - }, - }) - } - } else if (sourceVolumeType === 'secret') { - // delete configMap object and add secret object - commit('wizard/model$delete', '/resources/kubedbComMariaDB/spec/init/script/configMap') - - if (!valueExists(model, getValue, '/resources/kubedbComMariaDB/spec/init/script/secret')) { - commit('wizard/model$update', { - path: '/resources/kubedbComMariaDB/spec/init/script/secret', - value: { - secretName: '', - }, - }) - } + function valueExists(value, getValue, path) { + const val = getValue(value, path) + if (val) return true + else return false } -} - -function showInitializationForm({ getValue, discriminator, watchDependency }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - watchDependency('discriminator#/prePopulateDatabase') - return prePopulateDatabase === 'yes' -} - -function showScriptOrStashForm({ getValue, discriminator, watchDependency }, value) { - const dataSource = getValue(discriminator, '/dataSource') - watchDependency('discriminator#/dataSource') - return dataSource === value -} -function showConfigMapOrSecretName({ getValue, discriminator, watchDependency }, value) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - watchDependency('discriminator#/sourceVolumeType') - return sourceVolumeType === value -} - -// for stash backup -function initializeNamespace({ getValue, model }) { - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} - -function showRepositorySelectOrCreate({ getValue, discriminator, watchDependency }, value) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - return repositoryChoise === value -} - -function onInitRepositoryChoiseChange({ getValue, discriminator, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - if (repositoryChoise === 'select') { - // delete stashAppscodeComRepository_init_repo from model - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else if (repositoryChoise === 'create') { - // add stashAppscodeComRepository_init_repo to model - commit('wizard/model$update', { - path: 'resources/stashAppscodeComRepository_init_repo', - value: stashAppscodeComRepository_init_repo, + function deleteKubeDbComMariaDbAnnotation(getValue, model, commit) { + const annotations = getValue(model, '/resources/kubedbComMariaDB/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] }) - - const repositoryName = `${getValue(model, '/metadata/release/name')}-init-repo` - // set this name in stashAppscodeComRestoreSession_init commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: repositoryName, + path: '/resources/kubedbComMariaDB/metadata/annotations', + value: filteredAnnotations, }) } -} -function initCustomizeRestoreJobRuntimeSettings({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function initCustomizeRestoreJobRuntimeSettingsForBackup({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function onCustomizeRestoreJobRuntimeSettingsChange({ commit, getValue, discriminator, model }) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - value: restoreSessionInitRunTimeSettings, - }) - } - } -} - -function onCustomizeRestoreJobRuntimeSettingsChangeForBackup({ - commit, - getValue, - discriminator, - model, -}) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - value: {}, - force: true, - }) - } - } -} - -function showRuntimeForm({ discriminator, getValue, watchDependency }, value) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - watchDependency('discriminator#/customizeRestoreJobRuntimeSettings') - return customizeRestoreJobRuntimeSettings === value -} - -async function getImagePullSecrets({ getValue, model, watchDependency, axios, storeGet }) { - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - - let resources = await getNamespacedResourceList(axios, storeGet, { - namespace, - group: 'core', - version: 'v1', - resource: 'secrets', - }) - - resources = resources.filter((item) => { - const validType = ['kubernetes.io/dockerconfigjson'] - return validType.includes(item.type) - }) - - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: { name: name }, - } - }) -} - -// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// FOR Backup Configuration - -// schedule bakcup - -function getBackupConfigsAndAnnotations(getValue, model) { - const stashAppscodeComBackupConfiguration = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration', - ) - const kubedbComMariaDBAnnotations = - getValue(model, '/resources/kubedbComMariaDB/metadata/annotations') || {} - - const isBluePrint = Object.keys(kubedbComMariaDBAnnotations).some( - (k) => - k === 'stash.appscode.com/backup-blueprint' || - k === 'stash.appscode.com/schedule' || - k.startsWith('params.stash.appscode.com/'), - ) - - return { - stashAppscodeComBackupConfiguration, - isBluePrint, - } -} - -function deleteKubeDbComMariaDbAnnotation(getValue, model, commit) { - const annotations = getValue(model, '/resources/kubedbComMariaDB/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/kubedbComMariaDB/metadata/annotations', - value: filteredAnnotations, - }) -} - -function addKubeDbComMariaDbAnnotation(getValue, model, commit, key, value, force) { - const annotations = getValue(model, '/resources/kubedbComMariaDB/metadata/annotations') || {} - - if (annotations[key] === undefined) { - annotations[key] = value - } else if (force) { - annotations[key] = value - } - - commit('wizard/model$update', { - path: '/resources/kubedbComMariaDB/metadata/annotations', - value: annotations, - force: true, - }) -} - -function initScheduleBackupForEdit({ getValue, model, setDiscriminatorValue }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function initScheduleBackup({ getValue, model }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function onScheduleBackupChange({ commit, getValue, discriminator, model }) { - 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 kubedbComMariaDB annotation - deleteKubeDbComMariaDbAnnotation(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, - }) - } + // backup form + function showBackupForm() { + const scheduleBackup = getValue(discriminator, '/scheduleBackup') + // watchDependency('discriminator#/scheduleBackup') + if (scheduleBackup === 'yes') return true + else return false } -} -// backup form -function showBackupForm({ getValue, discriminator, watchDependency }) { - const scheduleBackup = getValue(discriminator, '/scheduleBackup') - watchDependency('discriminator#/scheduleBackup') - - if (scheduleBackup === 'yes') return true - else return false -} - -// backup configuration form -function initalizeTargetReferenceName({ getValue, model, watchDependency }) { - const databaseName = getValue(model, '/metadata/release/name') - watchDependency('model#/metadata/release/name') - - return databaseName -} - -// restore session repository -function setInitialRestoreSessionRepo({ getValue, model }) { - const value = getValue(model, 'resources/stashAppscodeComRepository_init_repo') - return value ? 'create' : 'select' -} + 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/kubedbComMariaDB') + initialDbMetadata = objectCopy(dbResource.metadata) + initialArchiver = dbResource.spec?.archiver ? objectCopy(dbResource.spec?.archiver) : undefined -// backup config repository -function initRepositoryChoise({ getValue, model }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) + // 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 - if (stashAppscodeComRepository_repo) return 'create' - else return 'select' -} + let url = `/clusters/${user}/${cluster}/helm/packageview/values?name=${chartName}&sourceApiGroup=${sourceApiGroup}&sourceKind=${sourceKind}&sourceNamespace=${sourceNamespace}&sourceName=${sourceName}&version=${chartVersion}&format=json` -function initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' - setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) + if (spoke) + url = `/clusters/${user}/${spoke}/helm/packageview/values?name=${chartName}&sourceApiGroup=${sourceApiGroup}&sourceKind=${sourceKind}&sourceNamespace=${sourceNamespace}&sourceName=${sourceName}&version=${chartVersion}&format=json` - return repoInitialSelectionStatus -} + const resp = await axios.get(url) -function onRepositoryChoiseChange({ getValue, discriminator, watchDependency, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') + valuesFromWizard = objectCopy(resp.data?.resources?.coreKubestashComBackupConfiguration) || {} + } catch (e) { + console.log(e) + } - if (repositoryChoise === 'select') { - // delete the stashAppscodeComRepository_repo - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') - } else if (repositoryChoise === 'create') { - // create new stashAppscodeComRepository_repo - if (!valueExists(model, getValue, '/resources/stashAppscodeComRepository_repo')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRepository_repo', - value: stashAppscodeComRepository_repo, - }) - const repositoryName = `${getValue(model, '/metadata/release/name')}-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) + // 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) + } } - } -} -function onRepositoryNameChange({ getValue, model, commit }) { - const repositoryName = getValue(model, 'resources/stashAppscodeComRepository_repo/metadata/name') - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) -} + // 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, + ) -// backup blueprint form -function getMongoAnnotations(getValue, model) { - const annotations = getValue(model, '/resources/kubedbComMariaDB/metadata/annotations') - return { ...annotations } || {} -} + // 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, + ) -function initFromAnnotationValue({ getValue, model }, key) { - const annotations = getMongoAnnotations(getValue, model) - return annotations[key] -} + // set backup switch here + isBackupOn = !!config -function onBackupBlueprintNameChange({ getValue, discriminator, commit, model }) { - const backupBlueprintName = getValue(discriminator, '/backupBlueprintName') - addKubeDbComMariaDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/backup-blueprint', - backupBlueprintName, - true, - ) -} + // set initial data from stash-presets + const stashPreset = storeGet('/backup/stashPresets') + if (stashPreset) { + const { retentionPolicy, encryptionSecret, schedule, storageRef } = stashPreset -function onBackupBlueprintScheduleChange({ getValue, discriminator, commit, model }) { - const backupBlueprintSchedule = getValue(discriminator, '/schedule') - addKubeDbComMariaDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/schedule', - backupBlueprintSchedule, - true, - ) -} + const tempBackends = valuesFromWizard.spec?.backends + tempBackends[0]['storageRef'] = storageRef + tempBackends[0]['retentionPolicy'] = retentionPolicy + valuesFromWizard.spec['backends'] = tempBackends -function initFromAnnotationKeyValue({ getValue, model }, prefix) { - const annotations = getMongoAnnotations(getValue, model) - const newOb = {} - Object.keys(annotations).forEach((key) => { - if (key.startsWith(prefix)) { - const newKey = key.replace(prefix, '') - newOb[newKey] = annotations[key] - } - }) - return newOb -} + 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}` -function onTaskParametersChange({ getValue, discriminator, model, commit }) { - const taskParameters = getValue(discriminator, '/taskParameters') + tempSessions[0]['repositories'] = tempRepositories + tempSessions[0]['scheduler']['schedule'] = schedule + valuesFromWizard.spec['sessions'] = tempSessions + } - const taskParamterKeys = Object.keys(taskParameters).map( - (tp) => `params.stash.appscode.com/${tp}`, - ) - const oldAnnotations = getValue(model, '/resources/kubedbComMariaDB/metadata/annotations') || {} - const newAnnotations = {} + 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, + } - const filteredAnnotationKeys = Object.keys(oldAnnotations).filter( - (key) => !taskParamterKeys.includes(key) && !key.startsWith('params.stash.appscode.com/'), - ) + setDiscriminatorValue('isBackupDataLoaded', true) + } - filteredAnnotationKeys.forEach((key) => { - newAnnotations[key] = oldAnnotations[key] - }) + function isBackupDataLoadedTrue() { + // watchDependency('discriminator#/isBackupDataLoaded') + return !!getValue(discriminator, '/isBackupDataLoaded') + } - Object.keys(taskParameters).forEach((tpk) => { - newAnnotations[`params.stash.appscode.com/${tpk}`] = taskParameters[tpk] - }) + function setBackupType() { + return 'BackupConfig' + } - commit('wizard/model$update', { - path: '/resources/kubedbComMariaDB/metadata/annotations', - value: newAnnotations, - }) -} + function getTypes() { + const arr = [ + { + description: 'Create, Delete or Modify BackupConfig', + text: 'BackupConfig', + value: 'BackupConfig', + }, + { + description: 'Enable/Disable BackupBlueprint', + text: 'BackupBlueprint', + value: 'BackupBlueprint', + }, + ] -function isValueExistInModel({ model, getValue }, path) { - const modelValue = getValue(model, path) - return !!modelValue -} + if ((dbResource?.spec?.replicaSet || dbResource?.spec?.shardTopology) && isArchiverAvailable) { + arr.push({ + description: 'Enable/Disable Archiver', + text: 'Archiver', + value: 'Archiver', + }) + } + return arr + } -function onNamespaceChange({ commit, model, getValue }) { - const namespace = getValue(model, '/metadata/release/namespace') - const agent = getValue(model, '/resources/kubedbComMariaDB/spec/monitor/agent') - if (agent === 'prometheus.io') { + 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/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', - value: [namespace], + path: '/resources/kubedbComMariaDB', + value: objectCopy(dbResource), force: true, }) } -} -function onLabelChange({ commit, model, getValue }) { - const labels = getValue(model, '/resources/kubedbComMariaDB/spec/metadata/labels') + function isBackupType(type) { + // watchDependency('discriminator#/backupType') + const selectedType = getValue(discriminator, '/backupType') - const agent = getValue(model, '/resources/kubedbComMariaDB/spec/monitor/agent') + return selectedType === type + } - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) + 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 onNameChange({ commit, model, getValue }) { - const dbName = getValue(model, '/metadata/release/name') + function onArchiverChange() { + const archiverSwitch = getValue(discriminator, '/archiverEnabled') + const path = 'resources/kubedbComMariaDB/spec/archiver' + if (archiverSwitch) { + commit('wizard/model$update', { + path: path, + value: initialArchiver ? initialArchiver : archiverObjectToCommit, + }) + } else { + commit('wizard/model$delete', path) + } + } - const agent = getValue(model, '/resources/kubedbComMariaDB/spec/monitor/agent') + function addLabelAnnotation(type) { + const obj = objectCopy(initialDbMetadata[type]) - const labels = getValue(model, '/resources/kubedbComMariaDB/spec/metadata/labels') + 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' + } - if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, + path: `/resources/kubedbComMariaDB/metadata/${type}`, + value: obj, force: true, }) } - const scheduleBackup = getValue(model, '/resources/stashAppscodeComBackupConfiguration') + 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'] - if (scheduleBackup) { commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, + path: `/resources/kubedbComMariaDB/metadata/${type}`, + value: obj, force: true, }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_repo') - if (creatingNewRepo) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: `${dbName}-repo`, - force: true, - }) - } } - const prePopulateDatabase = getValue(model, '/resources/stashAppscodeComRestoreSession_init') + function getContext() { + if (isBackupOn) return ['Create', 'Delete', 'Modify'] + return ['Create'] + } - if (prePopulateDatabase) { + function onContextChange() { + const context = getValue(discriminator, '/backupConfigContext') commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, + path: '/context', + value: context, force: true, }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_init_repo') - if (creatingNewRepo) { + if (context === 'Create') { commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: `${dbName}-init-repo`, + path: '/resources/coreKubestashComBackupConfiguration', + value: valuesFromWizard, force: true, }) } + if (context === 'Delete') setDiscriminatorValue('hidePreviewFromWizard', true) + else setDiscriminatorValue('hidePreviewFromWizard', undefined) } - // to reset configSecret name field - const hasSecretConfig = getValue(model, '/resources/secret_config') - if (hasSecretConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComMariaDB/spec/configSecret/name', - value: `${dbName}-config`, - force: true, - }) + 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 returnFalse() { - return false -} + function onConfigChange() { + const configName = getValue(discriminator, '/config') + const configs = objectCopy(backupConfigurationsFromStore) + const configDetails = configs?.find((item) => item?.metadata?.name === configName) -function onAgentChange({ commit, model, getValue }) { - const agent = getValue(model, '/resources/kubedbComMariaDB/spec/monitor/agent') - if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', - value: [], + path: '/resources/coreKubestashComBackupConfiguration', + value: configDetails, force: true, }) + } - onNamespaceChange({ commit, model, getValue }) - onLabelChange({ commit, model, getValue }) - } else { - commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') + function showPause() { + // watchDependency('discriminator#/backupConfigContext') + // watchDependency('discriminator#/config') + const contex = getValue(discriminator, '/backupConfigContext') + const configName = getValue(discriminator, '/config') + return !!configName && contex === 'Modify' } -} -/************************************* Database Secret Section ********************************************/ + 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 getCreateAuthSecret({ model, getValue }) { - const authSecret = getValue(model, '/resources/kubedbComMariaDB/spec/authSecret') + function showConfigList() { + // watchDependency('discriminator#/backupConfigContext') + const contex = getValue(discriminator, '/backupConfigContext') + return contex === 'Modify' || contex === 'Delete' + } - return !authSecret -} + 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 showExistingSecretSection({ getValue, watchDependency, discriminator }) { - watchDependency('discriminator#/createAuthSecret') - const hasAuthSecretName = getValue(discriminator, '/createAuthSecret') - return !hasAuthSecretName -} + function showScheduleBackup() { + const operationQuery = storeGet('/route/params/actions') || '' + const isBackupOperation = operationQuery === 'edit-self-backupconfiguration' ? true : false + return !isBackupOperation + } -function showPasswordSection({ getValue, watchDependency, discriminator }) { - return !showExistingSecretSection({ - getValue, - watchDependency, - discriminator, - }) -} + 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 setAuthSecretPassword({ model, getValue }) { - const encodedPassword = getValue(model, '/resources/secret_auth/data/password') - return encodedPassword ? decodePassword({}, encodedPassword) : '' -} + function initRepositoryChoiseForEdit() { + const stashAppscodeComRepository_repo = getValue( + model, + '/resources/stashAppscodeComRepository_repo', + ) + const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' + setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) -function onAuthSecretPasswordChange({ getValue, discriminator, commit }) { - const stringPassword = getValue(discriminator, '/password') + return repoInitialSelectionStatus + } - if (stringPassword) { - commit('wizard/model$update', { - path: '/resources/secret_auth/data/password', - value: encodePassword({}, stringPassword), - force: true, - }) - commit('wizard/model$update', { - path: '/resources/secret_auth/data/username', - value: encodePassword({}, 'root'), - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/secret_auth') + 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 disableInitializationSection({ model, getValue, watchDependency }) { - const initialized = getValue(model, '/resources/kubedbComMariaDB/spec/init/initialized') - watchDependency('model#/resources/kubedbComMariaDB/spec/init/initialized') - return !!initialized -} + function objectCopy(obj) { + const temp = JSON.stringify(obj) + return JSON.parse(temp) + } -// eslint-disable-next-line no-empty-pattern -function encodePassword({}, value) { - return btoa(value) -} + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } -// eslint-disable-next-line no-empty-pattern -function decodePassword({}, value) { - return atob(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) || [] -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/resources/kubedbComMariaDB/spec/authSecret') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/resources/secret_auth') + 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 getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') + 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}` - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, - { + let ans = [] + try { + const resp = await axios.get(url, { params: { filter: { items: { metadata: { name: null }, type: null } }, }, - }, - ) + }) - const secrets = (resp && resp.data && resp.data.items) || [] + const items = (resp && resp.data && resp.data.items) || [] + ans = items + } catch (e) { + console.log(e) + } - const filteredSecrets = secrets.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) + return ans + } - 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 [] + function setValueFromDbDetails(path) { + const value = getValue(model, path) + return value } -} -//////////////////////////////////////// Service Monitor ////////////////////////////////////////////////////// + /****** Monitoring *********/ -function isEqualToServiceMonitorType({ rootModel, watchDependency }, value) { - watchDependency('rootModel#/spec/type') - return rootModel && rootModel.spec && rootModel.spec.type === value -} + function showMonitoringSection() { + // watchDependency('discriminator#/enableMonitoring') + const configureStatus = getValue(discriminator, '/enableMonitoring') + return configureStatus + } -//////////////////// custom config ///////////////// -function onConfigurationSourceChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSource') - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_config') - } else { - const value = getValue(model, '/resources/secret_config') - if (!value) { + function onEnableMonitoringChange() { + const configureStatus = getValue(discriminator, '/enableMonitoring') + if (configureStatus) { commit('wizard/model$update', { - path: '/resources/secret_config', + path: '/resources/kubedbComMariaDB/spec/monitor', value: {}, force: true, }) + } else { + commit('wizard/model$delete', '/resources/kubedbComMariaDB/spec/monitor') } - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` + + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: '/resources/kubedbComMariaDB/spec/configSecret/name', - value: configSecretName, + path: '/form/alert/enabled', + value: configureStatus ? 'warning' : 'none', force: true, }) } -} - -function onConfigurationChange({ getValue, commit, discriminator, model }) { - const value = getValue(discriminator, '/configuration') - commit('wizard/model$update', { - path: '/resources/secret_config/stringData/md-config.cnf', - value: value, - force: true, - }) - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComMariaDB/spec/configSecret/name', - value: configSecretName, - force: true, - }) -} -function setConfigurationSource({ model, getValue }) { - const modelValue = getValue(model, '/resources/secret_config') - if (modelValue) { - return 'create-new-config' + function showCustomizeExporterSection() { + // watchDependency('discriminator#/customizeExporter') + const configureStatus = getValue(discriminator, '/customizeExporter') + return configureStatus } - return 'use-existing-config' -} -function setSecretConfigNamespace({ getValue, model, watchDependency }) { - watchDependency('model#/metadata/release/namespace') - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} - -function setConfiguration({ model, getValue }) { - return getValue(model, '/resources/secret_config/stringData/md-config.cnf') -} - -function setConfigurationFiles({ model, getValue }) { - const value = getValue(model, '/resources/secret_config/data/md-config.cnf') - return atob(value) -} - -function onSetCustomConfigChange({ discriminator, getValue, commit }) { - const value = getValue(discriminator, '/setCustomConfig') + function onCustomizeExporterChange() { + const configureStatus = getValue(discriminator, '/customizeExporter') + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComMariaDB/spec/monitor/prometheus/exporter', + value: {}, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/kubedbComMariaDB/spec/monitor/prometheus/exporter') + } + } - if (value === 'no') { - commit('wizard/model$delete', '/resources/kubedbComMariaDB/spec/configSecret') - commit('wizard/model$delete', '/resources/secret_config') + function isValueExistInModel(path) { + const modelValue = getValue(model, path) || null + return !!modelValue } -} -function getOpsRequestUrl({ storeGet, model, getValue, mode }, 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 + `/create-opsrequest-${reqType.toLowerCase()}?namespace=${namespace}` - - if (mode === 'standalone-step') return pathConstructedForKubedb - else - return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/mariadbopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` -} + // function onNamespaceChange() { + // const namespace = getValue(model, '/metadata/release/namespace') + // const agent = getValue(model, '/resources/kubedbComMariaDB/spec/monitor/agent') + // if (agent === 'prometheus.io') { + // commit('wizard/model$update', { + // path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + // value: [namespace], + // force: true, + // }) + // } + // } -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function onLabelChange() { + const labels = getValue(model, '/resources/kubedbComMariaDB/spec/metadata/labels') - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } -} + const agent = getValue(model, '/resources/kubedbComMariaDB/spec/monitor/agent') -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} + if (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', + value: labels, + force: true, + }) + } + } -function showScheduleBackup({ storeGet }) { - const operationQuery = storeGet('/route/params/actions') || '' - const isBackupOperation = operationQuery === 'edit-self-backupconfiguration' ? true : false - return !isBackupOperation -} + function onAgentChange() { + const agent = getValue(model, '/resources/kubedbComMariaDB/spec/monitor/agent') + if (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', + value: [], + force: true, + }) -function showBackupOptions({ discriminator, getValue, watchDependency }, backup) { - const backupEnabled = getValue(discriminator, '/backupEnabled') - if (backupEnabled) { - if (backup === 'alert') return true - else return false - } else { - if (backup === 'alert') return false - else return true + onNamespaceChange() + onLabelChange() + } else { + commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') + } } -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + 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') -function getNamespaceArray() { - return namespaceList -} + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }, + ) -async function fetchNamespaces({ axios, storeGet }) { - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const group = storeGet('/route/params/group') - const version = storeGet('/route/params/version') - const resource = storeGet('/route/params/resource') + const secrets = (resp && resp.data && resp.data.items) || [] - const url = `clusters/${username}/${clusterName}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews` + const filteredSecrets = secrets.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) - try { - const resp = await axios.post(url, { - _recurringCall: false, - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], - }, - }) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] + 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 [] } - } catch (e) { - console.log(e) } - return [] -} -async function fetchNames( - { getValue, axios, storeGet, watchDependency, discriminator }, - version, - type, - discriminatorName, -) { - watchDependency(`discriminator#/${discriminatorName}`) - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const namespace = getValue(discriminator, `${discriminatorName}`) - const url = - type !== 'secrets' - ? `clusters/${username}/${clusterName}/proxy/storage.kubestash.com/${version}/namespaces/${namespace}/${type}` - : `clusters/${username}/${clusterName}/proxy/core/${version}/namespaces/${namespace}/${type}` - try { - if (namespace) { - const resp = await axios.get(url) - let data = resp.data.items - if (type === 'secrets') data = data.filter((ele) => !!ele.data['RESTIC_PASSWORD']) - data = data.map((ele) => ele.metadata.name) - return data - } - } catch (e) { - console.log(e) - } - return [] -} + /************* Compute Autoscaling *************/ -function onInputChange( - { getValue, discriminator, commit, model }, - modelPath, - field, - subfield, - discriminatorName, -) { - const value = getValue(discriminator, `/${discriminatorName}`) - const backends = getValue(model, modelPath) || [] - - if (field !== 'encryptionSecret') backends[0][field][subfield] = value - else backends[0]['repositories'][0][field][subfield] = value - commit('wizard/model$update', { - path: modelPath, - value: backends, - force: true, - }) -} + let autoscaleType = '' + let dbDetails = {} + let instance = '' -function onInputChangeSchedule( - { getValue, discriminator, commit, model }, - modelPath, - discriminatorName, -) { - const value = getValue(discriminator, `/${discriminatorName}`) - const session = getValue(model, modelPath) || [] - if (session.length) { - session[0].scheduler.schedule = value + async function getDbDetails() { + const annotations = getValue( + model, + '/resources/autoscalingKubedbComMariaDBAutoscaler/metadata/annotations', + ) + instance = annotations?.['kubernetes.io/instance-type'] + + const owner = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + + const namespace = + storeGet('/route/query/namespace') || + getValue(model, '/resources/autoscalingKubedbComMariaDBAutoscaler/metadata/namespace') || + '' + const name = + storeGet('/route/params/name') || + getValue(model, '/resources/autoscalingKubedbComMariaDBAutoscaler/spec/databaseRef/name') || + '' + + if (namespace && name) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/mariadbs/${name}`, + ) + dbDetails = resp.data || {} + + setDiscriminatorValue('/dbDetails', true) + } catch (e) { + console.log(e) + } + } + + commit('wizard/model$update', { + path: `/metadata/release/name`, + value: name, + force: true, + }) + commit('wizard/model$update', { + path: `/metadata/release/namespace`, + value: namespace, + force: true, + }) + commit('wizard/model$update', { + path: `/resources/autoscalingKubedbComMariaDBAutoscaler/spec/databaseRef/name`, + value: name, + force: true, + }) commit('wizard/model$update', { - path: modelPath, - value: session, + path: `/resources/autoscalingKubedbComMariaDBAutoscaler/metadata/labels`, + value: dbDetails.metadata.labels, + force: true, }) } -} -function getDefault({ getValue, model }, modelPath, field, subfield) { - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') return backends[0][field][subfield] - else { - return backends[0]['repositories'][0][field][subfield] + function isKubedb() { + return !!storeGet('/route/params/actions') } -} -function getDefaultSchedule({ getValue, model, watchDependency }, modelPath) { - watchDependency('discriminator#/config') - const session = getValue(model, modelPath) - return session?.length ? session[0]?.scheduler.schedule : '' -} + function isConsole() { + const isKube = isKubedb() -async function initBackupData({ commit, storeGet, axios, getValue, model, setDiscriminatorValue }) { - // 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/kubedbComMariaDB') - 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', - }, - } + if (isKube) { + const dbName = storeGet('/route/params/name') || '' + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComMariaDBAutoscaler/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/autoscalingKubedbComMariaDBAutoscaler/metadata/name', + value: modifiedName, + force: true, + }) + const namespace = storeGet('/route/query/namespace') || '' + if (namespace) { + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComMariaDBAutoscaler/metadata/namespace', + value: namespace, + force: true, + }) } - } 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 + return !isKube + } - // set initial data from stash-presets - const stashPreset = storeGet('/backup/stashPresets') - if (stashPreset) { - const { retentionPolicy, encryptionSecret, schedule, storageRef } = stashPreset + async function getNamespaces() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - const tempBackends = valuesFromWizard.spec?.backends - tempBackends[0]['storageRef'] = storageRef - tempBackends[0]['retentionPolicy'] = retentionPolicy - valuesFromWizard.spec['backends'] = tempBackends + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, + }) - 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}` + const resources = (resp && resp.data && resp.data.items) || [] - tempSessions[0]['repositories'] = tempRepositories - tempSessions[0]['scheduler']['schedule'] = schedule - valuesFromWizard.spec['sessions'] = tempSessions + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) } - 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, + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found } - setDiscriminatorValue('isBackupDataLoaded', true) -} -function isBackupDataLoadedTrue({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/isBackupDataLoaded') - return !!getValue(discriminator, '/isBackupDataLoaded') -} + // function onNamespaceChange() { + // const namespace = getValue(model, '/metadata/release/namespace') + // const agent = getValue(model, '/resources/kubedbComMariaDB/spec/monitor/agent') + // if (agent === 'prometheus.io') { + // commit('wizard/model$update', { + // path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + // value: [namespace], + // force: true, + // }) + // } + // } -async function setBackupType() { - return 'BackupConfig' -} + async function getMariaDbs() { + // watchDependency('model#/metadata/namespace') + const namespace = getValue(model, '/metadata/namespace') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -async 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?.replicas !== 1 && isArchiverAvailable) { - arr.push({ - description: 'Enable/Disable Archiver', - text: 'Archiver', - value: 'Archiver', - }) - } - return arr -} + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/mariadbs`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) -function onBackupTypeChange({ commit, getValue, discriminator }) { - 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, + const resources = (resp && resp.data && resp.data.items) || [] + + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } }) } - commit('wizard/model$delete', '/context') - commit('wizard/model$update', { - path: '/resources/kubedbComMariaDB', - value: objectCopy(dbResource), - force: true, - }) -} - -function isBackupType({ watchDependency, getValue, discriminator }, type) { - watchDependency('discriminator#/backupType') - const selectedType = getValue(discriminator, '/backupType') - return selectedType === type -} - -function setBlueprintSwitch() { - const annotations = initialDbMetadata?.annotations + function initMetadata() { + const dbName = + getValue(model, '/resources/autoscalingKubedbComMariaDBAutoscaler/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/autoscalingKubedbComMariaDBAutoscaler/metadata/name', + value: modifiedName, + force: true, + }) - return !!( - annotations['blueprint.kubestash.com/name'] && annotations['blueprint.kubestash.com/namespace'] - ) -} + // delete the other type object from vuex wizard model + if (type === 'compute') + commit('wizard/model$delete', '/resources/autoscalingKubedbComMariaDBAutoscaler/spec/storage') + if (type === 'storage') + commit('wizard/model$delete', '/resources/autoscalingKubedbComMariaDBAutoscaler/spec/compute') + } + + async function fetchTopologyMachines() { + const instance = hasAnnotations() + + 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 onBlueprintChange({ getValue, discriminator, commit, model, storeGet }) { - const blueprintSwitch = getValue(discriminator, '/blueprintEnabled') - if (blueprintSwitch) addLabelAnnotation(commit, storeGet, 'annotations') - else deleteLabelAnnotation(commit, 'annotations') -} + function setTrigger(path) { + let value = getValue(model, `/resources/${path}`) + return value === 'On' + } -function setArchiverSwitch() { - const archiver = dbResource?.spec?.archiver - return !!archiver -} + function onTriggerChange(type) { + const trigger = getValue(discriminator, `/${type}/trigger`) + const commitPath = `/resources/autoscalingKubedbComMariaDBAutoscaler/spec/${type}/trigger` -function onArchiverChange({ getValue, discriminator, commit, model, storeGet }) { - const archiverSwitch = getValue(discriminator, '/archiverEnabled') - const path = 'resources/kubedbComMariaDB/spec/archiver' - if (archiverSwitch) { commit('wizard/model$update', { - path: path, - value: initialArchiver ? initialArchiver : archiverObjectToCommit, + path: commitPath, + value: trigger ? 'On' : 'Off', + force: true, }) - } else { - commit('wizard/model$delete', path) } -} -function addLabelAnnotation(commit, storeGet, type) { - const obj = objectCopy(initialDbMetadata[type]) + function hasAnnotations() { + const annotations = + getValue(model, '/resources/autoscalingKubedbComMariaDBAutoscaler/metadata/annotations') || {} + const instance = annotations['kubernetes.io/instance-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' + return !!instance } - commit('wizard/model$update', { - path: `/resources/kubedbComMariaDB/metadata/${type}`, - value: obj, - force: true, - }) -} + function setAllowedMachine(minmax) { + const mx = instance?.includes(',') ? instance.split(',')[1] : '' + const mn = instance?.includes(',') ? instance.split(',')[0] : '' + const machineName = minmax === 'min' ? mn : mx -function deleteLabelAnnotation(commit, type) { - const obj = initialDbMetadata[type] + // Find the machine details from topologyMachines + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] + const machineData = nodeGroups.find((item) => item.topologyValue === machineName) - if (type === 'annotations') { - delete obj['blueprint.kubestash.com/name'] - delete obj['blueprint.kubestash.com/namespace'] - } else delete obj['kubedb.com/archiver'] + // 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: '', + } + } - commit('wizard/model$update', { - path: `/resources/kubedbComMariaDB/metadata/${type}`, - value: obj, - force: true, - }) -} + function getMachines(minmax) { + // watchDependency('discriminator#/topologyMachines') + const depends = minmax === 'min' ? 'max' : 'min' + const dependantPath = `/allowedMachine-${depends}` -function getContext() { - if (isBackupOn) return ['Create', 'Delete', 'Modify'] - return ['Create'] -} + // watchDependency(`discriminator#${dependantPath}`) + const dependantMachineObj = getValue(discriminator, dependantPath) + const dependantMachine = dependantMachineObj?.machine || '' -function onContextChange({ getValue, discriminator, commit, model }) { - 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, - }) - } -} + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] -function getConfigList({ storeGet }) { - 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 -} + const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) -function onConfigChange({ getValue, discriminator, commit, storeGet, model }) { - const configName = getValue(discriminator, '/config') - const configs = objectCopy(backupConfigurationsFromStore) - const configDetails = configs?.find((item) => item?.metadata?.name === configName) + // 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, + }, + } + }) - commit('wizard/model$update', { - path: '/resources/coreKubestashComBackupConfiguration', - value: configDetails, - force: true, - }) -} + const filteredMachine = machines?.filter((item, ind) => + minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, + ) -function showPause({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/backupConfigContext') - watchDependency('discriminator#/config') - const contex = getValue(discriminator, '/backupConfigContext') - const configName = getValue(discriminator, '/config') - return !!configName && contex === 'Modify' -} + return dependantIndex === -1 ? machines : filteredMachine + } -function showConfigList({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/backupConfigContext') - const contex = getValue(discriminator, '/backupConfigContext') - return contex === 'Modify' || contex === 'Delete' -} + function onMachineChange(type) { + const annoPath = '/resources/autoscalingKubedbComMariaDBAutoscaler/metadata/annotations' + const annotations = getValue(model, annoPath) || {} + const instance = annotations['kubernetes.io/instance-type'] -function showSchedule({ watchDependency, getValue, discriminator }) { - 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 -} + // 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 -//////////////// Autoscaler ////////// + // 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/autoscalingKubedbComMariaDBAutoscaler/spec/compute/${type}` -let autoscaleType = '' -let dbDetails = {} + 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 isConsole({ storeGet, commit }) { - const isKube = isKubedb({ storeGet }) + function hasNoAnnotations() { + return !hasAnnotations() + } - if (isKube) { - const dbName = storeGet('/route/params/name') || '' + function setControlledResources(type) { + const list = ['cpu', 'memory'] + const path = `/resources/autoscalingKubedbComMariaDBAutoscaler/spec/compute/${type}/controlledResources` commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComMariaDBAutoscaler/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: '/metadata/name', - value: modifiedName, + path: path, + value: list, force: true, }) - const namespace = storeGet('/route/query/namespace') || '' - if (namespace) { - commit('wizard/model$update', { - path: '/metadata/namespace', - value: namespace, - 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 [] } - return !isKube -} - -function isKubedb({ storeGet }) { - return !!storeGet('/route/params/actions') -} + function isNodeTopologySelected() { + // watchDependency( + // 'model#/resources/autoscalingKubedbComMariaDBAutoscaler/spec/compute/nodeTopology/name', + // ) + const nodeTopologyName = + getValue( + model, + '/resources/autoscalingKubedbComMariaDBAutoscaler/spec/compute/nodeTopology/name', + ) || '' + return !!nodeTopologyName.length + } -function showOpsRequestOptions({ model, getValue, watchDependency, storeGet, discriminator }) { - if (isKubedb({ storeGet }) === true) return true - watchDependency('model#/resources/autoscalingKubedbComMariaDBAutoscaler/spec/databaseRef/name') - watchDependency('discriminator#/autoscalingType') - return ( - !!getValue(model, '/resources/autoscalingKubedbComMariaDBAutoscaler/spec/databaseRef/name') && - !!getValue(discriminator, '/autoscalingType') - ) -} + function showOpsRequestOptions() { + if (isKubedb() === true) return true + // watchDependency('model#/resources/autoscalingKubedbComMariaDBAutoscaler/spec/databaseRef/name') + // watchDependency('discriminator#/autoscalingType') + return ( + !!getValue(model, '/resources/autoscalingKubedbComMariaDBAutoscaler/spec/databaseRef/name') && + !!getValue(discriminator, '/autoscalingType') + ) + } -async function getNamespaces({ axios, storeGet }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function setApplyToIfReady() { + return 'IfReady' + } - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + /************* Monitoring *************/ - const resources = (resp && resp.data && resp.data.items) || [] + 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}` - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + const isKube = !!storeGet('/route/params/actions') -async function getMariaDbs({ axios, storeGet, model, getValue, watchDependency }) { - watchDependency('model#/metadata/namespace') - const namespace = getValue(model, '/metadata/namespace') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + if (isKube) return pathConstructedForKubedb + else + return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/mariadbopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` + } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/mariadbs`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + function onNamespaceChange() { + const namespace = getValue(model, '/metadata/namespace') + if (!namespace) { + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComMariaDBAutoscaler/spec/databaseRef/name', + ) + } + } - const resources = (resp && resp.data && resp.data.items) || [] + function setValueFrom() { + if (isConfigMapTypeValueFrom()) { + return 'configMap' + } else if (isSecretTypeValueFrom()) { + return 'secret' + } else { + return 'input' + } + } - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, + 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 initMetadata({ getValue, discriminator, model, commit, storeGet }) { - const dbName = - getValue(model, '/resources/autoscalingKubedbComMariaDBAutoscaler/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: '/metadata/name', - value: modifiedName, - force: true, - }) + // function isEqualToValueFromType(value) { + // //watchDependency('discriminator#/valueFromType') + // const valueFrom = getValue(discriminator, '/valueFromType') + // return valueFrom === value + // } - // delete the other type object from vuex wizard model - if (type === 'compute') - commit('wizard/model$delete', '/resources/autoscalingKubedbComMariaDBAutoscaler/spec/storage') - if (type === 'storage') - commit('wizard/model$delete', '/resources/autoscalingKubedbComMariaDBAutoscaler/spec/compute') -} + async function resourceNames(group, version, resource) { + const namespace = getValue(model, '/metadata/release/namespace') + // watchDependency('model#/metadata/release/namespace') -function onNamespaceChange({ model, getValue, commit }) { - const namespace = getValue(model, '/metadata/namespace') - if (!namespace) { - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComMariaDBAutoscaler/spec/databaseRef/name', - ) - } -} + let resources = await getNamespacedResourceList(axios, storeGet, { + namespace, + group, + version, + resource, + }) -function ifScalingTypeEqualsTo( - { storeGet, watchDependency, getValue, discriminator, model }, - type, -) { - watchDependency('discriminator#/autoscalingType') - watchDependency('model#/resources/autoscalingKubedbComMariaDBAutoscaler/spec/databaseRef/name') - - const operation = storeGet('/route/params/actions') || '' - if (operation.length) { - const splitOp = operation.split('-') - if (splitOp.length > 2) autoscaleType = splitOp[2] - } else autoscaleType = getValue(discriminator, '/autoscalingType') || '' - const isDatabaseSelected = !!getValue( - model, - '/resources/autoscalingKubedbComMariaDBAutoscaler/spec/databaseRef/name', - ) - return autoscaleType === type && isDatabaseSelected -} + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } -async function fetchNodeTopology({ axios, storeGet }) { - 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 resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } }) - return mappedList - } catch (e) { - console.log(e) } - return [] -} -function isNodeTopologySelected({ watchDependency, model, getValue }) { - watchDependency( - 'model#/resources/autoscalingKubedbComMariaDBAutoscaler/spec/compute/nodeTopology/name', - ) - const nodeTopologyName = - getValue( + 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/autoscalingKubedbComMariaDBAutoscaler/spec/compute/nodeTopology/name', - ) || '' - return !!nodeTopologyName.length -} - -function setControlledResources({ commit }, type) { - const list = ['cpu', 'memory'] - const path = `/resources/autoscalingKubedbComMariaDBAutoscaler/spec/compute/${type}/controlledResources` - commit('wizard/model$update', { - path: path, - value: list, - force: true, - }) - return list -} + `/resources/kubedbComMariaDB/spec/monitor/prometheus/exporter/env/${index}/valueFrom/configMapKeyRef/name`, + ) -function setTrigger({ model, getValue }, path) { - let value = getValue(model, `/resources/${path}`) - if (value) return value - return 'On' -} + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/configMapKeyRef/name') -function setApplyToIfReady() { - return 'IfReady' -} + if (!configMapName) return [] -async function getDbDetails({ setDiscriminatorValue, commit, axios, storeGet, getValue, model }) { - 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, '/resources/autoscalingKubedbComMariaDBAutoscaler/spec/databaseRef/name') || - '' - - if (namespace && name) { try { const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/mariadbs/${name}`, + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/configmaps/${configMapName}`, ) - dbDetails = resp.data || {} - setDiscriminatorValue('/dbDetails', true) + + 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 [] } } - commit('wizard/model$update', { - path: `/metadata/release/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/metadata/release/namespace`, - value: namespace, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComMariaDBAutoscaler/spec/databaseRef/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComMariaDBAutoscaler/metadata/labels`, - value: dbDetails.metadata.labels, - force: true, - }) -} + 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') -function objectCopy(obj) { - const temp = JSON.stringify(obj) - return JSON.parse(temp) -} + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }, + ) -function isBindingAlreadyOn({ model, getValue }) { - const value = getValue(model, '/resources') - const keys = Object.keys(value) - isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComMariaDBBinding') - return isExposeBinding -} + const secrets = (resp && resp.data && resp.data.items) || [] -async function addOrRemoveBinding({ commit, model, getValue, discriminator }) { - const value = getValue(discriminator, `/binding`) - const dbName = getValue(model, '/metadata/release/name') - const dbNamespace = getValue(model, '/metadata/release/namespace') - const labels = getValue(model, '/resources/kubedbComMariaDB/metadata/labels') - const bindingValues = { - apiVersion: 'catalog.appscode.com/v1alpha1', - kind: 'MariaDBBinding', - metadata: { - labels, - name: dbName, - namespace: dbNamespace, - }, - spec: { - sourceRef: { - name: dbName, - namespace: dbNamespace, - }, - }, - } + const filteredSecrets = secrets.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) - if (value) { - await commit('wizard/model$update', { - path: '/resources/catalogAppscodeComMariaDBBinding', - value: bindingValues, - force: true, - }) - } else { - await commit('wizard/model$delete', '/resources/catalogAppscodeComMariaDBBinding') + 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 fetchTopologyMachines({ axios, getValue, storeGet, model, setDiscriminatorValue }) { - const instance = hasAnnotations({ model, getValue }) + 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/kubedbComMariaDB/spec/monitor/prometheus/exporter/env/${index}/valueFrom/secretKeyRef/name`, + ) + + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/secretKeyRef/name') + + if (!secretName) return [] - 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 resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets/${secretName}`, + ) - const nodeGroups = resp.data?.spec?.nodeGroups || [] - setDiscriminatorValue('/topologyMachines', nodeGroups) - return nodeGroups + 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 setAllowedMachine({ model, getValue }, minmax) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComMariaDBAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - const mx = instance?.includes(',') ? instance.split(',')[1] : '' - const mn = instance?.includes(',') ? instance.split(',')[0] : '' - - if (minmax === 'min') return mn - else return mx -} + /************* Binding *************/ -async function getMachines({ getValue, watchDependency, discriminator }, minmax) { - watchDependency('discriminator#/topologyMachines') - const depends = minmax === 'min' ? 'max' : 'min' - const dependantPath = `/allowedMachine-${depends}` - - watchDependency(`discriminator#${dependantPath}`) - const dependantMachine = getValue(discriminator, dependantPath) - - const nodeGroups = getValue(discriminator, '/topologyMachines') || [] - - const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) + function isBindingAlreadyOn() { + const value = getValue(model, '/resources') + const keys = Object.keys(value) + const isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComMariaDBBinding') + return isExposeBinding + } - const machines = nodeGroups?.map((item) => { - const subText = `CPU: ${item.allocatable.cpu}, Memory: ${item.allocatable.memory}` - const text = item.topologyValue - return { text, subText, value: item.topologyValue } - }) + 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/kubedbComMariaDB/metadata/labels') + const bindingValues = { + apiVersion: 'catalog.appscode.com/v1alpha1', + kind: 'MariaDBBinding', + metadata: { + labels, + name: dbName, + namespace: dbNamespace, + }, + spec: { + sourceRef: { + name: dbName, + namespace: dbNamespace, + }, + }, + } - const filteredMachine = machines?.filter((item, ind) => - minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, - ) + if (value) { + commit('wizard/model$update', { + path: '/resources/catalogAppscodeComMariaDBBinding', + value: bindingValues, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/catalogAppscodeComMariaDBBinding') + } + } - return dependantIndex === -1 ? machines : filteredMachine -} + function returnFalse() { + return false + } -function hasAnnotations({ model, getValue }) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComMariaDBAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] + 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, + }) + } + } + } - return !!instance -} + 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 + }) -function hasNoAnnotations({ model, getValue }) { - return !hasAnnotations({ model, getValue }) -} + if (filteredEnv.length) + commit('wizard/model$update', { + path: '/resources/kubedbComMariaDB/spec/monitor/prometheus/exporter/env', + value: filteredEnv, + force: true, + }) + } -function onMachineChange({ model, getValue, discriminator, commit }, type) { - const annoPath = '/resources/autoscalingKubedbComMariaDBAutoscaler/metadata/annotations' - const annotations = getValue(model, annoPath) - const instance = annotations['kubernetes.io/instance-type'] + function initEnvArray() { + const env = getValue(model, '/resources/kubedbComMariaDB/spec/monitor/prometheus/exporter/env') - const minMachine = getValue(discriminator, '/allowedMachine-min') - const maxMachine = getValue(discriminator, '/allowedMachine-max') - const minMaxMachine = `${minMachine},${maxMachine}` - annotations['kubernetes.io/instance-type'] = minMaxMachine + return env || [] + } - const machines = getValue(discriminator, `/topologyMachines`) || [] - const minMachineObj = machines.find((item) => item.topologyValue === minMachine) - const maxMachineObj = machines.find((item) => item.topologyValue === maxMachine) - const minMachineAllocatable = minMachineObj?.allocatable - const maxMachineAllocatable = maxMachineObj?.allocatable - const allowedPath = `/resources/autoscalingKubedbComMariaDBAutoscaler/spec/compute/${type}` + function isEqualToTemp(value, index) { + //watchDependency('discriminator#/valueFromType') + const valueFrom = getValue(discriminator, `/env/${index}/temp/valueFromType`) + return valueFrom === value + } - 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 initMonitoring() { + const env = + getValue(model, '/resources/kubedbComMariaDB/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 { - getDbDetails, - isConsole, - getNamespaces, - getMariaDbs, - isKubedb, - initMetadata, - onNamespaceChange, - ifScalingTypeEqualsTo, - fetchNodeTopology, - isNodeTopologySelected, - setControlledResources, - setTrigger, - setApplyToIfReady, - showOpsRequestOptions, - fetchNames, - isRancherManaged, - fetchNamespaces, - onInputChangeSchedule, - getDefaultSchedule, - getDefault, - onInputChange, - showBackupOptions, - showScheduleBackup, - isVariantAvailable, - fetchJsons, - disableLableChecker, - isEqualToModelPathValue, - getResources, - isEqualToDiscriminatorPath, - setValueFromModel, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - returnTrue, - returnStringYes, - getMariaDbVersions, - showAuthPasswordField, - showAuthSecretField, - showNewSecretCreateField, - setDatabaseMode, - getStorageClassNames, - deleteDatabaseModePath, - isEqualToDatabaseMode, - setApiGroup, - getIssuerRefsName, - hasIssuerRefName, - hasNoIssuerRefName, - setSSLMode, - showTlsConfigureSection, - onTlsConfigureChange, - getAliasOptions, - showMonitoringSection, - onEnableMonitoringChange, - showCustomizeExporterSection, - onCustomizeExporterChange, - valueExists, - initPrePopulateDatabase, - onPrePopulateDatabaseChange, - initDataSource, - onDataSourceChange, - initVolumeType, - onVolumeTypeChange, - showInitializationForm, - showScriptOrStashForm, - showConfigMapOrSecretName, - initializeNamespace, - showRepositorySelectOrCreate, - onInitRepositoryChoiseChange, - initCustomizeRestoreJobRuntimeSettings, - initCustomizeRestoreJobRuntimeSettingsForBackup, - onCustomizeRestoreJobRuntimeSettingsChange, - onCustomizeRestoreJobRuntimeSettingsChangeForBackup, - showRuntimeForm, - getImagePullSecrets, - getBackupConfigsAndAnnotations, - deleteKubeDbComMariaDbAnnotation, - addKubeDbComMariaDbAnnotation, - initScheduleBackup, - initScheduleBackupForEdit, - onScheduleBackupChange, - showBackupForm, - initalizeTargetReferenceName, - setInitialRestoreSessionRepo, - initRepositoryChoise, - initRepositoryChoiseForEdit, - onRepositoryChoiseChange, - onRepositoryNameChange, - getMongoAnnotations, - initFromAnnotationValue, - onBackupBlueprintNameChange, - onBackupBlueprintScheduleChange, - initFromAnnotationKeyValue, - onTaskParametersChange, - isValueExistInModel, - onNamespaceChange, - onLabelChange, - onNameChange, - returnFalse, - onAgentChange, - getCreateAuthSecret, - showExistingSecretSection, - showPasswordSection, - disableInitializationSection, - setAuthSecretPassword, - onAuthSecretPasswordChange, - encodePassword, - decodePassword, - onCreateAuthSecretChange, - getSecrets, - isEqualToServiceMonitorType, - onConfigurationSourceChange, - onConfigurationChange, - setConfigurationSource, - setSecretConfigNamespace, - setConfiguration, - setConfigurationFiles, - onSetCustomConfigChange, - getOpsRequestUrl, - getCreateNameSpaceUrl, - setStorageClass, - - initBackupData, - isBackupDataLoadedTrue, - setBackupType, - getTypes, - getNamespaceArray, - isBackupType, - getContext, - onContextChange, - getConfigList, - onConfigChange, - showPause, - showSchedule, - showConfigList, - setBlueprintSwitch, - onBlueprintChange, - setArchiverSwitch, - onArchiverChange, - onBackupTypeChange, - isBindingAlreadyOn, - addOrRemoveBinding, - getMachines, - setAllowedMachine, - hasAnnotations, - hasNoAnnotations, - fetchTopologyMachines, - onMachineChange, + 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, + getBackupConfigsAndAnnotations, + deleteKubeDbComMariaDbAnnotation, + valueExists, + setPausedValue, + + getDbDetails, + isKubedb, + isConsole, + getNamespaces, + isRancherManaged, + onNamespaceChange, + getMariaDbs, + initMetadata, + fetchTopologyMachines, + setTrigger, + onTriggerChange, + hasAnnotations, + setAllowedMachine, + getMachines, + onMachineChange, + hasNoAnnotations, + setControlledResources, + fetchNodeTopology, + isNodeTopologySelected, + showOpsRequestOptions, + setApplyToIfReady, + setValueFromDbDetails, + + handleUnit, + + getOpsRequestUrl, + isValueExistInModel, + onEnableMonitoringChange, + showMonitoringSection, + onAgentChange, + getResources, + isEqualToModelPathValue, + onCustomizeExporterChange, + showCustomizeExporterSection, + onLabelChange, + setValueFrom, + onValueFromChange, + resourceNames, + getConfigMapKeys, + getSecrets, + getSecretKeys, + isConfigMapTypeValueFrom, + isSecretTypeValueFrom, + getNamespacedResourceList, + onEnvArrayChange, + initEnvArray, + isEqualToTemp, + initMonitoring, + + isBindingAlreadyOn, + addOrRemoveBinding, + returnFalse, + } } diff --git a/charts/kubedbcom-memcached-editor-options/ui/create-ui.yaml b/charts/kubedbcom-memcached-editor-options/ui/create-ui.yaml index b3c2e1f530..d74b4dc185 100644 --- a/charts/kubedbcom-memcached-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-memcached-editor-options/ui/create-ui.yaml @@ -1,255 +1,237 @@ -steps: -- form: - discriminator: - bundleApiLoaded: - default: false - type: boolean +step: +- type: single-step-form + loader: initBundle + elements: + - type: label-element + label: '' + subtitle: Select the Memcached version you want to deploy on Kubernetes. The chosen version determines the Memcached engine features, compatibility, and runtime behavior of your database. + - disableUnselect: true + loader: getAdminOptions|databases/Memcached/versions + if: + type: function + name: isToggleOn|databases/Memcached/versions + label: Database version + schema: schema/properties/spec/properties/admin/properties/databases/properties/Memcached/properties/versions/properties/default + type: select + - init: + type: func + value: getDefault|databases/Memcached/mode + loader: getAdminOptions|databases/Memcached/mode + if: + type: function + name: isToggleOn|databases/Memcached/mode + isHorizontal: true + label: Database mode + schema: schema/properties/spec/properties/mode + type: radio + - if: + type: function + name: isEqualToModelPathValue|Replicaset|/spec/mode + label: Replicaset number + schema: schema/properties/spec/properties/replicas + type: input + - elements: + - type: label-element + label: '' + subtitle: Select a machine profile to allocate CPU and memory resources for your database. Choose 'custom' to manually specify resource requirements or select a predefined profile. + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu + if: + type: function + name: isMachineCustom + label: cpu + watcher: + func: setRequests|cpu + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory + if: + type: function + name: isMachineCustom + label: memory + watcher: + func: setRequests|memory + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + label: Machine_profile + showLabels: true + type: block-layout + - description: Configure Credentials, Deployment Mode etc. elements: - - computed: initBundle - if: returnFalse - type: label-element - - disableUnselect: true - fetch: getAdminOptions|databases/Memcached/versions - if: isToggleOn|databases/Memcached/versions - label: - text: labels.database.version - schema: - $ref: schema#/properties/spec/properties/admin/properties/databases/properties/Memcached/properties/versions/properties/default + - elements: + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/annotations + label: Labels & Annotations + showLabels: true + hideBlock: true + type: block-layout + - init: + type: func + value: getDefault|deletionPolicy + customClass: mt-20 + if: + type: function + name: isToggleOn|deletionPolicy + label: Deletion Policy + options: + - description: options.deletionPolicy.delete.description + text: Delete + value: Delete + - description: options.deletionPolicy.halt.description + text: Halt + value: Halt + - description: options.deletionPolicy.wipeOut.description + text: WipeOut + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: DoNotTerminate + value: DoNotTerminate + schema: schema/properties/spec/properties/deletionPolicy type: select - - computed: getDefault|databases/Memcached/mode - fetch: getAdminOptions|databases/Memcached/mode - hasDescription: true - if: isToggleOn|databases/Memcached/mode - label: - text: labels.database.mode - schema: - $ref: schema#/properties/spec/properties/mode - type: radio - - if: isEqualToModelPathValue|Replicaset|/spec/mode - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/replicas + - if: + type: function + name: getDefaultValue|spec/admin/authCredential/customize + label: Provide Authentication Credentials? + watcher: + func: onAuthChange + paths: + - temp/createAuthSecret + schema: temp/createAuthSecret + type: switch + - if: + type: function + name: showReferSecretSwitch + label: Refer existing Secret? + watcher: + func: onReferSecretChange + paths: + - temp/referSecret + schema: temp/referSecret + type: switch + - loader: getReferSecrets + if: + type: function + name: showSecretDropdown + label: Secret + schema: schema/properties/spec/properties/authSecret/properties/name + type: select + - if: + type: function + name: showReferSecret + label: password + schema: schema/properties/spec/properties/authSecret/properties/password type: input + - if: + type: function + name: getDefaultValue|spec/admin/customConfiguration + label: Configure Database? + watcher: + func: clearConfiguration + paths: + - temp/configDatabase + schema: temp/configDatabase + type: switch + - if: + type: function + name: isConfigDatabaseOn + label: Configuration + # hasCopy: true + schema: schema/properties/spec/properties/configuration + type: textarea + - if: + type: function + name: isToggleOn|deployment + label: Deployment name + options: + - description: labels.deployment.shared + text: Shared + value: Shared + - description: labels.deployment.dedicated + text: Dedicated + value: Dedicated + schema: schema/properties/spec/properties/admin/properties/deployment/properties/default + type: radio + - if: + type: function + name: isToggleOn|clusterTier + isHorizontal: true + label: Cluster Tier + options: + - text: General Purpose + value: GeneralPurpose + - text: Memory Optimized + value: MemoryOptimized + - text: CPU Optimized + value: CPUOptimized + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/default + type: radio + - disableUnselect: true + loader: getAdminOptions|clusterTier/placement + if: + type: function + name: isToggleOn|clusterTier/placement + label: Placement + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + type: select + - disableUnselect: true + loader: getNodeTopology + if: + type: function + name: isToggleOn|clusterTier/nodeTopology + label: Node Topology + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + type: select + label: Advanced Configuration + showLabels: true + type: block-layout + - description: Enable Backup, Monitoring, TLS etc. + elements: - elements: - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.cpu - onChange: setRequests|cpu - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.memory - onChange: setRequests|memory - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - label: - text: labels.machine_profile - show_label: true - type: single-step-form - - accordion: true - description: - text: Configure Credentials, Deployment Mode etc. - discriminator: - configDatabase: - default: false - type: boolean - createAuthSecret: - default: false - type: boolean - referSecret: - default: false - type: boolean - elements: - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties - type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties - type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - computed: getDefault|deletionPolicy - customClass: mt-20 - if: isToggleOn|deletionPolicy - label: - text: labels.deletionPolicy - 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/spec/properties/deletionPolicy - type: select - - if: getDefaultValue|spec/admin/authCredential/customize - label: - text: Provide Authentication Credentials? - onChange: onAuthChange - schema: - $ref: discriminator#/createAuthSecret - type: switch - - if: showReferSecretSwitch - label: - text: Refer existing Secret? - onChange: onReferSecretChange - schema: - $ref: discriminator#/referSecret + - init: + type: func + value: setMonitoring + label: Enable Monitoring? + watcher: + func: updateAlertValue + paths: + - temp/monitoring + schema: temp/monitoring type: switch - - fetch: getReferSecrets - if: showSecretDropdown - label: - text: Secret - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/name - type: select - - if: showReferSecret - label: - text: labels.password - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/password - type: input - - computed: isConfigAvailable - if: getDefaultValue|spec/admin/customConfiguration - label: - text: Configure Database? - onChange: clearConfiguration - schema: - $ref: discriminator#/configDatabase - type: switch - - if: isConfigDatabaseOn - label: - text: Configuration - schema: - $ref: schema#/properties/spec/properties/configuration - type: editor - - hasDescription: true - if: isToggleOn|deployment - label: - text: labels.deployment.name - options: - - description: labels.deployment.shared - text: Shared - value: Shared - - description: labels.deployment.dedicated - text: Dedicated - value: Dedicated - schema: - $ref: schema#/properties/spec/properties/admin/properties/deployment/properties/default - type: radio - - if: isToggleOn|clusterTier - isHorizontal: true - label: - text: labels.clusterTier - options: - - text: General Purpose - value: GeneralPurpose - - text: Memory Optimized - value: MemoryOptimized - - text: CPU Optimized - value: CPUOptimized - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/default - type: radio - - disableUnselect: true - fetch: getAdminOptions|clusterTier/placement - if: isToggleOn|clusterTier/placement - label: - text: labels.placement - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default - type: select - - disableUnselect: true - fetch: getNodeTopology - if: isToggleOn|clusterTier/nodeTopology - label: - text: labels.nodeTopology - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default - type: select - hideForm: true - label: - text: Advanced Configuration - show_label: true - type: single-step-form - - accordion: true - description: - text: Enable Backup, Monitoring, TLS etc. - discriminator: - backup: - default: false - type: boolean - elements: - - discriminator: - monitoring: - default: false - type: boolean - elements: - - computed: setMonitoring - label: - text: labels.enable_monitoring - onChange: updateAlertValue - schema: - $ref: discriminator#/monitoring - type: switch - if: isToggleOn|monitoring - type: single-step-form - if: showAdditionalSettings - label: - text: Additional Options - show_label: true - type: single-step-form - type: single-step-form + if: + type: function + name: isToggleOn|monitoring + type: block-layout + if: + type: function + name: showAdditionalSettings + label: Additional Options + showLabels: true + type: block-layout id: options - title: steps.0.label + # title: steps.0.label type: multi-step-form diff --git a/charts/kubedbcom-memcached-editor-options/ui/functions.js b/charts/kubedbcom-memcached-editor-options/ui/functions.js index 67b50d4b73..6cd99ec320 100644 --- a/charts/kubedbcom-memcached-editor-options/ui/functions.js +++ b/charts/kubedbcom-memcached-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -315,743 +317,810 @@ const modeDetails = { }, } -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], + setDiscriminatorValue('bundleApiLoaded', false) + setDiscriminatorValue('configDatabase', false) + setDiscriminatorValue('createAuthSecret', false) + setDiscriminatorValue('referSecret', false) + setDiscriminatorValue('backup', false) + setDiscriminatorValue('monitoring', false) + + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } + + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, }, - }, - ) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] + ) + if (resp.data?.status?.projects) { + const projects = resp.data?.status?.projects + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } + } catch (e) { + console.log(e) } - } catch (e) { - console.log(e) + return [] } - return [] -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } + + async function getMemcachedVersions(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -async function getMemcachedVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + const queryParams = { + filter: { + items: { + metadata: { name: null }, + spec: { version: null, deprecated: null }, + }, + }, + } - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: queryParams, }, - }, - } + ) - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) + const resources = (resp && resp.data && resp.data.items) || [] - const resources = (resp && resp.data && resp.data.items) || [] + // keep only non deprecated versions + const filteredMemcachedVersions = resources.filter((item) => item.spec && !item.spec.deprecated) - // keep only non deprecated versions - const filteredMemcachedVersions = resources.filter((item) => item.spec && !item.spec.deprecated) + filteredMemcachedVersions.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + const specVersion = (item.spec && item.spec.version) || '' + item.text = `${name} (${specVersion})` + item.value = name + return true + }) + return filteredMemcachedVersions + } - filteredMemcachedVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredMemcachedVersions -} + 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') -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, + 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 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) - }) + 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 -} + filteredSecrets.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true + }) + return filteredSecrets + } -function getMachineListForOptions({ model, getValue }) { - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') let array = [] + function getMachineListForOptions() { + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') - if (available.length) { - array = available.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - else { - let subText = '', - text = '' - const machineData = machinesFromPreset.find((val) => val.id === machine) - if (machineData) { - subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` - text = machineData.name ? machineData.name : machineData.id - } - return { text, subText, value: machine } - } - }) - } else { - array = machineList - .map((machine) => { + if (available.length) { + array = available.map((machine) => { if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + else { + let subText = '', + text = '' + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + text = machineData.name ? machineData.name : machineData.id + } + return { text, subText, value: machine } + } }) - .filter((val) => !!val) + } else { + array = machineList + .map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { text, subText, value: machine } + }) + .filter((val) => !!val) + } + return array } - return array -} -function setLimits({ model, getValue, commit, watchDependency }, resource, type) { - const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' - watchDependency(`model#${path}`) - const selectedMachine = getValue(model, path) || 'custom' - const reqCommitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - const comparePath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - - const resourceValue = getValue(model, comparePath) - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - - let cpu = '', - memory = '' - if (available.length && selectedMachine !== 'custom') { - const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) - if (machineData) { - cpu = machineData.limits.cpu - memory = machineData.limits.memory + function setLimits(resource, type) { + const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' + // watchDependency(`model#${path}`) + const selectedMachine = getValue(model, path) || 'custom' + const reqCommitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + const comparePath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + + const resourceValue = getValue(model, comparePath) + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + let cpu = '', + memory = '' + if (available.length && selectedMachine !== 'custom') { + const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) + if (machineData) { + cpu = machineData.limits.cpu + memory = machineData.limits.memory + } + } else { + if (selectedMachine === 'custom') { + cpu = resourceValue + memory = resourceValue + } else { + cpu = machines[selectedMachine].resources.limits.cpu + memory = machines[selectedMachine].resources.limits.memory + } } - } else { - if (selectedMachine === 'custom') { - cpu = resourceValue - memory = resourceValue + + if (resource === 'memory') { + commit('wizard/model$update', { + path: reqCommitPath, + value: memory, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: memory, + force: true, + }) + return memory } else { - cpu = machines[selectedMachine].resources.limits.cpu - memory = machines[selectedMachine].resources.limits.memory + commit('wizard/model$update', { + path: reqCommitPath, + value: cpu, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: cpu, + force: true, + }) + return cpu } } - if (resource === 'memory') { + function setRequests(resource, type) { + const modelPath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + + const fullpath = `/spec/podResources/machine` + const modelPathValue = getValue(model, fullpath) + commit('wizard/model$update', { - path: reqCommitPath, - value: memory, + path: commitPath, + value: val, force: true, }) - commit('wizard/model$update', { - path: comparePath, - value: memory, - force: true, + + if (modelPathValue === 'custom') { + return + } + let commitCpuMemory, ModelPathValue + if (resource && type) { + const fullPath = `/spec/${type}/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/${type}/podResources/resources/requests/${resource}` + } else { + const fullPath = `/spec/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/podResources/resources/requests/${resource}` + } + let cpuMemoryValue + array.forEach((item) => { + if (item.value === ModelPathValue) { + // Parse subText like "CPU: 2, Memory: 2Gi" + const subText = item.subText || '' + if (resource === 'cpu') { + // Extract CPU value + const cpuMatch = subText.match(/CPU:\s*([^,]+)/) + cpuMemoryValue = cpuMatch ? cpuMatch[1].trim() : '' + } else if (resource === 'memory') { + // Extract Memory value + const memoryMatch = subText.match(/Memory:\s*(.+)/) + cpuMemoryValue = memoryMatch ? memoryMatch[1].trim() : '' + } + } }) - return memory - } else { commit('wizard/model$update', { - path: reqCommitPath, - value: cpu, + path: commitCpuMemory, + value: cpuMemoryValue, force: true, }) + return cpuMemoryValue + } + + function setRequests(resource) { + const modelPath = `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + commitPath = `/spec/podResources/resources/limits/${resource}` commit('wizard/model$update', { - path: comparePath, - value: cpu, + path: commitPath, + value: val, force: true, }) - return cpu } -} - -function setRequests({ getValue, model, commit }, resource) { - const modelPath = `/spec/podResources/resources/requests/${resource}` - const val = getValue(model, modelPath) - commitPath = `/spec/podResources/resources/limits/${resource}` - commit('wizard/model$update', { - path: commitPath, - value: val, - force: true, - }) -} - -function setMachineToCustom({ getValue, model }) { - const machine = getValue(model, '/spec/admin/machineProfiles/default') - return machine || 'custom' -} - -function isMachineCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue === 'custom' -} - -function isMachineNotCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue !== 'custom' && !!modelPathValue -} - -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + function setMachineToCustom() { + const machine = getValue(model, '/spec/admin/machineProfiles/default') + return machine || 'custom' } -} -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} - -function showAlerts({ watchDependency, model, getValue, discriminator }) { - watchDependency('discriminator#/monitoring') - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const isAlertToggleEnabled = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'alert', - ) - return isMonitorEnabled && isAlertToggleEnabled -} - -function updateAlertValue({ commit, model, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const alert = isMonitorEnabled ? 'warning' : 'none' - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: alert, - force: true, - }) - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} - -function onBackupSwitch({ discriminator, getValue, commit }) { - const isBackupOn = getValue(discriminator, '/backup') - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: isBackupOn ? 'KubeStash' : '', - force: true, - }) -} - -function showIssuer({ model, getValue, watchDependency, discriminator }) { - watchDependency('model#/spec/admin/tls/default') - const isTlsEnabled = getValue(model, '/spec/admin/tls/default') - const isIssuerToggleEnabled = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'clusterIssuers', - ) - return isTlsEnabled && isIssuerToggleEnabled -} - -function setMonitoring({ getValue, model }) { - const agent = getValue(model, '/spec/admin/monitoring/agent') || '' - return !!agent -} - -function setBackup({ model, getValue }) { - const backup = getValue(model, '/spec/backup/tool') - const val = getValue(model, '/spec/admin/backup/enable/default') - return backup === 'KubeStash' && features.includes('backup') && val -} - -function onAuthChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/authSecret/password', - value: '', - force: true, - }) -} - -function isConfigDatabaseOn({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configDatabase') - return getValue(discriminator, '/configDatabase') -} - -function clearConfiguration({ discriminator, getValue, commit }) { - const configOn = getValue(discriminator, '/configDatabase') + function isMachineCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue === 'custom' + } - if (!configOn) { - commit('wizard/model$delete', '/spec/configuration') + function isMachineNotCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue !== 'custom' && !!modelPathValue } -} -function updateAgentValue({ commit, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} + function getCreateNameSpaceUrl() { + const user = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -let placement = [] -let versions = [] -let storageClass = [] -let clusterIssuers = [] -let nodetopologiesShared = [] -let nodetopologiesDedicated = [] -let features = [] -async function initBundle({ commit, model, getValue, axios, storeGet, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - - let db = getValue(model, '/metadata/resource/kind') - db = db.toLowerCase() - let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` - try { - const resp = await axios.get(url) - features = resp.data.features || [] - placement = resp.data.placementpolicies || [] - versions = resp.data.versions || [] - storageClass = resp.data.storageclasses || [] - clusterIssuers = resp.data.clusterissuers || [] - nodetopologiesDedicated = resp.data.dedicated || [] - nodetopologiesShared = resp.data.shared || [] - } catch (e) { - console.log(e) + const domain = storeGet('/domain') || '' + if (domain.includes('bb.test')) { + return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } } - commit('wizard/model$update', { - path: '/spec/deletionPolicy', - value: getDefault({ getValue, model }, 'deletionPolicy'), - force: true, - }) - - if (!getValue(model, `/spec/admin/databases/Memcached/mode/toggle`)) { - let defMode = getDefault({ getValue, model }, 'databases/Memcached/mode') || '' - if (defMode === '') { - const arr = getValue(model, '/spec/databases/Memcached/mode/available') || [] - if (arr.length) defMode = arr[0] - } - commit('wizard/model$update', { - path: '/spec/mode', - value: defMode, - force: true, - }) + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false } - if (!features.includes('tls')) { - commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: false, - force: true, - }) + function showAlerts() { + // watchDependency('discriminator#/monitoring') + const isMonitorEnabled = getValue(discriminator, '/monitoring') + return isMonitorEnabled && isToggleOn('alert') } - if (!features.includes('binding')) { + + function updateAlertValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const alert = isMonitorEnabled ? 'warning' : 'none' + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: '/spec/admin/expose/default', - value: false, + path: '/form/alert/enabled', + value: alert, force: true, }) - } - if (!features.includes('monitoring')) { + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' commit('wizard/model$update', { path: '/spec/admin/monitoring/agent', - value: '', + value: agent, force: true, }) + } + + function onBackupSwitch() { + const isBackupOn = getValue(discriminator, '/backup') commit('wizard/model$update', { - path: '/form/alert/enabled', - value: 'none', + path: '/spec/backup/tool', + value: isBackupOn ? 'KubeStash' : '', force: true, }) } - if (!features.includes('backup')) { + + function showIssuer() { + // watchDependency('model#/spec/admin/tls/default') + const isTlsEnabled = getValue(model, '/spec/admin/tls/default') + const isIssuerToggleEnabled = isToggleOn('clusterIssuers') + return isTlsEnabled && isIssuerToggleEnabled + } + + function setMonitoring() { + const agent = getValue(model, '/spec/admin/monitoring/agent') || '' + return !!agent + } + + function setBackup() { + const backup = getValue(model, '/spec/backup/tool') + const val = getValue(model, '/spec/admin/backup/enable/default') + return backup === 'KubeStash' && features.includes('backup') && val + } + + function onAuthChange() { commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, + path: '/spec/authSecret/name', + value: '', force: true, }) commit('wizard/model$update', { - path: '/spec/backup/tool', + path: '/spec/authSecret/password', value: '', force: true, }) } - setDiscriminatorValue('/bundleApiLoaded', true) -} + function isConfigDatabaseOn() { + // watchDependency('discriminator#/configDatabase') + return getValue(discriminator, '/configDatabase') + } + + function clearConfiguration() { + const configOn = getValue(discriminator, '/configDatabase') -function fetchOptions({ model, getValue, commit }, type) { - let kind = getValue(model, '/metadata/resource/kind') - - let returnArray = [] - if (type === 'clusterTier/placement') { - returnArray = placement - } else if (type === `databases/${kind}/versions`) { - returnArray = versions - } else if (type === 'storageClasses') { - returnArray = storageClass - } else if (type === 'clusterIssuers') { - returnArray = clusterIssuers + if (!configOn) { + commit('wizard/model$delete', '/spec/configuration') + } } - if (returnArray.length === 1) { - const path = `/spec/admin/${type}/default` + function updateAgentValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' commit('wizard/model$update', { - path: path, - value: returnArray[0], + path: '/spec/admin/monitoring/agent', + value: agent, force: true, }) } - return returnArray -} + let placement = [] + let versions = [] + let storageClass = [] + let clusterIssuers = [] + let nodetopologiesShared = [] + let nodetopologiesDedicated = [] + let features = [] + + async function initBundle() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + + let db = getValue(model, '/metadata/resource/kind') + db = db.toLowerCase() + let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` + try { + const resp = await axios.get(url) + features = resp.data.features || [] + placement = resp.data.placementpolicies || [] + versions = resp.data.versions || [] + storageClass = resp.data.storageclasses || [] + clusterIssuers = resp.data.clusterissuers || [] + nodetopologiesDedicated = resp.data.dedicated || [] + nodetopologiesShared = resp.data.shared || [] + } catch (e) { + console.log(e) + } -function getAdminOptions({ getValue, model, watchDependency, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') + commit('wizard/model$update', { + path: '/spec/deletionPolicy', + value: getDefault('deletionPolicy'), + force: true, + }) - const options = getValue(model, `/spec/admin/${type}/available`) || [] + if (!getValue(model, `/spec/admin/databases/Memcached/mode/toggle`)) { + let defMode = getDefault('databases/Memcached/mode') || '' + if (defMode === '') { + const arr = getValue(model, '/spec/databases/Memcached/mode/available') || [] + if (arr.length) defMode = arr[0] + } + commit('wizard/model$update', { + path: '/spec/mode', + value: defMode, + force: true, + }) + } - if (options.length === 0) { - return fetchOptions({ model, getValue, commit }, type) - } - if (type.endsWith('/mode')) { - return ( - options?.map((item) => ({ - description: modeDetails[item]?.description || '', - text: modeDetails[item]?.text || '', - value: item, - })) || [] - ) - } - return options -} + if (!features.includes('tls')) { + commit('wizard/model$update', { + path: '/spec/admin/tls/default', + value: false, + force: true, + }) + } + if (!features.includes('binding')) { + commit('wizard/model$update', { + path: '/spec/admin/expose/default', + value: false, + force: true, + }) + } + if (!features.includes('monitoring')) { + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: 'none', + force: true, + }) + } + if (!features.includes('backup')) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: '', + force: true, + }) + } -function checkIfFeatureOn({ getValue, model }, type) { - let val = getValue(model, `/spec/admin/${type}/toggle`) - if (type === 'backup' || type === 'archiver') { - val = getValue(model, `/spec/admin/${type}/enable/toggle`) - } - const backupVal = getValue(model, '/spec/backup/tool') - - if (type === 'backup') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } else if (type === 'tls') { - return features.includes('tls') && val - } else if (type === 'expose') { - return features.includes('binding') && val - } else if (type === 'monitoring') { - return features.includes('monitoring') && val - } else if (type === 'archiver') { - return features.includes('backup') && backupVal === 'KubeStash' && val + setDiscriminatorValue('/bundleApiLoaded', true) } -} -function isToggleOn({ getValue, model, discriminator, watchDependency }, type) { - watchDependency('discriminator#/bundleApiLoaded') - watchDependency('model#/spec/admin/deployment/default') - const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') - let deploymentType = getValue(model, `/spec/admin/deployment/default`) - if ( - type === 'tls' || - type === 'backup' || - type === 'expose' || - type === 'monitoring' || - type === 'archiver' - ) { - return checkIfFeatureOn({ getValue, model }, type) - } else if ( - type === 'clusterTier' || - type === 'clusterTier/placement' || - type === 'clusterTier/nodeTopology' - ) { - if (deploymentType === 'Dedicated' && bundleApiLoaded) return true - else return false - } else if (type === 'deployment') { - const deploymentType = getValue(model, '/spec/admin/deployment/default') - if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + function fetchOptions(type) { + let kind = getValue(model, '/metadata/resource/kind') + + let returnArray = [] + if (type === 'clusterTier/placement') { + returnArray = placement + } else if (type === `databases/${kind}/versions`) { + returnArray = versions + } else if (type === 'storageClasses') { + returnArray = storageClass + } else if (type === 'clusterIssuers') { + returnArray = clusterIssuers + } + + if (returnArray.length === 1) { + const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: '/spec/admin/deployment/default', - value: 'Shared', + path: path, + value: returnArray[0], force: true, }) } - return ( - getValue(model, `/spec/admin/${type}/toggle`) && - nodetopologiesDedicated.length && - bundleApiLoaded - ) - } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded -} -async function getNodeTopology({ model, getValue, axios, storeGet, watchDependency }) { - watchDependency('model#/spec/admin/deployment/default') - watchDependency('model#/spec/admin/clusterTier/default') - const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' - const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' - let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + return returnArray + } - const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + function getAdminOptions(type) { + // watchDependency('discriminator#/bundleApiLoaded') - if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared - else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + const options = getValue(model, `/spec/admin/${type}/available`) || [] - const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) - return filteredList -} + if (options.length === 0) { + return fetchOptions(type) + } + if (type.endsWith('/mode')) { + return ( + options?.map((item) => ({ + description: modeDetails[item]?.description || '', + text: modeDetails[item]?.text || '', + value: item, + })) || [] + ) + } + return options + } -function filterNodeTopology(list, tier, provider) { - // first filter the list from value that exists from the filtered list got from API - const filteredlist = list + let backupToolInitialValue = '' + function checkIfFeatureOn(type) { + let val = getValue(model, `/spec/admin/${type}/toggle`) + if (type === 'backup' || type === 'archiver') { + val = getValue(model, `/spec/admin/${type}/enable/toggle`) + } + const backupVal = getValue(model, '/spec/backup/tool') + if (type === 'backup') { + if (backupToolInitialValue === '') { + backupToolInitialValue = + features.includes('backup') && backupVal === 'KubeStash' && val ? 'on' : 'off' + return features.includes('backup') && backupVal === 'KubeStash' && val + } else { + if (backupToolInitialValue === 'on') { + return true + } else { + return false + } + } + } else if (type === 'tls') { + return features.includes('tls') && val + } else if (type === 'expose') { + return features.includes('binding') && val + } else if (type === 'monitoring') { + return features.includes('monitoring') && val + } else if (type === 'archiver') { + return features.includes('backup') && val + } + } - // filter the list based on clusterTier - if (provider === 'EKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('c') - else if (tier === 'MemoryOptimized') return item.startsWith('r') - else return !item.startsWith('c') && !item.startsWith('r') - }) - } else if (provider === 'AKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - else - return ( - !(item.startsWith('f') || item.startsWith('fx')) && - !( + function isToggleOn(type) { + // watchDependency('discriminator#/bundleApiLoaded') + // watchDependency('model#/spec/admin/deployment/default') + const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') + let deploymentType = getValue(model, `/spec/admin/deployment/default`) + if ( + type === 'tls' || + type === 'backup' || + type === 'expose' || + type === 'monitoring' || + type === 'archiver' + ) { + return checkIfFeatureOn(type) + } else if ( + type === 'clusterTier' || + type === 'clusterTier/placement' || + type === 'clusterTier/nodeTopology' + ) { + if (deploymentType === 'Dedicated' && bundleApiLoaded) return true + else return false + } else if (type === 'deployment') { + const deploymentType = getValue(model, '/spec/admin/deployment/default') + if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + commit('wizard/model$update', { + path: '/spec/admin/deployment/default', + value: 'Shared', + force: true, + }) + } + return ( + getValue(model, `/spec/admin/${type}/toggle`) && + nodetopologiesDedicated.length && + bundleApiLoaded + ) + } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded + } + + async function getNodeTopology() { + // watchDependency('model#/spec/admin/deployment/default') + // watchDependency('model#/spec/admin/clusterTier/default') + const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' + const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' + let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + + const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + + if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared + else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + + const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) + return filteredList + } + + function filterNodeTopology(list, tier, provider) { + // first filter the list from value that exists from the filtered list got from API + const filteredlist = list + + // filter the list based on clusterTier + if (provider === 'EKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('c') + else if (tier === 'MemoryOptimized') return item.startsWith('r') + else return !item.startsWith('c') && !item.startsWith('r') + }) + } else if (provider === 'AKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('e') || item.startsWith('eb') || item.startsWith('ec') || item.startsWith('m') || item.startsWith('d') ) - ) - }) - } else if (provider === 'GKE') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') - return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - else - return ( - !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && - !( + else + return ( + !(item.startsWith('f') || item.startsWith('fx')) && + !( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + ) + }) + } else if (provider === 'GKE') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') + return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('x4') || item.startsWith('m1') || item.startsWith('m2') || item.startsWith('m3') ) - ) - }) - } else return filteredlist -} + else + return ( + !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && + !( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + ) + }) + } else return filteredlist + } -function returnFalse() { - return false -} + function returnFalse() { + return false + } -function showAdditionalSettings({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return features.length -} + function showAdditionalSettings() { + // watchDependency('discriminator#/bundleApiLoaded') + return features.length + } -function getDefault({ getValue, model }, type) { - const val = getValue(model, `/spec/admin/${type}/default`) || '' - return val -} + function getDefault(type) { + const val = getValue(model, `/spec/admin/${type}/default`) || '' + return val + } -function isConfigAvailable({ getValue, model }) { - const val = getValue(model, '/spec/configuration') - return val !== '' -} + async function getReferSecrets() { + const referSecret = getValue(discriminator, '/referSecret') + if (!referSecret) { + return [] + } -async function getReferSecrets({ getValue, model, storeGet, axios, discriminator }) { - const referSecret = getValue(discriminator, '/referSecret') - if (!referSecret) { - return [] + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/metadata/release/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` + + const options = [] + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + return options } - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/metadata/release/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - - const options = [] - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) - } catch (e) { - console.log(e) + function showAuthPasswordField() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !modelPathValue && showReferSecret() } - return options -} -function showAuthPasswordField({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} - -function showSecretDropdown({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showSecretDropdown() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !!modelPathValue && showReferSecret() + } -function showReferSecret({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/createAuthSecret') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue -} + function showReferSecret() { + const modelPathValue = getValue(discriminator, '/createAuthSecret') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue + } -function getDefaultValue({ getValue, model }, path) { - const val = getValue(model, `/${path}`) || '' - return val -} + function getDefaultValue(path) { + const val = getValue(model, `/${path}`) || '' + return val + } -function showReferSecretSwitch({ model, getValue, watchDependency, discriminator }) { - const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showReferSecretSwitch() { + const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue && showReferSecret() + } -function onReferSecretChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) -} + function onReferSecretChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + } -return { - showReferSecretSwitch, - onReferSecretChange, - getDefaultValue, - isRancherManaged, - showSecretDropdown, - showReferSecret, - getReferSecrets, - isConfigAvailable, - updateAlertValue, - showAdditionalSettings, - initBundle, - returnFalse, - isVariantAvailable, - showAuthPasswordField, - isEqualToModelPathValue, - getNamespaces, - getMemcachedVersions, - getSecrets, - getMachineListForOptions, - setLimits, - setRequests, - setMachineToCustom, - isMachineNotCustom, - isMachineCustom, - getCreateNameSpaceUrl, - showAlerts, - onBackupSwitch, - showIssuer, - setMonitoring, - onAuthChange, - isConfigDatabaseOn, - clearConfiguration, - getNodeTopology, - filterNodeTopology, - updateAgentValue, - getAdminOptions, - isToggleOn, - setBackup, - getDefault, + return { + showReferSecretSwitch, + onReferSecretChange, + getDefaultValue, + isRancherManaged, + showSecretDropdown, + showReferSecret, + getReferSecrets, + updateAlertValue, + showAdditionalSettings, + initBundle, + returnFalse, + isVariantAvailable, + showAuthPasswordField, + isEqualToModelPathValue, + getNamespaces, + getMemcachedVersions, + getSecrets, + getMachineListForOptions, + setLimits, + setRequests, + setMachineToCustom, + isMachineNotCustom, + isMachineCustom, + getCreateNameSpaceUrl, + showAlerts, + onBackupSwitch, + showIssuer, + setMonitoring, + onAuthChange, + isConfigDatabaseOn, + clearConfiguration, + getNodeTopology, + filterNodeTopology, + updateAgentValue, + getAdminOptions, + isToggleOn, + setBackup, + getDefault, + } } diff --git a/charts/kubedbcom-memcached-editor/ui/edit-ui.yaml b/charts/kubedbcom-memcached-editor/ui/edit-ui.yaml index c7df872c8a..e8f40bda5c 100644 --- a/charts/kubedbcom-memcached-editor/ui/edit-ui.yaml +++ b/charts/kubedbcom-memcached-editor/ui/edit-ui.yaml @@ -1,460 +1,474 @@ -steps: -- form: - discriminator: - dbDetails: - default: false - type: boolean +type: multi-step-form +step: + - type: single-step-form + id: monitoring + loader: initMonitoring elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: Select Db - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: Select Type - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - discriminator: - topologyMachines: - default: [] - type: array + - type: label-element + label: To update Exporter Resource section click on Create OpsRequest + - type: anchor + label: Create OpsRequest + schema: temp/properties/opsRequestUrl + init: + type: func + value: getOpsRequestUrl|scale-vertically + - type: switch + label: Enable Monitoring + fullwidth: true + schema: temp/properties/enableMonitoring + init: + type: func + value: isValueExistInModel|/resources/kubedbComMemcached/spec/monitor + watcher: + func: onEnableMonitoringChange + paths: + - temp/properties/enableMonitoring + - type: block-layout + if: + type: function + name: showMonitoringSection elements: - - fetch: fetchTopologyMachines - if: returnFalse - schema: - $ref: discriminator#/topologyMachines - type: input - - elements: - - computed: setTrigger|autoscalingKubedbComMemcachedAutoscaler/spec/compute/memcached/trigger - label: - text: Trigger + - type: radio + label: Select a Monitoring Method + schema: schema/properties/resources/properties/kubedbComMemcached/properties/spec/properties/monitor/properties/agent + isHorizontal: true options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/memcached/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/memcached/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/memcached/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-max: - type: string - allowedMachine-min: - type: string + - text: Prometheus Operator + value: prometheus.io/operator + description: Inject metric exporter sidecar and creates a ServiceMonitor + - text: Custom ServiceMonitor + value: prometheus.io + description: Injects the metric exporter sidecar and let you customize ServiceMonitor + - text: Custom Scrapper + value: prometheus.io/builtin + description: Inject metric exporter sidecar and add Prometheus annotations to the stats Service + init: + type: static + value: prometheus.io/operator + watcher: + func: onAgentChange + paths: + - schema/properties/resources/properties/kubedbComMemcached/properties/spec/properties/monitor/properties/agent + - type: block-layout + label: ServiceMonitor Configuration + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComMemcached/spec/monitor/agent elements: - - computed: setAllowedMachine|min - disableUnselect: true - fetch: getMachines|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|memcached - schema: - $ref: discriminator#/properties/allowedMachine-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/memcached/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/memcached/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/memcached/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|max - disableUnselect: true - fetch: getMachines|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|memcached - schema: - $ref: discriminator#/properties/allowedMachine-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/memcached/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/memcached/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/memcached/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|memcached - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/memcached/properties/controlledResources - type: multiselect - label: - text: Memcached - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/memcached - show_label: true - type: single-step-form - - elements: - - fetch: fetchNodeTopology - label: - text: Select Node Topology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name - type: select - - if: isNodeTopologySelected - label: - text: ScaleUp Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage - type: input - - if: isNodeTopologySelected - label: - text: ScaleDown Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage - type: input - if: hasNoAnnotations - label: - text: NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/nodeTopology - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: compute-autoscaler - title: steps.6.label -- form: - discriminator: - enableMonitoring: - default: true - type: boolean + - label: Scrapping Interval + schema: schema/properties/resources/properties/kubedbComMemcached/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval + type: input + - type: block-layout + label: Service Monitor + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComMemcached/spec/monitor/agent + elements: + - type: array-object-form + label: Endpoints + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/endpoints + buttonClass: is-light is-outlined + elements: + - type: switch + label: Honor labels + fullwidth: true + schema: honorLabels + - type: input + label: Interval + schema: interval + validation: + type: required + - type: input + label: Path + schema: path + validation: + type: required + - type: input + label: Port + schema: port + validation: + type: required + - type: select + multiple: true + label: Match Namespaces + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/namespaceSelector/properties/matchNames + loader: getResources|core|v1|namespaces + if: + type: function + name: returnFalse + - type: block-layout + showLabels: false + if: + type: function + name: returnFalse + elements: + - type: object-item + label: Labels + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector/properties/matchLabels + - type: object-item + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/metadata/properties/labels + label : Labels + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComMemcached/spec/monitor/agent + - type: label-element + label: Exporter Configuration + schema: '' + - type: switch + label: Customize Exporter Sidecar + fullwidth: true + schema: temp/properties/customizeExporter + init: + type: static + value: true + watcher: + func: onCustomizeExporterChange + paths: + - temp/properties/customizeExporter + - type: block-layout + label: Customer Exporter Section + showLabels: false + if: + type: function + name: showCustomizeExporterSection + elements: + - type: machine-compare + label: Resources + schema: schema/properties/resources/properties/kubedbComMemcached/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/resources + if: + type: function + name: returnFalse + - type: label-element + label: Security Context + schema: '' + - type: input + schema: schema/properties/resources/properties/kubedbComMemcached/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsUser + label: Run as User + - type: input + schema: schema/properties/resources/properties/kubedbComMemcached/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup + label: Run as Group + - type: input + schema: schema/properties/resources/properties/kubedbComMemcached/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/port + label: Port + - type: array-item-form + label: Args + schema: schema/properties/resources/properties/kubedbComMemcached/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args + init: + type: static + value: ['--compatible-mode'] + element: + type: input + label: Args + - type: block-layout + label: Metadata + showLabels: false + elements: + - type: array-object-form + init: + type: func + value: initEnvArray + label: Environment Variables + buttonClass: is-light is-outlined + watcher: + func: onEnvArrayChange + paths: + - temp/properties/env + schema: temp/properties/env + elements: + - type: input + label: Name + schema: name + validation: + type: required + - type: radio + label: Value From + schema: temp/properties/valueFromType + validation: + type: required + init: + type: func + value: setValueFrom + options: + - text: Input + value: input + - text: Secret + value: secret + - text: ConfigMap + value: configMap + watcher: + func: onValueFromChange + paths: + - temp/properties/valueFromType + - type: input + label: Value + schema: value + validation: + type: required + if: + name: isEqualToTemp|input + type: function + - type: select + if: + type: function + name: isEqualToTemp|configMap + label: ConfigMap Name + schema: valueFrom/properties/configMapKeyRef/properties/name + loader: + name: resourceNames|core|v1|configmaps + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: ConfigMap Key + schema: valueFrom/properties/configMapKeyRef/properties/key + if: + type: function + name: isEqualToTemp|configMap + loader: + name: getConfigMapKeys + watchPaths: + - schema/resources/kubedbComMemcached/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/configMapKeyRef/name + - schema/metadata/release/namespace + - type: select + label: Secret Name + schema: valueFrom/properties/secretKeyRef/properties/name + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecrets + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: Secret Key + schema: valueFrom/properties/secretKeyRef/properties/key + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecretKeys + watchPaths: + - schema/resources/kubedbComMemcached/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/secretKeyRef/name + - schema/metadata/release/namespace + + - type: single-step-form + id: compute-autoscaler + loader: getDbDetails elements: - - label: - text: labels.to_update_exporter_resources - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - function: getOpsRequestUrl|VerticalScaling - - computed: isValueExistInModel|/resources/kubedbComMemcached/spec/monitor - 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 + - type: block-layout + if: + type: function + name: isConsole + elements: + - type: input + label: Name + schema: schema/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/metadata/properties/name + - type: select + label: Select Namespace + loader: getNamespaces + if: + type: function + name: isRancherManaged + schema: schema/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/metadata/properties/namespace + - type: select + label: Select Db + loader: getDbs + validation: + type: required + refresh: true + schema: schema/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/databaseRef/properties/name + watcher: + func: initMetadata + paths: + - schema/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/databaseRef/properties/name + + - type: radio + if: + type: function + name: isConsole + label: Select Type + validation: + type: required + schema: temp/properties/autoscalingType + watcher: + func: initMetadata + paths: + - temp/properties/autoscalingType 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/kubedbComMemcached/properties/spec/properties/monitor/properties/agent - type: radio - - elements: - - label: - text: labels.scrapping_interval - schema: - $ref: schema#/properties/resources/properties/kubedbComMemcached/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval - type: input - if: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComMemcached/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/kubedbComMemcached/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/kubedbComMemcached/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: - - if: returnFalse - label: - text: labels.resources - schema: - $ref: schema#/properties/resources/properties/kubedbComMemcached/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/kubedbComMemcached/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/kubedbComMemcached/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup - type: input - - label: - text: labels.port - schema: - $ref: schema#/properties/resources/properties/kubedbComMemcached/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/kubedbComMemcached/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args/items - type: input - label: - text: labels.args - schema: - $ref: schema#/properties/resources/properties/kubedbComMemcached/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args - type: list-input-form - - alias: reusable_env - chart: - name: uibytebuildersdev-component-env - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComMemcached/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 -type: multi-step-form + - text: Compute + value: compute + description: Scale your CPU Memory based on resource usage + - text: Storage + value: storage + description: Expand your database size based on volume usage + + - type: block-layout + showLabels: false + loader: fetchTopologyMachines + elements: + # memcached mode + - type: block-layout + label: Memcached + showLabels: true + elements: + - type: select + label: Trigger + init: + type: func + value: setTrigger|autoscalingKubedbComMemcachedAutoscaler/spec/compute/memcached/trigger + options: + - text: 'On' + value: 'On' + - text: 'Off' + value: 'Off' + schema: schema/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/memcached/properties/trigger + - type: input + label: Pod LifeTime Threshold + schema: schema/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/memcached/properties/podLifeTimeThreshold + - type: threshold-input + label: Resource Diff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/memcached/properties/resourceDiffPercentage + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|min + loader: + name: getMachines|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-max + watcher: + func: onMachineChange|memcached + paths: + - temp/properties/allowedMachine-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/memcached/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/memcached/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|max + loader: + name: getMachines|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-min + watcher: + func: onMachineChange|memcached + paths: + - temp/properties/allowedMachine-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/memcached/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/memcached/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|memcached + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/memcached/properties/controlledResources + + - type: block-layout + label: Node Topology + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: select + label: Select Node Topology + loader: fetchNodeTopology + schema: schema/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name + - type: threshold-input + label: ScaleUp Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage + - type: threshold-input + label: ScaleDown Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage + + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + elements: + - type: select + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + options: + - text: 5 minutes + value: 5m0s + - text: 10 minutes + value: 10m0s + - text: 30 minutes + value: 30m0s + - text: 1 hour + value: 1h0m + - text: 2 hours + value: 2h0m + - text: 5 hours + value: 5h0m + - text: 10 hours + value: 10h0m + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComMemcachedAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply diff --git a/charts/kubedbcom-memcached-editor/ui/functions.js b/charts/kubedbcom-memcached-editor/ui/functions.js index da73f94ea3..609315a181 100644 --- a/charts/kubedbcom-memcached-editor/ui/functions.js +++ b/charts/kubedbcom-memcached-editor/ui/functions.js @@ -1,2208 +1,919 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + // ************************* common functions ******************************************** // eslint-disable-next-line no-empty-pattern -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 disableLableChecker({ itemCtx }) { - const { key } = itemCtx - if (key.startsWith('app.kubernetes.io') || key.includes('helm')) return true - else return false -} - -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} - -async function getResources({ axios, storeGet }, 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 [] - } -} - -function isEqualToDiscriminatorPath( - { discriminator, getValue, watchDependency }, - value, - discriminatorPath, -) { - watchDependency('discriminator#' + discriminatorPath) - const discriminatorValue = getValue(discriminator, discriminatorPath) - return discriminatorValue === value -} - -function setValueFromModel({ getValue, model }, path) { - return getValue(model, path) -} - -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 -} - -async function getResourceList(axios, storeGet, { 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( - { axios, getValue, model, watchDependency, storeGet }, - 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) - }) - } +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + 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 instance = {} + async function getDbDetails() { + const annotations = + getValue(model, '/resources/autoscalingKubedbComMemcachedAutoscaler/metadata/annotations') || + {} + instance = annotations['kubernetes.io/instance-type'] + const owner = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + const namespace = + storeGet('/route/query/namespace') || + getValue(model, '/resources/autoscalingKubedbComMemcachedAutoscaler/metadata/namespace') || + '' + const name = + storeGet('/route/params/name') || + getValue(model, '/resources/autoscalingKubedbComMemcachedAutoscaler/spec/databaseRef/name') || + '' + + if (namespace && name) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/memcacheds/${name}`, + ) + dbDetails = resp.data || {} + setDiscriminatorValue('/dbDetails', true) + } catch (e) { + console.log(e) + } } - }) -} - -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - 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, + commit('wizard/model$update', { + path: `/metadata/release/name`, value: name, - } - }) -} - -function returnTrue() { - return true -} - -function returnStringYes() { - return 'yes' -} -function setAddressType({ model, getValue }) { - const value = getValue(model, '/resources/kubedbComMemcached/spec/useAddressType') - - if (!value) { - return 'DNS' - } - - return value -} - -// ************************* Basic Info ********************************************** -async function getMemcachedVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, - }, - }, - } - - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) - - const resources = (resp && resp.data && resp.data.items) || [] - - // keep only non deprecated versions - const filteredMongoDbVersions = resources.filter((item) => item.spec && !item.spec.deprecated) - - filteredMongoDbVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredMongoDbVersions - } catch (e) { - console.log(e) - return [] - } -} - -// ********************* Database Mode *********************** -function setDatabaseMode({ model, getValue }) { - const replicas = getValue(model, '/resources/kubedbComMemcached/spec/replicas') - - return replicas === 1 ? 'Standalone' : 'Cluster' -} - -function isEqualToDatabaseMode({ getValue, watchDependency, discriminator }, value) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - return mode === value -} - -const onDatabaseModeChange = ({ discriminator, getValue, commit }) => { - const databaseMode = getValue(discriminator, '/activeDatabaseMode') - - commit('wizard/model$update', { - path: '/resources/kubedbComMemcached/spec/replicas', - value: databaseMode === 'Standalone' ? 1 : 3, - force: true, - }) -} - -// ************************** TLS ******************************88 - -function setApiGroup() { - return 'cert-manager.io' -} - -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - watchDependency('model#/resources/kubedbComMemcached/spec/tls/issuerRef/apiGroup') - watchDependency('model#/resources/kubedbComMemcached/spec/tls/issuerRef/kind') - watchDependency('model#/metadata/release/namespace') - const apiGroup = getValue(model, '/resources/kubedbComMemcached/spec/tls/issuerRef/apiGroup') - const kind = getValue(model, '/resources/kubedbComMemcached/spec/tls/issuerRef/kind') - const namespace = getValue(model, '/metadata/release/namespace') - - let url - if (kind === 'Issuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/namespaces/${namespace}/issuers` - } else if (kind === 'ClusterIssuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/clusterissuers` - } - - if (!url) return [] - - 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 + force: true, }) - return resources - } catch (e) { - console.log(e) - return [] - } -} - -async function hasIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await getIssuerRefsName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !!(resp && resp.length) -} - -async function hasNoIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await hasIssuerRefName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !resp -} - -function setSSLMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComMemcached/spec/sslMode') - return val || 'require' -} - -function showTlsConfigureSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configureTLS') - const configureStatus = getValue(discriminator, '/configureTLS') - return configureStatus -} - -function onTlsConfigureChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/configureTLS') - if (configureStatus) { commit('wizard/model$update', { - path: '/resources/kubedbComMemcached/spec/tls', - value: { issuerRef: {}, certificates: [] }, + path: `/metadata/release/namespace`, + value: namespace, force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComMemcached/spec/tls') - commit('wizard/model$delete', '/resources/kubedbComMemcached/spec/sslMode') - } -} - -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} - -/****** Monitoring *********/ - -function showMonitoringSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/enableMonitoring') - const configureStatus = getValue(discriminator, '/enableMonitoring') - return configureStatus -} - -function onEnableMonitoringChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/enableMonitoring') - if (configureStatus) { commit('wizard/model$update', { - path: '/resources/kubedbComMemcached/spec/monitor', - value: {}, + path: `/resources/autoscalingKubedbComMemcachedAutoscaler/spec/databaseRef/name`, + value: name, force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComMemcached/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, getValue }) { - watchDependency('discriminator#/customizeExporter') - const configureStatus = getValue(discriminator, '/customizeExporter') - return configureStatus -} - -function onCustomizeExporterChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/customizeExporter') - if (configureStatus) { commit('wizard/model$update', { - path: '/resources/kubedbComMemcached/spec/monitor/prometheus/exporter', - value: {}, + path: `/resources/autoscalingKubedbComMemcachedAutoscaler/metadata/labels`, + value: dbDetails.metadata.labels, force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComMemcached/spec/monitor/prometheus/exporter') } -} - -// ********************************* Initialization & Backup ************************************* -const stashAppscodeComRestoreSession_init = { - spec: { - repository: { - name: '', - }, - rules: [ - { - snapshots: ['latest'], - }, - ], - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} -const initScript = { - scriptPath: '', - secret: { - secretName: '', - }, -} -const stashAppscodeComRepository_init_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const stashAppscodeComRepository_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const restoreSessionInitRunTimeSettings = { - container: { - resources: { - requests: { - cpu: '', - memory: '', - }, - limits: { - cpu: '', - memory: '', - }, - }, - nice: { - adjustment: null, - }, - ionice: { - class: null, - classData: null, - }, - securityContext: { - privileged: false, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - env: [], - envFrom: [], - }, - pod: { - serviceAccountName: '', - imagePullSecrets: [], - securityContext: { - fsGroup: null, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - }, -} - -const stashAppscodeComBackupConfiguration = { - spec: { - repository: { - name: '', - }, - retentionPolicy: { - keepLast: 5, - name: 'keep-last-5', - prune: true, - }, - schedule: '*/5 * * * *', - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} - -function valueExists(value, getValue, path) { - const val = getValue(value, path) - if (val) return true - else return false -} - -function initPrePopulateDatabase({ getValue, model }) { - const waitForInitialRestore = getValue( - model, - '/resources/kubedbComMemcached/spec/init/waitForInitialRestore', - ) - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - const script = getValue(model, '/resources/kubedbComMemcached/spec/init/script') - return waitForInitialRestore || !!stashAppscodeComRestoreSession_init || !!script ? 'yes' : 'no' -} + let autoscaleType = '' + let dbDetails = {} -function onPrePopulateDatabaseChange({ commit, getValue, discriminator, model }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - if (prePopulateDatabase === 'no') { - // delete related properties - commit('wizard/model$update', { - path: '/resources/kubedbComMemcached/spec/init/waitForInitialRestore', - value: false, - }) - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - commit('wizard/model$delete', '/resources/kubedbComMemcached/spec/init/script') - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else { - const dbName = getValue(model, '/metadata/release/name') - // set stashAppscodeComRestoreSession_init if it doesn't exist - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - force: true, - }) + function isConsole() { + const isKube = isKubedb() + if (isKube) { + const dbName = storeGet('/route/params/name') || '' commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', + path: '/resources/autoscalingKubedbComMemcachedAutoscaler/spec/databaseRef/name', value: dbName, force: true, }) - } - } -} - -function initDataSource({ getValue, model }) { - const script = getValue(model, '/resources/kubedbComMemcached/spec/init/script') - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - - if (script) return 'script' - else if (stashAppscodeComRestoreSession_init) return 'stashBackup' - else return undefined -} - -function onDataSourceChange({ commit, getValue, discriminator, model }) { - const dataSource = getValue(discriminator, '/dataSource') - - commit('wizard/model$update', { - path: '/resources/kubedbComMemcached/spec/init/waitForInitialRestore', - value: dataSource === 'stashBackup', - force: true, - }) - - if (dataSource === 'script') { - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - - // create a new script if there is no script property - if (!valueExists(model, getValue, '/resources/kubedbComMemcached/spec/init/script')) - commit('wizard/model$update', { - path: '/resources/kubedbComMemcached/spec/init/script', - value: initScript, - }) - } else if (dataSource === 'stashBackup') { - commit('wizard/model$delete', '/resources/kubedbComMemcached/spec/init/script') - - // create a new stashAppscodeComRestoreSession_init if there is no stashAppscodeComRestoreSession_init property - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - const dbName = getValue(model, '/metadata/release/name') - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - }) - + 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/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, + path: '/resources/autoscalingKubedbComMemcachedAutoscaler/metadata/name', + value: modifiedName, force: true, }) + const namespace = storeGet('/route/query/namespace') || '' + if (namespace) { + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComMemcachedAutoscaler/metadata/namespace', + value: namespace, + force: true, + }) + } } - } -} - -// // for script -function initVolumeType({ getValue, model }) { - const configMap = getValue(model, '/resources/kubedbComMemcached/spec/init/script/configMap/name') - const secret = getValue(model, '/resources/kubedbComMemcached/spec/init/script/secret/secretName') - - if (configMap) return 'configMap' - else if (secret) return 'secret' - else return undefined -} - -function onVolumeTypeChange({ commit, getValue, discriminator, model }) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - if (sourceVolumeType === 'configMap') { - // add configMap object and delete secret object - commit('wizard/model$delete', '/resources/kubedbComMemcached/spec/init/script/secret') - - if (!valueExists(model, getValue, '/resources/kubedbComMemcached/spec/init/script/configMap')) { - commit('wizard/model$update', { - path: '/resources/kubedbComMemcached/spec/init/script/configMap', - value: { - name: '', - }, - }) - } - } else if (sourceVolumeType === 'secret') { - // delete configMap object and add secret object - commit('wizard/model$delete', '/resources/kubedbComMemcached/spec/init/script/configMap') - if (!valueExists(model, getValue, '/resources/kubedbComMemcached/spec/init/script/secret')) { - commit('wizard/model$update', { - path: '/resources/kubedbComMemcached/spec/init/script/secret', - value: { - secretName: '', - }, - }) - } + return !isKube } -} - -function showInitializationForm({ getValue, discriminator, watchDependency }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - watchDependency('discriminator#/prePopulateDatabase') - return prePopulateDatabase === 'yes' -} - -function showScriptOrStashForm({ getValue, discriminator, watchDependency }, value) { - const dataSource = getValue(discriminator, '/dataSource') - watchDependency('discriminator#/dataSource') - return dataSource === value -} - -function showConfigMapOrSecretName({ getValue, discriminator, watchDependency }, value) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - watchDependency('discriminator#/sourceVolumeType') - return sourceVolumeType === value -} - -// for stash backup -function initializeNamespace({ getValue, model }) { - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} -function showRepositorySelectOrCreate({ getValue, discriminator, watchDependency }, value) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') + function isKubedb() { + return !!storeGet('/route/params/actions') + } - return repositoryChoise === value -} + async function getNamespaces() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function onInitRepositoryChoiseChange({ getValue, discriminator, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - if (repositoryChoise === 'select') { - // delete stashAppscodeComRepository_init_repo from model - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else if (repositoryChoise === 'create') { - // add stashAppscodeComRepository_init_repo to model - commit('wizard/model$update', { - path: 'resources/stashAppscodeComRepository_init_repo', - value: stashAppscodeComRepository_init_repo, + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, }) - const repositoryName = `${getValue(model, '/metadata/release/name')}-init-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: repositoryName, + 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 initCustomizeRestoreJobRuntimeSettings({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} -function initCustomizeRestoreJobRuntimeSettingsForBackup({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function onCustomizeRestoreJobRuntimeSettingsChange({ commit, getValue, discriminator, model }) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - value: restoreSessionInitRunTimeSettings, - }) - } + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found } -} -function onCustomizeRestoreJobRuntimeSettingsChangeForBackup({ - commit, - getValue, - discriminator, - model, -}) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', + function onNamespaceChange() { + const namespace = getValue( + model, + '/resources/autoscalingKubedbComMemcachedAutoscaler/metadata/namespace', ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', + if (!namespace) { + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComMemcachedAutoscaler/spec/databaseRef/name', ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - value: {}, - force: true, - }) - } - } -} - -function showRuntimeForm({ discriminator, getValue, watchDependency }, value) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - watchDependency('discriminator#/customizeRestoreJobRuntimeSettings') - return customizeRestoreJobRuntimeSettings === value -} - -async function getImagePullSecrets({ getValue, model, watchDependency, axios, storeGet }) { - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - - let resources = await getNamespacedResourceList(axios, storeGet, { - namespace, - group: 'core', - version: 'v1', - resource: 'secrets', - }) - - resources = resources.filter((item) => { - const validType = ['kubernetes.io/dockerconfigjson'] - return validType.includes(item.type) - }) - - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: { name: name }, } - }) -} - -// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// FOR Backup Configuration - -// schedule bakcup - -function getBackupConfigsAndAnnotations(getValue, model) { - const stashAppscodeComBackupConfiguration = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration', - ) - const kubedbComMemcachedAnnotations = - getValue(model, '/resources/kubedbComMemcached/metadata/annotations') || {} - - const isBluePrint = Object.keys(kubedbComMemcachedAnnotations).some( - (k) => - k === 'stash.appscode.com/backup-blueprint' || - k === 'stash.appscode.com/schedule' || - k.startsWith('params.stash.appscode.com/'), - ) - - return { - stashAppscodeComBackupConfiguration, - isBluePrint, } -} + async function getDbs() { + // watchDependency('model#/resources/autoscalingKubedbComMemcachedAutoscaler/metadata/namespace') + const namespace = getValue( + model, + '/resources/autoscalingKubedbComMemcachedAutoscaler/metadata/namespace', + ) + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function deleteKubeDbComMemcachedDbAnnotation(getValue, model, commit) { - const annotations = getValue(model, '/resources/kubedbComMemcached/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/kubedbComMemcached/metadata/annotations', - value: filteredAnnotations, - }) -} + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) -function addKubeDbComMemcachedDbAnnotation(getValue, model, commit, key, value, force) { - const annotations = getValue(model, '/resources/kubedbComMemcached/metadata/annotations') || {} + const resources = (resp && resp.data && resp.data.items) || [] - if (annotations[key] === undefined) { - annotations[key] = value - } else if (force) { - annotations[key] = value + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) } - commit('wizard/model$update', { - path: '/resources/kubedbComMemcached/metadata/annotations', - value: annotations, - force: true, - }) -} - -function initScheduleBackupForEdit({ getValue, model, setDiscriminatorValue }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function initScheduleBackup({ getValue, model }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function onScheduleBackupChange({ commit, getValue, discriminator, model }) { - 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 kubedbComMemcached annotation - deleteKubeDbComMemcachedDbAnnotation(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, - }) + function initMetadata() { + const dbName = + getValue(model, '/resources/autoscalingKubedbComMemcachedAutoscaler/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/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, + path: '/resources/autoscalingKubedbComMemcachedAutoscaler/metadata/name', + value: modifiedName, force: true, }) - } - } -} - -// backup form -function showBackupForm({ getValue, discriminator, watchDependency }) { - const scheduleBackup = getValue(discriminator, '/scheduleBackup') - watchDependency('discriminator#/scheduleBackup') - - if (scheduleBackup === 'yes') return true - else return false -} - -// invoker form -function initBackupInvoker({ getValue, model }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - if (stashAppscodeComBackupConfiguration) return 'backupConfiguration' - else if (isBluePrint) return 'backupBlueprint' - else return undefined -} -function onBackupInvokerChange({ getValue, discriminator, commit, model }) { - const backupInvoker = getValue(discriminator, '/backupInvoker') - - if (backupInvoker === 'backupConfiguration') { - // delete annotation and create backup config object - deleteKubeDbComMemcachedDbAnnotation(getValue, model, commit) - const dbName = getValue(model, '/metadata/release/name') - - if (!valueExists(model, getValue, '/resources/stashAppscodeComBackupConfiguration')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration', - value: stashAppscodeComBackupConfiguration, - }) - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, - force: true, - }) - } - } else if (backupInvoker === 'backupBlueprint') { - // delete backup configuration object and create the annotation - commit('wizard/model$delete', '/resources/stashAppscodeComBackupConfiguration') - addKubeDbComMemcachedDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/backup-blueprint', - '', - ) + // delete the other type object from model + if (type === 'compute') + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComMemcachedAutoscaler/spec/storage', + ) + if (type === 'storage') + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComMemcachedAutoscaler/spec/compute', + ) } -} -function showInvokerForm({ getValue, discriminator, watchDependency }, value) { - const backupInvoker = getValue(discriminator, '/backupInvoker') - watchDependency('discriminator#/backupInvoker') + async function fetchTopologyMachines() { + const instance = hasAnnotations() - return backupInvoker === value -} - -// backup configuration form -function initalizeTargetReferenceName({ getValue, model, watchDependency }) { - const databaseName = getValue(model, '/metadata/release/name') - watchDependency('model#/metadata/release/name') + 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) - return databaseName -} - -// restore session repository -function setInitialRestoreSessionRepo({ getValue, model }) { - const value = getValue(model, 'resources/stashAppscodeComRepository_init_repo') - return value ? 'create' : 'select' -} - -// backup config repository -function initRepositoryChoise({ getValue, model }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - - if (stashAppscodeComRepository_repo) return 'create' - else return 'select' -} - -function initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' - setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) - - return repoInitialSelectionStatus -} - -function onRepositoryChoiseChange({ getValue, discriminator, watchDependency, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - if (repositoryChoise === 'select') { - // delete the stashAppscodeComRepository_repo - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') - } else if (repositoryChoise === 'create') { - // create new stashAppscodeComRepository_repo - if (!valueExists(model, getValue, '/resources/stashAppscodeComRepository_repo')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRepository_repo', - value: stashAppscodeComRepository_repo, - }) - const repositoryName = `${getValue(model, '/metadata/release/name')}-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) + const nodeGroups = resp.data?.spec?.nodeGroups || [] + setDiscriminatorValue('/topologyMachines', nodeGroups) + return nodeGroups + } catch (e) { + console.log(e) + return [] + } } } -} - -function onRepositoryNameChange({ getValue, model, commit }) { - const repositoryName = getValue(model, 'resources/stashAppscodeComRepository_repo/metadata/name') - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) -} - -// backup blueprint form -function getMongoAnnotations(getValue, model) { - const annotations = getValue(model, '/resources/kubedbComMemcached/metadata/annotations') - return { ...annotations } || {} -} -function initFromAnnotationValue({ getValue, model }, key) { - const annotations = getMongoAnnotations(getValue, model) - return annotations[key] -} + function hasAnnotations() { + const annotations = getValue( + model, + '/resources/autoscalingKubedbComMemcachedAutoscaler/metadata/annotations', + ) + const instance = annotations['kubernetes.io/instance-type'] -function onBackupBlueprintNameChange({ getValue, discriminator, commit, model }) { - const backupBlueprintName = getValue(discriminator, '/backupBlueprintName') - addKubeDbComMemcachedDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/backup-blueprint', - backupBlueprintName, - true, - ) -} + return !!instance + } -function onBackupBlueprintScheduleChange({ getValue, discriminator, commit, model }) { - const backupBlueprintSchedule = getValue(discriminator, '/schedule') - addKubeDbComMemcachedDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/schedule', - backupBlueprintSchedule, - true, - ) -} + function setAllowedMachine(minmax) { + const mx = instance?.includes(',') ? instance.split(',')[1] : '' + const mn = instance?.includes(',') ? instance.split(',')[0] : '' + const machineName = minmax === 'min' ? mn : mx -function initFromAnnotationKeyValue({ getValue, model }, prefix) { - const annotations = getMongoAnnotations(getValue, model) - const newOb = {} - Object.keys(annotations).forEach((key) => { - if (key.startsWith(prefix)) { - const newKey = key.replace(prefix, '') - newOb[newKey] = annotations[key] + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] + const machineData = nodeGroups.find((item) => item.topologyValue === machineName) + if (machineData) { + return { + machine: machineName, + cpu: machineData.allocatable?.cpu, + memory: machineData.allocatable?.memory, + } } - }) - return newOb -} - -function onTaskParametersChange({ getValue, discriminator, model, commit }) { - const taskParameters = getValue(discriminator, '/taskParameters') - - const taskParamterKeys = Object.keys(taskParameters).map( - (tp) => `params.stash.appscode.com/${tp}`, - ) - const oldAnnotations = getValue(model, '/resources/kubedbComMemcached/metadata/annotations') || {} - const newAnnotations = {} - - const filteredAnnotationKeys = Object.keys(oldAnnotations).filter( - (key) => !taskParamterKeys.includes(key) && !key.startsWith('params.stash.appscode.com/'), - ) + return { machine: machineName || '', cpu: '', memory: '' } + } - filteredAnnotationKeys.forEach((key) => { - newAnnotations[key] = oldAnnotations[key] - }) + async function getMachines(minmax) { + // watchDependency('discriminator#/topologyMachines') + const depends = minmax === 'min' ? 'max' : 'min' + const dependantPath = `/allowedMachine-${depends}` - Object.keys(taskParameters).forEach((tpk) => { - newAnnotations[`params.stash.appscode.com/${tpk}`] = taskParameters[tpk] - }) + // watchDependency(`discriminator#${dependantPath}`) + const dependantMachineObj = getValue(discriminator, dependantPath) + const dependantMachine = dependantMachineObj?.machine || '' - commit('wizard/model$update', { - path: '/resources/kubedbComMemcached/metadata/annotations', - value: newAnnotations, - }) -} + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] -function isValueExistInModel({ model, getValue }, path) { - const modelValue = getValue(model, path) - return !!modelValue -} + const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) -function onNamespaceChange({ commit, model, getValue }) { - const namespace = getValue(model, '/metadata/release/namespace') - const agent = getValue(model, '/resources/kubedbComMemcached/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', - value: [namespace], - force: true, + 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, + }, + } }) - } -} -function onLabelChange({ commit, model, getValue }) { - const labels = getValue(model, '/resources/kubedbComMemcached/spec/metadata/labels') - - const agent = getValue(model, '/resources/kubedbComMemcached/spec/monitor/agent') + const filteredMachine = machines?.filter((item, ind) => + minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, + ) - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) + return dependantIndex === -1 ? machines : filteredMachine } -} - -function onNameChange({ commit, model, getValue }) { - const dbName = getValue(model, '/metadata/release/name') - const agent = getValue(model, '/resources/kubedbComMemcached/spec/monitor/agent') + function onMachineChange(type) { + const annoPath = '/resources/autoscalingKubedbComMemcachedAutoscaler/metadata/annotations' + const annotations = getValue(model, annoPath) || {} + const instance = annotations['kubernetes.io/instance-type'] - const labels = getValue(model, '/resources/kubedbComMemcached/spec/metadata/labels') - - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) - } + 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 - const scheduleBackup = getValue(model, '/resources/stashAppscodeComBackupConfiguration') + const minMachineAllocatable = minMachineObj + ? { cpu: minMachineObj.cpu, memory: minMachineObj.memory } + : null + const maxMachineAllocatable = maxMachineObj + ? { cpu: maxMachineObj.cpu, memory: maxMachineObj.memory } + : null + const allowedPath = `/resources/autoscalingKubedbComMemcachedAutoscaler/spec/compute/${type}` - if (scheduleBackup) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_repo') - if (creatingNewRepo) { + if (minMachine && maxMachine && instance !== minMaxMachine) { commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: `${dbName}-repo`, + path: `${allowedPath}/maxAllowed`, + value: maxMachineAllocatable, force: true, }) - } - } - - const prePopulateDatabase = getValue(model, '/resources/stashAppscodeComRestoreSession_init') - - if (prePopulateDatabase) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_init_repo') - if (creatingNewRepo) { commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: `${dbName}-init-repo`, + path: `${allowedPath}/minAllowed`, + value: minMachineAllocatable, + force: true, + }) + commit('wizard/model$update', { + path: annoPath, + value: annotations, force: true, }) } } - // to reset configSecret name field - const hasSecretConfig = getValue(model, '/resources/secret_config') - if (hasSecretConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComMemcached/spec/configSecret/name', - value: `${dbName}-config`, - force: true, - }) - } - - // to reset shard configSecret name field - const hasSecretShardConfig = getValue(model, '/resources/secret_shard_config') - if (hasSecretShardConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComMemcached/spec/shardTopology/shard/configSecret/name', - value: `${dbName}-shard-config`, - force: true, - }) - } - - // to reset shard configSecret name field - const hasSecretConfigServerConfig = getValue(model, '/resources/secret_configserver_config') - if (hasSecretConfigServerConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComMemcached/spec/shardTopology/configServer/configSecret/name', - value: `${dbName}-configserver-config`, - force: true, - }) - } - - // to reset mongos configSecret name field - const hasSecretMongosConfig = getValue(model, '/resources/secret_mongos_config') - if (hasSecretMongosConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComMemcached/spec/shardTopology/mongos/configSecret/name', - value: `${dbName}-mongos-config`, - force: true, - }) - } -} - -function returnFalse() { - return false -} - -function onAgentChange({ commit, model, getValue }) { - const agent = getValue(model, '/resources/kubedbComMemcached/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', - value: [], - force: true, - }) + function hasAnnotations() { + const annotations = + getValue(model, '/resources/autoscalingKubedbComMemcachedAutoscaler/metadata/annotations') || + {} + const instance = annotations['kubernetes.io/instance-type'] - onNamespaceChange({ commit, model, getValue }) - onLabelChange({ commit, model, getValue }) - } else { - commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') + return !!instance } -} - -/************************************* Database Secret Section ********************************************/ - -function getCreateAuthSecret({ model, getValue }) { - const authSecret = getValue(model, '/resources/kubedbComMemcached/spec/authSecret') - return !authSecret -} - -function showExistingSecretSection({ getValue, watchDependency, discriminator }) { - watchDependency('discriminator#/createAuthSecret') - const hasAuthSecretName = getValue(discriminator, '/createAuthSecret') - return !hasAuthSecretName -} - -function showPasswordSection({ getValue, watchDependency, discriminator }) { - return !showExistingSecretSection({ - getValue, - watchDependency, - discriminator, - }) -} - -function setAuthSecretPassword({ model, getValue }) { - const encodedPassword = getValue(model, '/resources/secret_auth/data/password') - return encodedPassword ? decodePassword({}, encodedPassword) : '' -} + function hasNoAnnotations() { + return !hasAnnotations() + } -function onAuthSecretPasswordChange({ getValue, discriminator, commit }) { - const stringPassword = getValue(discriminator, '/password') + function isNodeTopologySelected() { + // watchDependency( + // 'model#/resources/autoscalingKubedbComMemcachedAutoscaler/spec/compute/nodeTopology/name', + // ) + const nodeTopologyName = + getValue( + model, + '/resources/autoscalingKubedbComMemcachedAutoscaler/spec/compute/nodeTopology/name', + ) || '' + return !!nodeTopologyName.length + } - if (stringPassword) { - commit('wizard/model$update', { - path: '/resources/secret_auth/data/password', - value: encodePassword({}, stringPassword), - force: true, - }) + function setControlledResources(type) { + const list = ['cpu', 'memory'] + const path = `/resources/autoscalingKubedbComMemcachedAutoscaler/spec/compute/${type}/controlledResources` commit('wizard/model$update', { - path: '/resources/secret_auth/data/username', - value: encodePassword({}, 'root'), + path: path, + value: list, force: true, }) - } else { - commit('wizard/model$delete', '/resources/secret_auth') + return list } -} -function disableInitializationSection({ model, getValue, watchDependency }) { - const initialized = getValue(model, '/resources/kubedbComMemcached/spec/init/initialized') - watchDependency('model#/resources/kubedbComMemcached/spec/init/initialized') - return !!initialized -} + function setTrigger(path) { + let value = getValue(model, `/resources/${path}`) + if (value) return value + return 'On' + } -// eslint-disable-next-line no-empty-pattern -function encodePassword({}, value) { - return btoa(value) -} + function setApplyToIfReady() { + return 'IfReady' + } + 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 [] + } -// eslint-disable-next-line no-empty-pattern -function decodePassword({}, value) { - return atob(value) -} + function showOpsRequestOptions() { + if (isKubedb() === true) return true + // watchDependency('model#/resources/autoscalingKubedbComMemcachedAutoscaler/spec/databaseRef/name') + // watchDependency('discriminator#/autoscalingType') + return ( + !!getValue( + model, + '/resources/autoscalingKubedbComMemcachedAutoscaler/spec/databaseRef/name', + ) && !!getValue(discriminator, '/autoscalingType') + ) + } -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/resources/kubedbComMemcached/spec/authSecret') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/resources/secret_auth') + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value } -} -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - if (owner && cluster && namespace) { try { const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, { - params: { - filter: { - items: { - data: { username: null, password: null }, - metadata: { name: null }, - type: null, - }, - }, - }, + params: { filter: { items: { metadata: { name: null } } } }, }, ) - const secrets = (resp && resp.data && resp.data.items) || [] - - const filteredSecrets = secrets.filter((item) => { - const validType = [ - 'kubernetes.io/service-account-token', - 'Opaque', - 'kubernetes.io/basic-auth', - ] - return validType.includes(item.type) - }) + const resources = (resp && resp.data && resp.data.items) || [] - filteredSecrets.map((item) => { + resources.map((item) => { const name = (item.metadata && item.metadata.name) || '' item.text = name item.value = name return true }) - return filteredSecrets + return resources } catch (e) { console.log(e) + return [] } } - return [] -} -//////////////////// custom config ///////////////// -function onConfigurationSourceChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSource') - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_config') - } else { - const value = getValue(model, '/resources/secret_config') - if (!value) { - commit('wizard/model$update', { - path: '/resources/secret_config', - value: {}, - force: true, - }) - } - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` + async function getNamespacedResourceList( + axios, + storeGet, + { namespace, group, version, resource }, + ) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - commit('wizard/model$update', { - path: '/resources/kubedbComMemcached/spec/configSecret/name', - value: configSecretName, - force: true, - }) - } -} + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` -function onConfigurationChange({ getValue, commit, discriminator, model }) { - const value = getValue(discriminator, '/configuration') - commit('wizard/model$update', { - path: '/resources/secret_config/stringData/user.conf', - value: value, - force: true, - }) - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComMemcached/spec/configSecret/name', - value: configSecretName, - force: true, - }) -} + let ans = [] + try { + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) -function onConfigurationChangeEdit({ getValue, commit, discriminator, model }) { - const value = getValue(discriminator, '/configuration') - - commit('wizard/model$update', { - path: '/resources/secret_config/data/memcached.ini', - value: btoa(value), - force: true, - }) - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComMemcached/spec/configSecret/name', - value: configSecretName, - force: true, - }) -} + const items = (resp && resp.data && resp.data.items) || [] + ans = items + } catch (e) { + console.log(e) + } -function setConfigurationSource({ model, getValue }) { - const modelValue = getValue(model, '/resources/secret_config') - if (modelValue) { - return 'create-new-config' + return ans } - return 'use-existing-config' -} -function setSecretConfigNamespace({ getValue, model, watchDependency }) { - watchDependency('model#/metadata/release/namespace') - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} - -function setConfiguration({ model, getValue }) { - return getValue(model, '/resources/secret_config/stringData/user.conf') -} - -function setConfigurationForEdit({ model, getValue }) { - const value = getValue(model, '/resources/secret_config/data/memcached.ini') - return atob(value) -} + async function resourceNames(group, version, resource) { + const namespace = getValue(model, '/metadata/release/namespace') + // watchDependency('model#/metadata/release/namespace') -function setConfigurationFiles({ model, getValue }) { - const value = getValue(model, '/resources/secret_config/data/user.conf') - return atob(value) -} + let resources = await getNamespacedResourceList(axios, storeGet, { + namespace, + group, + version, + resource, + }) -function onSetCustomConfigChange({ discriminator, getValue, commit }) { - const value = getValue(discriminator, '/setCustomConfig') + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } - if (value === 'no') { - commit('wizard/model$delete', '/resources/kubedbComMemcached/spec/configSecret') - commit('wizard/model$delete', '/resources/secret_config') + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } + }) } -} - -function getOpsRequestUrl({ storeGet, model, getValue, mode }, 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 + `/create-opsrequest-${reqType.toLowerCase()}?namespace=${namespace}` - - if (mode === 'standalone-step') return pathConstructedForKubedb - else - return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/memcachedopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` -} - -const getAppbinding = async ({ axios, storeGet, getValue, watchDependency, rootModel }) => { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const group = 'appcatalog.appscode.com' - const version = 'v1alpha1' - const resource = 'appbindings' - - watchDependency('rootModel#/databaseRef/namespace') - - const namespace = getValue(rootModel, '/databaseRef/namespace') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}`, - { - params: { - filter: { items: { metadata: { name: null }, type: 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 -} - -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} -function onRefChange({ discriminator, getValue, commit }) { - const ref = getValue(discriminator, '/pgRef') || {} - commit('wizard/model$update', { - path: '/resources/kubedbComMemcached/spec/database/databaseRef/name', - value: ref.name || '', - force: true, - }) - commit('wizard/model$update', { - path: '/resources/kubedbComMemcached/spec/database/databaseRef/namespace', - value: ref.namespace || '', - force: true, - }) -} + /****** Monitoring *********/ -async function getAppBindings({ axios, storeGet }, type) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const queryParams = { - filter: { - items: { - metadata: { name: null, namespace: null }, - spec: { type: null }, - }, - }, + function showMonitoringSection() { + // watchDependency('discriminator#/enableMonitoring') + const configureStatus = getValue(discriminator, '/enableMonitoring') + return configureStatus } - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/appcatalog.appscode.com/v1alpha1/appbindings`, - queryParams, - ) - const resources = (resp && resp.data && resp.data.items) || [] - const fileredResources = resources - .filter((item) => item.spec?.type === `kubedb.com/${type}`) - .map((item) => { - const name = item.metadata?.name || '' - const namespace = item.metadata?.namespace || '' - return { - text: `${namespace}/${name}`, - value: { - name: name, - namespace: namespace, - }, - } + function onEnableMonitoringChange() { + const configureStatus = getValue(discriminator, '/enableMonitoring') + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComMemcached/spec/monitor', + value: {}, + force: true, }) - return fileredResources - } catch (e) { - console.log(e) - return [] - } -} - -///////////////////////// Autoscaler /////////////////// -let autoscaleType = '' -let dbDetails = {} - -function isConsole({ storeGet, commit }) { - const isKube = isKubedb({ storeGet }) - - if (isKube) { - const dbName = storeGet('/route/params/name') || '' - commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComMemcachedAutoscaler/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] + } else { + commit('wizard/model$delete', '/resources/kubedbComMemcached/spec/monitor') } - const date = Math.floor(Date.now() / 1000) - const modifiedName = `${dbName}-${date}-autoscaling-${autoscaleType}` + + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComMemcachedAutoscaler/metadata/name', - value: modifiedName, + path: '/form/alert/enabled', + value: configureStatus ? 'warning' : 'none', force: true, }) - const namespace = storeGet('/route/query/namespace') || '' - if (namespace) { + } + + 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/autoscalingKubedbComMemcachedAutoscaler/metadata/namespace', - value: namespace, + path: '/resources/kubedbComMemcached/spec/monitor/prometheus/exporter', + value: {}, force: true, }) + } else { + commit( + 'wizard/model$delete', + '/resources/kubedbComMemcached/spec/monitor/prometheus/exporter', + ) } } - return !isKube -} - -function isKubedb({ storeGet }) { - return !!storeGet('/route/params/actions') -} - -function showOpsRequestOptions({ model, getValue, watchDependency, storeGet, discriminator }) { - if (isKubedb({ storeGet }) === true) return true - watchDependency('model#/resources/autoscalingKubedbComMemcachedAutoscaler/spec/databaseRef/name') - watchDependency('discriminator#/autoscalingType') - return ( - !!getValue(model, '/resources/autoscalingKubedbComMemcachedAutoscaler/spec/databaseRef/name') && - !!getValue(discriminator, '/autoscalingType') - ) -} - -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function isValueExistInModel(path) { + const modelValue = getValue(model, path) || null + return !!modelValue + } -async function getNamespaces({ axios, storeGet }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + // function onNamespaceChange() { + // const namespace = getValue(model, '/metadata/release/namespace') + // const agent = getValue(model, '/resources/kubedbComMemcached/spec/monitor/agent') + // if (agent === 'prometheus.io') { + // commit('wizard/model$update', { + // path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + // value: [namespace], + // force: true, + // }) + // } + // } - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + function onLabelChange() { + const labels = getValue(model, '/resources/kubedbComMemcached/spec/metadata/labels') - const resources = (resp && resp.data && resp.data.items) || [] + const agent = getValue(model, '/resources/kubedbComMemcached/spec/monitor/agent') - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, + if (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', + value: labels, + force: true, + }) } - }) -} - -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - watchDependency('model#/resources/autoscalingKubedbComMemcachedAutoscaler/metadata/namespace') - const namespace = getValue( - model, - '/resources/autoscalingKubedbComMemcachedAutoscaler/metadata/namespace', - ) - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + } - const resources = (resp && resp.data && resp.data.items) || [] + function onAgentChange() { + const agent = getValue(model, '/resources/kubedbComMemcached/spec/monitor/agent') + if (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', + value: [], + force: true, + }) - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, + onNamespaceChange() + onLabelChange() + } else { + commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') } - }) -} + } -async function getDbDetails({ commit, setDiscriminatorValue, axios, storeGet, getValue, model }) { - const owner = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - const namespace = - storeGet('/route/query/namespace') || - getValue(model, '/resources/autoscalingKubedbComMemcachedAutoscaler/metadata/namespace') || - '' - const name = - storeGet('/route/params/name') || - getValue(model, '/resources/autoscalingKubedbComMemcachedAutoscaler/spec/databaseRef/name') || - '' - - if (namespace && name) { - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/memcacheds/${name}`, - ) - dbDetails = resp.data || {} - setDiscriminatorValue('/dbDetails', true) - } catch (e) { - console.log(e) + 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') + + if (owner && cluster && namespace) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { + items: { + data: { username: null, password: null }, + 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', + 'kubernetes.io/basic-auth', + ] + 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 [] } - commit('wizard/model$update', { - path: `/metadata/release/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/metadata/release/namespace`, - value: namespace, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComMemcachedAutoscaler/spec/databaseRef/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComMemcachedAutoscaler/metadata/labels`, - value: dbDetails.metadata.labels, - force: true, - }) -} + 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}` -async function dbTypeEqualsTo({ watchDependency, commit }, type) { - watchDependency('discriminator#/dbDetails') + const isKube = !!storeGet('/route/params/actions') - const { spec } = dbDetails || {} - const { topology } = spec || {} - let verd = '' - if (topology) verd = 'topology' - else { - verd = 'combined' + if (isKube) return pathConstructedForKubedb + else + return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/memcachedopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` } - clearSpecModel({ commit }, verd) - return type === verd && spec -} -function clearSpecModel({ commit }, dbtype) { - if (dbtype === 'standalone') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComMemcachedAutoscaler/spec/${autoscaleType}/cluster`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComMemcachedAutoscaler/spec/${autoscaleType}/sentinel`, - ) - } else if (dbtype === 'cluster') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComMemcachedAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComMemcachedAutoscaler/spec/${autoscaleType}/sentinel`, - ) - } else if (dbtype === 'sentinel') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComMemcachedAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComMemcachedAutoscaler/spec/${autoscaleType}/cluster`, + function onNamespaceChange() { + const namespace = getValue( + model, + '/resources/autoscalingKubedbComMemcachedAutoscaler/metadata/namespace', ) + if (!namespace) { + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComMemcachedAutoscaler/spec/databaseRef/name', + ) + } } -} - -function initMetadata({ getValue, discriminator, model, commit, storeGet }) { - const dbName = - getValue(model, '/resources/autoscalingKubedbComMemcachedAutoscaler/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/autoscalingKubedbComMemcachedAutoscaler/metadata/name', - value: modifiedName, - force: true, - }) - - // delete the other type object from model - if (type === 'compute') - commit('wizard/model$delete', '/resources/autoscalingKubedbComMemcachedAutoscaler/spec/storage') - if (type === 'storage') - commit('wizard/model$delete', '/resources/autoscalingKubedbComMemcachedAutoscaler/spec/compute') -} -function onNamespaceChange({ model, getValue, commit }) { - const namespace = getValue( - model, - '/resources/autoscalingKubedbComMemcachedAutoscaler/metadata/namespace', - ) - if (!namespace) { - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComMemcachedAutoscaler/spec/databaseRef/name', - ) + function setValueFrom() { + if (isConfigMapTypeValueFrom()) { + return 'configMap' + } else if (isSecretTypeValueFrom()) { + return 'secret' + } else { + return 'input' + } } -} -function ifScalingTypeEqualsTo( - { storeGet, watchDependency, getValue, discriminator, model }, - type, -) { - watchDependency('discriminator#/autoscalingType') - watchDependency('model#/resources/autoscalingKubedbComMemcachedAutoscaler/spec/databaseRef/name') - - const operation = storeGet('/route/params/actions') || '' - if (operation.length) { - const splitOp = operation.split('-') - if (splitOp.length > 2) autoscaleType = splitOp[2] - } else autoscaleType = getValue(discriminator, '/autoscalingType') || '' - const isDatabaseSelected = !!getValue( - model, - '/resources/autoscalingKubedbComMemcachedAutoscaler/spec/databaseRef/name', - ) - return autoscaleType === type && isDatabaseSelected -} - -async function fetchNodeTopology({ axios, storeGet }) { - 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) + 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, + }) + } } - return [] -} -function isNodeTopologySelected({ watchDependency, model, getValue }) { - watchDependency( - 'model#/resources/autoscalingKubedbComMemcachedAutoscaler/spec/compute/nodeTopology/name', - ) - const nodeTopologyName = - getValue( - model, - '/resources/autoscalingKubedbComMemcachedAutoscaler/spec/compute/nodeTopology/name', - ) || '' - return !!nodeTopologyName.length -} - -function setControlledResources({ commit }, type) { - const list = ['cpu', 'memory'] - const path = `/resources/autoscalingKubedbComMemcachedAutoscaler/spec/compute/${type}/controlledResources` - commit('wizard/model$update', { - path: path, - value: list, - force: true, - }) - return list -} + // function isEqualToValueFromType(value) { + // //watchDependency('discriminator#/valueFromType') + // const valueFrom = getValue(discriminator, '/valueFromType') + // return valueFrom === value + // } -function setTrigger({ model, getValue }, path) { - let value = getValue(model, `/resources/${path}`) - if (value) return value - return 'On' -} + 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/kubedbComMemcached/spec/monitor/prometheus/exporter/env/${index}/valueFrom/configMapKeyRef/name`, + ) -function setApplyToIfReady() { - return 'IfReady' -} + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/configMapKeyRef/name') -function handleUnit({ commit, model, getValue }, 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, - }) - } - } -} + if (!configMapName) return [] -function setMetadata({ storeGet, mode, commit }) { - const dbname = storeGet('/route/params/name') || '' - const namespace = storeGet('/route/query/namespace') || '' - if (mode === 'standalone-step') { - commit('wizard/model$update', { - path: '/metadata/release/name', - value: dbname, - force: true, - }) - commit('wizard/model$update', { - path: '/metadata/release/namespace', - value: namespace, - force: true, - }) - } -} + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/configmaps/${configMapName}`, + ) -async function fetchTopologyMachines({ axios, getValue, storeGet, model, setDiscriminatorValue }) { - const instance = hasAnnotations({ model, getValue }) + const configMaps = (resp && resp.data && resp.data.data) || {} - 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 configMapKeys = Object.keys(configMaps).map((item) => ({ + text: item, + value: item, + })) - const nodeGroups = resp.data?.spec?.nodeGroups || [] - setDiscriminatorValue('/topologyMachines', nodeGroups) - return nodeGroups + return configMapKeys } catch (e) { console.log(e) return [] } } -} - -function setAllowedMachine({ model, getValue }, minmax) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComMemcachedAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - const mx = instance?.includes(',') ? instance.split(',')[1] : '' - const mn = instance?.includes(',') ? instance.split(',')[0] : '' - if (minmax === 'min') return mn - else return mx -} - -async function getMachines({ getValue, watchDependency, discriminator }, minmax) { - watchDependency('discriminator#/topologyMachines') - const depends = minmax === 'min' ? 'max' : 'min' - const dependantPath = `/allowedMachine-${depends}` - - watchDependency(`discriminator#${dependantPath}`) - const dependantMachine = getValue(discriminator, dependantPath) + 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/kubedbComMemcached/spec/monitor/prometheus/exporter/env/${index}/valueFrom/secretKeyRef/name`, + ) - const nodeGroups = getValue(discriminator, '/topologyMachines') || [] + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/secretKeyRef/name') - const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) + if (!secretName) return [] - const machines = nodeGroups?.map((item) => { - const subText = `CPU: ${item.allocatable.cpu}, Memory: ${item.allocatable.memory}` - const text = item.topologyValue - return { text, subText, value: item.topologyValue } - }) + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets/${secretName}`, + ) - const filteredMachine = machines?.filter((item, ind) => - minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, - ) + const secret = (resp && resp.data && resp.data.data) || {} - return dependantIndex === -1 ? machines : filteredMachine -} + const secretKeys = Object.keys(secret).map((item) => ({ + text: item, + value: item, + })) -function hasAnnotations({ model, getValue }) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComMemcachedAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] + return secretKeys + } catch (e) { + console.log(e) + return [] + } + } - return !!instance -} + function returnFalse() { + return false + } + + 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 + }) -function hasNoAnnotations({ model, getValue }) { - return !hasAnnotations({ model, getValue }) -} + if (filteredEnv.length) + commit('wizard/model$update', { + path: '/resources/kubedbComMemcached/spec/monitor/prometheus/exporter/env', + value: filteredEnv, + force: true, + }) + } -function onMachineChange({ model, getValue, discriminator, commit }, type) { - const annoPath = '/resources/autoscalingKubedbComMemcachedAutoscaler/metadata/annotations' - const annotations = getValue(model, annoPath) - const instance = annotations['kubernetes.io/instance-type'] + function initEnvArray() { + const env = getValue( + model, + '/resources/kubedbComMemcached/spec/monitor/prometheus/exporter/env', + ) - const minMachine = getValue(discriminator, '/allowedMachine-min') - const maxMachine = getValue(discriminator, '/allowedMachine-max') - const minMaxMachine = `${minMachine},${maxMachine}` - annotations['kubernetes.io/instance-type'] = minMaxMachine + return env || [] + } - const machines = getValue(discriminator, `/topologyMachines`) || [] - const minMachineObj = machines.find((item) => item.topologyValue === minMachine) - const maxMachineObj = machines.find((item) => item.topologyValue === maxMachine) - const minMachineAllocatable = minMachineObj?.allocatable - const maxMachineAllocatable = maxMachineObj?.allocatable - const allowedPath = `/resources/autoscalingKubedbComMemcachedAutoscaler/spec/compute/${type}` + function isEqualToTemp(value, index) { + //watchDependency('discriminator#/valueFromType') + const valueFrom = getValue(discriminator, `/env/${index}/temp/valueFromType`) + return valueFrom === value + } - 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 initMonitoring() { + const env = + getValue(model, '/resources/kubedbComMemcached/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 { - setMetadata, - isRancherManaged, - handleUnit, - isConsole, - getNamespaces, - getDbs, - isKubedb, - getDbDetails, - dbTypeEqualsTo, - clearSpecModel, - initMetadata, - onNamespaceChange, - ifScalingTypeEqualsTo, - fetchNodeTopology, - isNodeTopologySelected, - setControlledResources, - setTrigger, - setApplyToIfReady, - showOpsRequestOptions, - isVariantAvailable, - fetchJsons, - getAppbinding, - onDatabaseModeChange, - setDatabaseMode, - disableLableChecker, - isEqualToModelPathValue, - getResources, - isEqualToDiscriminatorPath, - setValueFromModel, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - returnTrue, - returnStringYes, - setAddressType, - getMemcachedVersions, - isEqualToDatabaseMode, - setApiGroup, - getIssuerRefsName, - hasIssuerRefName, - hasNoIssuerRefName, - setSSLMode, - showTlsConfigureSection, - onTlsConfigureChange, - getAliasOptions, - showMonitoringSection, - onEnableMonitoringChange, - showCustomizeExporterSection, - onCustomizeExporterChange, - valueExists, - onConfigurationChangeEdit, - setConfigurationForEdit, - initPrePopulateDatabase, - onPrePopulateDatabaseChange, - initDataSource, - onDataSourceChange, - initVolumeType, - onVolumeTypeChange, - showInitializationForm, - showScriptOrStashForm, - showConfigMapOrSecretName, - initializeNamespace, - showRepositorySelectOrCreate, - onInitRepositoryChoiseChange, - initCustomizeRestoreJobRuntimeSettings, - initCustomizeRestoreJobRuntimeSettingsForBackup, - onCustomizeRestoreJobRuntimeSettingsChange, - onCustomizeRestoreJobRuntimeSettingsChangeForBackup, - showRuntimeForm, - getImagePullSecrets, - getBackupConfigsAndAnnotations, - deleteKubeDbComMemcachedDbAnnotation, - addKubeDbComMemcachedDbAnnotation, - initScheduleBackup, - initScheduleBackupForEdit, - onScheduleBackupChange, - showBackupForm, - initBackupInvoker, - onBackupInvokerChange, - showInvokerForm, - initalizeTargetReferenceName, - setInitialRestoreSessionRepo, - initRepositoryChoise, - initRepositoryChoiseForEdit, - setConfigurationForEdit, - onRepositoryChoiseChange, - onRepositoryNameChange, - getMongoAnnotations, - initFromAnnotationValue, - onBackupBlueprintNameChange, - onBackupBlueprintScheduleChange, - initFromAnnotationKeyValue, - onTaskParametersChange, - isValueExistInModel, - onNamespaceChange, - onLabelChange, - onNameChange, - returnFalse, - onAgentChange, - getCreateAuthSecret, - showExistingSecretSection, - showPasswordSection, - setAuthSecretPassword, - onAuthSecretPasswordChange, - disableInitializationSection, - encodePassword, - decodePassword, - onCreateAuthSecretChange, - getSecrets, - onConfigurationSourceChange, - onConfigurationChange, - setConfigurationSource, - setSecretConfigNamespace, - setConfiguration, - setConfigurationFiles, - onSetCustomConfigChange, - getOpsRequestUrl, - onRefChange, - getAppBindings, - getMachines, - setAllowedMachine, - hasAnnotations, - hasNoAnnotations, - fetchTopologyMachines, - onMachineChange, + return { + returnFalse, + getDbDetails, + isConsole, + isKubedb, + getNamespaces, + onNamespaceChange, + getDbs, + initMetadata, + fetchTopologyMachines, + hasAnnotations, + setAllowedMachine, + getMachines, + onMachineChange, + hasNoAnnotations, + isNodeTopologySelected, + setControlledResources, + setTrigger, + setApplyToIfReady, + fetchNodeTopology, + showOpsRequestOptions, + isEqualToModelPathValue, + getResources, + resourceNames, + // Monitoring + showMonitoringSection, + onEnableMonitoringChange, + showCustomizeExporterSection, + onCustomizeExporterChange, + isValueExistInModel, + // onNamespaceChange, + onLabelChange, + onAgentChange, + getSecrets, + getOpsRequestUrl, + setValueFrom, + isConfigMapTypeValueFrom, + isSecretTypeValueFrom, + onValueFromChange, + getConfigMapKeys, + getSecretKeys, + onEnvArrayChange, + initEnvArray, + isEqualToTemp, + initMonitoring, + } } diff --git a/charts/kubedbcom-mongodb-editor-options/ui/create-ui.yaml b/charts/kubedbcom-mongodb-editor-options/ui/create-ui.yaml index 32d49650ed..f3ba788bff 100644 --- a/charts/kubedbcom-mongodb-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-mongodb-editor-options/ui/create-ui.yaml @@ -1,659 +1,732 @@ -steps: -- form: - discriminator: - bundleApiLoaded: - default: false - type: boolean - elements: - - computed: initBundle - if: returnFalse - type: label-element - - disableUnselect: true - fetch: getAdminOptions|databases/MongoDB/versions - if: isToggleOn|databases/MongoDB/versions - label: - text: labels.database.version - schema: - $ref: schema#/properties/spec/properties/admin/properties/databases/properties/MongoDB/properties/versions/properties/default - type: select - - computed: getDefault|databases/MongoDB/mode - fetch: getAdminOptions|databases/MongoDB/mode - hasDescription: true - if: isToggleOn|databases/MongoDB/mode - label: - text: labels.database.mode - onChange: clearArbiterHidden - schema: - $ref: schema#/properties/spec/properties/mode - type: radio - - discriminator: - enableHorizons: - default: false - type: boolean +step: +- type: single-step-form + loader: initBundle + elements: + - type: label-element + label: '' + subtitle: Select the MongoDB version you want to deploy on Kubernetes. The chosen version determines the MongoDB engine features, compatibility, and runtime behavior of your database cluster. + - disableUnselect: true + loader: getAdminOptions|databases/MongoDB/versions + if: + type: function + name: isToggleOn|databases/MongoDB/versions + label: Database Version + schema: schema/properties/spec/properties/admin/properties/databases/properties/MongoDB/properties/versions/properties/default + type: select + - init: + type: func + value: getDefault|databases/MongoDB/mode + loader: getAdminOptions|databases/MongoDB/mode + isHorizontal: true + if: + type: function + name: isToggleOn|databases/MongoDB/mode + label: Database Mode + watcher: + func: clearArbiterHidden + paths: + - schema/properties/spec/properties/mode + schema: schema/properties/spec/properties/mode + type: radio + - elements: + - type: horizontal-layout + showLabels: true elements: - - label: - text: labels.replicaset.name - schema: - $ref: schema#/properties/spec/properties/replicaSet/properties/name - type: input - - label: - text: labels.replicaset.number - onChange: updateSuffix - schema: - $ref: schema#/properties/spec/properties/replicaSet/properties/replicas - type: input - - if: isTlsOn - label: - text: Do you want to access mongodb+srv style dns? - onChange: onHorizonsChange - schema: - $ref: discriminator#/enableHorizons - type: switch - - alertInfo: - show: true - type: neutral - if: isHorizonsOn - label: - text: Horizons count should be equal to Replica Number. - type: label-element - - element: - label: - text: Add a new horizon dns for pod - schema: - $ref: schema#/properties/spec/properties/replicaSet/properties/horizons/items + - label: Replicaset Name + schema: schema/properties/spec/properties/replicaSet/properties/name + type: input + - label: Replicaset Number + watcher: + func: updateSuffix + paths: + - schema/properties/spec/properties/replicaSet/properties/replicas + schema: schema/properties/spec/properties/replicaSet/properties/replicas type: input - if: isHorizonsOn - label: - text: Horizons - onChange: updateSuffix - schema: - $ref: schema#/properties/spec/properties/replicaSet/properties/horizons - type: list-input-form - validationRuleObject: - func: isHorizonsValid - if: isEqualToModelPathValue|Replicaset|/spec/mode - schema: - $ref: schema#/properties/spec/properties/replicaSet - type: single-step-form + - if: + type: function + name: isTlsOn + label: Do you want to access mongodb+srv style DNS? + watcher: + func: onHorizonsChange + paths: + - discriminator/enableHorizons + schema: discriminator/enableHorizons + type: switch + - if: + type: function + name: isHorizonsOn + label: Horizons count should be equal to Replica Number. + type: alert + - type: array-item-form + element: + label: Add a new horizon dns for pod + type: input + if: + type: function + name: isHorizonsOn + label: Horizons + watcher: + func: updateSuffix + paths: + - schema/properties/spec/properties/replicaSet/properties/horizons + schema: schema/properties/spec/properties/replicaSet/properties/horizons + validation: + type: custom + name: isHorizonsValid + if: + type: function + name: isEqualToModelPathValue|Replicaset|/spec/mode + type: block-layout + - elements: - elements: - - elements: - - customClass: mt-10 - label: - text: labels.shards - schema: - $ref: schema#/properties/spec/properties/shardTopology/properties/shard/properties/shards + - type: label-element + label: '' + subtitle: Configure Shard Nodes to define how MongoDB data is partitioned, replicated, and resourced across your Kubernetes cluster. + - type: horizontal-layout + showLabels: true + elements: + - label: Shards + schema: schema/properties/spec/properties/shardTopology/properties/shard/properties/shards type: input - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/shardTopology/properties/shard/properties/replicas + - label: Replicaset Number + schema: schema/properties/spec/properties/shardTopology/properties/shard/properties/replicas type: input - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/shardTopology/properties/shard/properties/persistence/properties/size + - label: Storage size + schema: schema/properties/spec/properties/shardTopology/properties/shard/properties/persistence/properties/size type: input - - elements: - - computed: setMachineToCustom|shardTopology/shard - fetch: getMachineListForOptions - label: - text: labels.machine - schema: - $ref: schema#/properties/spec/properties/shardTopology/properties/shard/properties/podResources/properties/machine + - elements: + - type : horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom|shardTopology/shard + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/shardTopology/properties/shard/properties/podResources/properties/machine type: select - - computed: setLimits|cpu|shardTopology/shard - disabled: isMachineNotCustom|shardTopology/shard - if: isMachineCustom|shardTopology/shard - label: - text: labels.cpu - onChange: setRequests|cpu|shardTopology/shard - schema: - $ref: schema#/properties/spec/properties/shardTopology/properties/shard/properties/podResources/properties/resources/properties/requests/properties/cpu + - init: + type: func + value: setLimits|cpu|shardTopology/shard + if: + type: function + name: isMachineCustom|shardTopology/shard + label: cpu + watcher: + func: setRequests|cpu|shardTopology/shard + paths: + - schema/properties/spec/properties/shardTopology/properties/shard/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/shardTopology/properties/shard/properties/podResources/properties/machine + schema: schema/properties/spec/properties/shardTopology/properties/shard/properties/podResources/properties/resources/properties/requests/properties/cpu type: input - - computed: setLimits|memory|shardTopology/shard - disabled: isMachineNotCustom|shardTopology/shard - if: isMachineCustom|shardTopology/shard - label: - text: labels.memory - onChange: setRequests|memory|shardTopology/shard - schema: - $ref: schema#/properties/spec/properties/shardTopology/properties/shard/properties/podResources/properties/resources/properties/requests/properties/memory + - init: + type: func + value: setLimits|memory|shardTopology/shard + if: + type: function + name: isMachineCustom|shardTopology/shard + label: memory + watcher: + func: setRequests|memory|shardTopology/shard + paths: + - schema/properties/spec/properties/shardTopology/properties/shard/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/shardTopology/properties/shard/properties/podResources/properties/machine + schema: schema/properties/spec/properties/shardTopology/properties/shard/properties/podResources/properties/resources/properties/requests/properties/memory type: input - schema: - $ref: schema#/properties/spec/properties/shardTopology/properties/shard/properties/podResources - type: single-step-form - label: - text: labels.shardNodes - show_label: true - type: single-step-form - - elements: - - customClass: mt-10 - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/shardTopology/properties/configServer/properties/replicas + type: block-layout + label: Shard Nodes + showLabels: true + type: block-layout + - elements: + - type: label-element + label: '' + subtitle: Config Servers store metadata about the sharded cluster, including chunk distribution and shard configuration.They must run as a replica set to ensure cluster consistency and availability. + - type: horizontal-layout + showLabels: true + elements: + - label: Replicaset Number + schema: schema/properties/spec/properties/shardTopology/properties/configServer/properties/replicas type: input - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/shardTopology/properties/configServer/properties/persistence/properties/size + - label: Storage size + schema: schema/properties/spec/properties/shardTopology/properties/configServer/properties/persistence/properties/size type: input - - elements: - - computed: setMachineToCustom|shardTopology/configServer - fetch: getMachineListForOptions - label: - text: labels.machine - schema: - $ref: schema#/properties/spec/properties/shardTopology/properties/configServer/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu|shardTopology/configServer - disabled: isMachineNotCustom|shardTopology/configServer - if: isMachineCustom|shardTopology/configServer - label: - text: labels.cpu - onChange: setRequests|cpu|shardTopology/configServer - schema: - $ref: schema#/properties/spec/properties/shardTopology/properties/configServer/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory|shardTopology/configServer - disabled: isMachineNotCustom|shardTopology/configServer - if: isMachineCustom|shardTopology/configServer - label: - text: labels.memory - onChange: setRequests|memory|shardTopology/configServer - schema: - $ref: schema#/properties/spec/properties/shardTopology/properties/configServer/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - schema: - $ref: schema#/properties/spec/properties/shardTopology/properties/configServer/properties/podResources - type: single-step-form - label: - text: labels.configServer - show_label: true - type: single-step-form - elements: - - customClass: mt-10 - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/shardTopology/properties/mongos/properties/replicas - type: input - - elements: - - computed: setMachineToCustom|shardTopology/mongos - fetch: getMachineListForOptions - label: - text: labels.machine - schema: - $ref: schema#/properties/spec/properties/shardTopology/properties/mongos/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu|shardTopology/mongos - disabled: isMachineNotCustom|shardTopology/mongos - if: isMachineCustom|shardTopology/mongos - label: - text: labels.cpu - onChange: setRequests|cpu|shardTopology/mongos - schema: - $ref: schema#/properties/spec/properties/shardTopology/properties/mongos/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory|shardTopology/mongos - disabled: isMachineNotCustom|shardTopology/mongos - if: isMachineCustom|shardTopology/mongos - label: - text: labels.memory - onChange: setRequests|memory|shardTopology/mongos - schema: - $ref: schema#/properties/spec/properties/shardTopology/properties/mongos/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - schema: - $ref: schema#/properties/spec/properties/shardTopology/properties/mongos/properties/podResources - type: single-step-form - label: - text: labels.mongos - show_label: true - type: single-step-form - if: isEqualToModelPathValue|Sharded|/spec/mode - type: single-step-form + - type : horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom|shardTopology/configServer + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/shardTopology/properties/configServer/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu|shardTopology/configServer + if: + type: function + name: isMachineCustom|shardTopology/configServer + label: cpu + watcher: + func: setRequests|cpu|shardTopology/configServer + paths: + - schema/properties/spec/properties/shardTopology/properties/configServer/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/shardTopology/properties/configServer/properties/podResources/properties/machine + schema: schema/properties/spec/properties/shardTopology/properties/configServer/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory|shardTopology/configServer + if: + type: function + name: isMachineCustom|shardTopology/configServer + label: memory + watcher: + func: setRequests|memory|shardTopology/configServer + paths: + - schema/properties/spec/properties/shardTopology/properties/configServer/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/shardTopology/properties/configServer/properties/podResources/properties/machine + schema: schema/properties/spec/properties/shardTopology/properties/configServer/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + type: block-layout + label: Config Server + showLabels: true + type: block-layout - elements: - - computed: setMachineToCustom - customClass: mt-10 - fetch: getMachineListForOptions - label: - text: labels.machine - schema: - $ref: schema#/properties/spec/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.cpu - onChange: setRequests|cpu - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - type: label-element + label: '' + subtitle: Mongos acts as the query router for the sharded cluster, directing client requests to the appropriate shards based on metadata from Config Servers. + - customClass: mt-10 + label: Replicaset number + schema: schema/properties/spec/properties/shardTopology/properties/mongos/properties/replicas type: input - - computed: setLimits|memory - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.memory - onChange: setRequests|memory - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - if: notEqualToDatabaseMode|Sharded - label: - text: labels.machine_profile - show_label: true - type: single-step-form - - fetch: getAdminOptions|storageClasses - if: isToggleOn|storageClasses - label: - text: labels.storage.select - schema: - $ref: schema#/properties/spec/properties/admin/properties/storageClasses/properties/default - type: select - - if: showStorageSizeField - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/persistence/properties/size - type: input - - accordion: true - description: - text: Configure Credentials, Deployment Mode etc. - discriminator: - configDatabase: - default: false - type: boolean - createAuthSecret: - default: false - type: boolean - recovery: - default: false - type: boolean - referSecret: - default: false - type: boolean + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom|shardTopology/mongos + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/shardTopology/properties/mongos/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu|shardTopology/mongos + if: + type: function + name: isMachineCustom|shardTopology/mongos + label: Cpu + watcher: + func: setRequests|cpu|shardTopology/mongos + paths: + - schema/properties/spec/properties/shardTopology/properties/mongos/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/shardTopology/properties/mongos/properties/podResources/properties/machine + schema: schema/properties/spec/properties/shardTopology/properties/mongos/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory|shardTopology/mongos + if: + type: function + name: isMachineCustom|shardTopology/mongos + label: Memory + watcher: + func: setRequests|memory|shardTopology/mongos + paths: + - schema/properties/spec/properties/shardTopology/properties/mongos/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/shardTopology/properties/mongos/properties/podResources/properties/machine + schema: schema/properties/spec/properties/shardTopology/properties/mongos/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + label: Mongos + showLabels: true + type: block-layout + if: + type: function + name: isEqualToModelPathValue|Sharded|/spec/mode + type: block-layout + - elements: + - type: label-element + label: '' + subtitle: Select a machine profile to allocate CPU and memory resources for your database. Choose 'custom' to manually specify resource requirements or select a predefined profile. + - type: horizontal-layout + showLabels: true elements: - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties - type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties - type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - computed: getDefault|deletionPolicy - customClass: mt-20 - if: isToggleOn|deletionPolicy - 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/spec/properties/deletionPolicy - type: select - - if: getDefaultValue|spec/admin/authCredential/customize - label: - text: Provide Authentication Credentials? - onChange: onAuthChange - schema: - $ref: discriminator#/createAuthSecret - type: switch - - if: showReferSecretSwitch - label: - text: Refer existing Secret? - onChange: onReferSecretChange - schema: - $ref: discriminator#/referSecret - type: switch - - fetch: getReferSecrets - if: showSecretDropdown - label: - text: Secret - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/name - type: select - - if: showReferSecret - label: - text: labels.password - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/password - type: input - - computed: isConfigAvailable - if: getDefaultValue|spec/admin/customConfiguration - label: - text: Configure Database? - onChange: clearConfiguration - schema: - $ref: discriminator#/configDatabase - type: switch - - if: isConfigDatabaseOn - label: - text: Configuration - schema: - $ref: schema#/properties/spec/properties/configuration - type: editor - - if: notEqualToDatabaseMode|Standalone - label: - text: Enable Arbiter? - schema: - $ref: schema#/properties/spec/properties/arbiter/properties/enabled - type: switch - - elements: - - elements: - - computed: setMachineToCustom|arbiter - customClass: mt-10 - fetch: getMachineListForOptions - label: - text: labels.machine - schema: - $ref: schema#/properties/spec/properties/arbiter/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu|arbiter - disabled: isMachineNotCustom|arbiter - if: isMachineCustom|arbiter - label: - text: labels.cpu - onChange: setRequests|cpu|arbiter - schema: - $ref: schema#/properties/spec/properties/arbiter/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory|arbiter - disabled: isMachineNotCustom|arbiter - if: isMachineCustom|arbiter - label: - text: labels.memory - onChange: setRequests|memory|arbiter - schema: - $ref: schema#/properties/spec/properties/arbiter/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - schema: - $ref: schema#/properties/spec/properties/arbiter/properties/podResources - type: single-step-form - if: showArbiter - label: - text: Arbiter - schema: - $ref: schema#/properties/spec/properties/arbiter - show_label: true - type: single-step-form - - if: notEqualToDatabaseMode|Standalone - label: - text: Enable hidden? - schema: - $ref: schema#/properties/spec/properties/hidden/properties/enabled - type: switch - - elements: - - customClass: mt-10 - label: - text: Replicas - schema: - $ref: schema#/properties/spec/properties/hidden/properties/replicas + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu + disable: isMachineNotCustom|schema/properties/spec/properties/podResources/properties/machine + if: + type: function + name: isMachineCustom + label: cpu + watcher: + func: setRequests|cpu + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu type: input - - label: - text: Persistence Size - schema: - $ref: schema#/properties/spec/properties/hidden/properties/persistence/properties/size + - init: + type: func + value: setLimits|memory + if: + type: function + name: isMachineCustom + label: Memory + watcher: + func: setRequests|memory + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory type: input - - computed: setMachineToCustom|hidden - fetch: getMachineListForOptions - label: - text: labels.machine - schema: - $ref: schema#/properties/spec/properties/hidden/properties/podResources/properties/machine + if: + type: function + name: notEqualToDatabaseMode|Sharded + label: Machine profile + showLabels: true + type: block-layout + - type: horizontal-layout + showLabels: true + elements: + - loader: getAdminOptions|storageClasses + if: + type: function + name: isToggleOn|storageClasses + label: Storage select + schema: schema/properties/spec/properties/admin/properties/storageClasses/properties/default + type: select + - if: + type: function + name: showStorageSizeField + label: Storage size + schema: schema/properties/spec/properties/persistence/properties/size + type: input + - description: Configure Credentials, Deployment Mode etc. + elements: + - elements: + - type: label-element + label: '' + subtitle: Add custom labels and annotations to your database resources for organization, monitoring, and integration with other Kubernetes tools and services. + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/annotations + label: Labels & Annotations + showLabels: true + hideBlock: true + type: block-layout + - init: + type: func + value: getDefault|deletionPolicy + customClass: mt-20 + if: + type: function + name: isToggleOn|deletionPolicy + label: Deletion Policy + watcher: + func: setStorageClass + paths: + - schema/properties/spec/properties/deletionPolicy + options: + - description: options.deletionPolicy.delete.description + text: Delete + value: Delete + - description: options.deletionPolicy.halt.description + text: Halt + value: Halt + - description: options.deletionPolicy.wipeOut.description + text: WipeOut + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: DoNotTerminate + value: DoNotTerminate + schema: schema/properties/spec/properties/deletionPolicy + type: select + - if: + type: function + name: getDefaultValue|spec/admin/authCredential/customize + label: Provide Authentication Credentials? + watcher: + func: onAuthChange + paths: + - temp/createAuthSecret + schema: temp/createAuthSecret + type: switch + - if: + type: function + name: showReferSecretSwitch + label: Refer existing Secret? + watcher: + func: onReferSecretChange + paths: + - temp/referSecret + schema: temp/referSecret + type: switch + - loader: getReferSecrets + if: + type: function + name: showSecretDropdown + label: Secret + schema: schema/properties/spec/properties/authSecret/properties/name + type: select + - if: + type: function + name: showReferSecret + label: Password + schema: schema/properties/spec/properties/authSecret/properties/password + type: input + - if: + type: function + name: getDefaultValue|spec/admin/customConfiguration + label: Configure Database? + watcher: + func: clearConfiguration + paths: + - temp/configDatabase + schema: temp/configDatabase + type: switch + - if: + type: function + name: isConfigDatabaseOn + label: Configuration + # hasCopy: true + schema: schema/properties/spec/properties/configuration + type: textarea + - if: + type: function + name: notEqualToDatabaseMode|Standalone + label: Enable Arbiter? + schema: schema/properties/spec/properties/arbiter/properties/enabled + type: switch + - elements: + - type: label-element + label: '' + subtitle: Configure resource allocation for arbiter nodes, which participate in elections but do not store data. Arbiters help maintain quorum in replica sets with minimal resource overhead. + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom|arbiter + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/arbiter/properties/podResources/properties/machine type: select - - computed: setLimits|cpu|hidden - disabled: isMachineNotCustom|hidden - if: isMachineCustom|hidden - label: - text: labels.cpu - onChange: setRequests|cpu|hidden - schema: - $ref: schema#/properties/spec/properties/hidden/properties/podResources/properties/resources/properties/requests/properties/cpu + - init: + type: func + value: setLimits|cpu|arbiter + if: + type: function + name: isMachineCustom|arbiter + label: cpu + watcher: + func: setRequests|cpu|arbiter + paths: + - schema/properties/spec/properties/arbiter/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/arbiter/properties/podResources/properties/machine + schema: schema/properties/spec/properties/arbiter/properties/podResources/properties/resources/properties/requests/properties/cpu type: input - - computed: setLimits|memory|hidden - disabled: isMachineNotCustom|hidden - if: isMachineCustom|hidden - label: - text: labels.memory - schema: - $ref: schema#/properties/spec/properties/hidden/properties/podResources/properties/resources/properties/requests/properties/memory + - init: + type: func + value: setLimits|memory|arbiter + if: + type: function + name: isMachineCustom|arbiter + label: memory + watcher: + func: setRequests|memory|arbiter + paths: + - schema/properties/spec/properties/arbiter/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/arbiter/properties/podResources/properties/machine + schema: schema/properties/spec/properties/arbiter/properties/podResources/properties/resources/properties/requests/properties/memory type: input - if: showHidden - label: - text: Hidden - schema: - $ref: schema#/properties/spec/properties/hidden/properties/podResources - show_label: true - type: single-step-form - - computed: getDefault|pointInTimeRecovery - if: isToggleOn|pointInTimeRecovery - label: - text: Point in-time Recovery? - schema: - $ref: discriminator#/recovery - type: switch - - discriminator: - refDBName: - type: string - refNamespace: - type: string + if: + type: function + name: showArbiter + label: Arbiter + showLabels: true + type: block-layout + - if: + type: function + name: notEqualToDatabaseMode|Standalone + label: Enable hidden? + schema: schema/properties/spec/properties/hidden/properties/enabled + type: switch + - elements: + - type: label-element + label: '' + subtitle: Configure hidden members that replicate data invisibly to clients. Define replicas, storage, and resource allocation for dedicated backup, analytics, or reporting operations. + - type: horizontal-layout + showLabels: true elements: - - label: - text: Namespace - onChange: setPointInTimeRecovery - required: true - schema: - $ref: discriminator#/refNamespace + - label: Replicas + schema: schema/properties/spec/properties/hidden/properties/replicas type: input - - label: - text: Name - onChange: setPointInTimeRecovery - required: true - schema: - $ref: discriminator#/refDBName + - label: Persistence Size + schema: schema/properties/spec/properties/hidden/properties/persistence/properties/size type: input - - customClass: mt-10 - label: - text: Recovery Timestamp - schema: - $ref: schema#/properties/spec/properties/init/properties/archiver/properties/recoveryTimestamp + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom|hidden + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/hidden/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu|hidden + if: + type: function + name: isMachineCustom|hidden + label: cpu + watcher: + func: setRequests|cpu|hidden + paths: + - schema/properties/spec/properties/hidden/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/hidden/properties/podResources/properties/machine + schema: schema/properties/spec/properties/hidden/properties/podResources/properties/resources/properties/requests/properties/cpu type: input - if: showRecovery - label: - text: Point in-time Recovery - schema: - $ref: schema#/properties/spec/properties/init/properties/archiver - show_label: true - type: single-step-form - - hasDescription: true - if: isToggleOn|deployment - label: - text: labels.deployment.name - options: - - description: labels.deployment.shared - text: Shared - value: Shared - - description: labels.deployment.dedicated - text: Dedicated - value: Dedicated - schema: - $ref: schema#/properties/spec/properties/admin/properties/deployment/properties/default - type: radio - - if: isToggleOn|clusterTier - isHorizontal: true - label: - text: labels.clusterTier + - init: + type: func + value: setLimits|memory|hidden + if: + type: function + name: isMachineCustom|hidden + label: memory + watcher: + func: setRequests|memory|hidden + paths: + - schema/properties/spec/properties/hidden/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/hidden/properties/podResources/properties/machine + schema: schema/properties/spec/properties/hidden/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + if: + type: function + name: showHidden + label: Hidden + showLabels: true + type: block-layout + - init: + type: func + value: getDefault|pointInTimeRecovery + if: + type: function + name: isToggleOn|pointInTimeRecovery + label: Point in-time Recovery? + schema: temp/recovery + type: switch + - elements: + - type: label-element + label: '' + subtitle: Restore your database to a specific point in time by selecting the source backup namespace, database name, and the exact timestamp for recovery. + - type: horizontal-layout + showLabels: true + elements: + - label: Namespace + watcher: + func: setPointInTimeRecovery + paths: + - temp/refNamespace + forceRequired: true + validation: + type: required + schema: temp/refNamespace + type: input + - label: Name + watcher: + func: setPointInTimeRecovery + paths: + - temp/refDBName + validation: + type: required + schema: temp/refDBName + type: input + - label: Recovery Timestamp + schema: schema/properties/spec/properties/init/properties/archiver/properties/recoveryTimestamp + type: date-time + watcher: + func: onTimestampChange + paths: + - schema/properties/spec/properties/init/properties/archiver/properties/recoveryTimestamp + if: + type: function + name: showRecovery + label: Point in-time Recovery + showLabels: true + type: block-layout + - if: + type: function + name: isToggleOn|deployment + label: Deployment + options: + - description: shared + text: Shared + value: Shared + - description: Dedicated + text: Dedicated + value: Dedicated + schema: schema/properties/spec/properties/admin/properties/deployment/properties/default + type: radio + - if: + type: function + name: isToggleOn|clusterTier + isHorizontal: true + label: ClusterTier + options: + - text: General Purpose + value: GeneralPurpose + - text: Memory Optimized + value: MemoryOptimized + - text: CPU Optimized + value: CPUOptimized + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/default + type: radio + - disableUnselect: true + loader: getAdminOptions|clusterTier/placement + if: + type: function + name: isToggleOn|clusterTier/placement + label: labels.placement + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + type: select + - disableUnselect: true + loader: getNodeTopology + if: + type: function + name: isToggleOn|clusterTier/nodeTopology + label: NodeTopology + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + type: select + label: Advanced Configuration + showLabels: true + type: block-layout + - description: Enable Backup, Monitoring, TLS etc. + elements: + - elements: + - init: + type: func + value: setMonitoring + label: Enable Monitoring + watcher: + func: updateAlertValue + paths: + - temp/monitoring + schema: temp/monitoring + type: switch + - customClass: mt-10 + if: + type: function + name: showAlerts + label: Alert Options options: - - text: General Purpose - value: GeneralPurpose - - text: Memory Optimized - value: MemoryOptimized - - text: CPU Optimized - value: CPUOptimized - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/default - type: radio - - disableUnselect: true - fetch: getAdminOptions|clusterTier/placement - if: isToggleOn|clusterTier/placement - label: - text: labels.placement - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + - text: None + value: none + - text: Critical + value: critical + - text: Warning + value: warning + - text: Info + value: info + schema: schema/properties/form/properties/alert/properties/enabled type: select - - disableUnselect: true - fetch: getNodeTopology - if: isToggleOn|clusterTier/nodeTopology - label: - text: labels.nodeTopology - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + if: + type: function + name: isToggleOn|monitoring + type: block-layout + - init: + type: func + value: setBackup + if: + type: function + name: isToggleOn|backup + + label: Enable Backup? + watcher: + func: onBackupSwitch + paths: + - temp/backup + schema: temp/backup + type: switch + - elements: + - disable: showArchiverAlert + label: Enable Archiver? + watcher: + func: onArchiverChange + paths: + - schema/properties/spec/properties/admin/properties/archiver/properties/enable/properties/default + schema: schema/properties/spec/properties/admin/properties/archiver/properties/enable/properties/default + type: switch + - if: + type: function + name: showArchiverAlert + label: The selected StorageClass does not support Archiver + type: warning + if: + type: function + name: showArchiver + type: block-layout + - elements: + - init: + type: func + value: checkHostnameOrIP + if: + type: function + name: isToggleOn|tls + label: Enable TLS? + watcher: + func: checkHostnameOrIP + paths: + - schema/properties/spec/properties/admin/properties/tls/properties/default + schema: schema/properties/spec/properties/admin/properties/tls/properties/default + type: switch + - loader: getAdminOptions|clusterIssuers + if: + type: function + name: showIssuer + label: Cluster Issuers + validation: + type: required + schema: schema/properties/spec/properties/admin/properties/clusterIssuers/properties/default type: select - hideForm: true - label: - text: Advanced Configuration - show_label: true - type: single-step-form - - accordion: true - description: - text: Enable Backup, Monitoring, TLS etc. - discriminator: - backup: - default: false - type: boolean - elements: - - discriminator: - monitoring: - default: false - type: boolean - elements: - - computed: setMonitoring - label: - text: labels.enable_monitoring - onChange: updateAlertValue - schema: - $ref: discriminator#/monitoring - type: switch - - customClass: mt-10 - if: showAlerts - label: - text: labels.alert.options - options: - - text: None - value: none - - text: Critical - value: critical - - text: Warning - value: warning - - text: Info - value: info - schema: - $ref: schema#/properties/form/properties/alert/properties/enabled - sortable: true - type: select - if: isToggleOn|monitoring - type: single-step-form - - computed: setBackup - if: isToggleOn|backup - label: - text: Enable Backup? - onChange: onBackupSwitch - schema: - $ref: discriminator#/backup + type: block-layout + - elements: + - init: + type: func + value: checkHostnameOrIP + if: + type: function + name: isToggleOn|expose + label: Expose via Gateway? + watcher: + func: checkHostnameOrIP + paths: + - schema/properties/spec/properties/admin/properties/expose/properties/default + schema: schema/properties/spec/properties/admin/properties/expose/properties/default type: switch - - elements: - - disabled: showArchiverAlert - label: - text: Enable Archiver? - onChange: onArchiverChange - schema: - $ref: schema#/properties/spec/properties/admin/properties/archiver/properties/enable/properties/default - type: switch - - alertInfo: - show: true - type: neutral - if: showArchiverAlert - label: - text: The selected StorageClass does not support Archiver - type: label-element - if: showArchiver - type: single-step-form - - elements: - - computed: checkHostnameOrIP - if: isToggleOn|tls - label: - text: Enable TLS? - onChange: checkHostnameOrIP - schema: - $ref: schema#/properties/spec/properties/admin/properties/tls/properties/default - type: switch - - fetch: getAdminOptions|clusterIssuers - if: showIssuer - label: - text: labels.clusterIssuers - required: true - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterIssuers/properties/default - type: select - type: single-step-form - - elements: - - computed: checkHostnameOrIP - if: isToggleOn|expose - label: - text: Expose via Gateway? - onChange: checkHostnameOrIP - schema: - $ref: schema#/properties/spec/properties/admin/properties/expose/properties/default - type: switch - type: single-step-form - if: showAdditionalSettings - label: - text: Additional Options - show_label: true - type: single-step-form - type: single-step-form + type: block-layout + if: + type: function + name: showAdditionalSettings + label: Additional Options + showLabels: true + type: block-layout id: options - title: steps.0.label -type: multi-step-form + # title: steps.0.label +type: multi-step-form \ No newline at end of file diff --git a/charts/kubedbcom-mongodb-editor-options/ui/functions.js b/charts/kubedbcom-mongodb-editor-options/ui/functions.js index b12b2a9522..fdce7721b9 100644 --- a/charts/kubedbcom-mongodb-editor-options/ui/functions.js +++ b/charts/kubedbcom-mongodb-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -319,1260 +321,1351 @@ const modeDetails = { }, } -async function getReferSecrets({ getValue, model, storeGet, axios, discriminator }) { - const referSecret = getValue(discriminator, '/referSecret') - if (!referSecret) { - return [] - } - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/metadata/release/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - - const options = [] - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) - } catch (e) { - console.log(e) +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) + + setDiscriminatorValue('bundleApiLoaded', false) + setDiscriminatorValue('enableHorizons', false) + setDiscriminatorValue('configDatabase', false) + setDiscriminatorValue('createAuthSecret', false) + setDiscriminatorValue('recovery', false) + setDiscriminatorValue('referSecret', false) + setDiscriminatorValue('refDBName', '') + setDiscriminatorValue('refNamespace', '') + setDiscriminatorValue('backup', false) + setDiscriminatorValue('monitoring', false) + + async function getReferSecrets() { + const referSecret = getValue(discriminator, '/referSecret') + if (!referSecret) { + return [] + } + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/metadata/release/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` + + const options = [] + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + return options } - return options -} -function showAuthPasswordField({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showAuthPasswordField() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !modelPathValue && showReferSecret() + } -function showSecretDropdown({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showSecretDropdown() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !!modelPathValue && showReferSecret() + } -function showReferSecret({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/createAuthSecret') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue -} + function showReferSecret() { + const modelPathValue = getValue(discriminator, '/createAuthSecret') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue + } -function showReferSecretSwitch({ model, getValue, watchDependency, discriminator }) { - const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showReferSecretSwitch() { + const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue && showReferSecret() + } -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } -function showStorageSizeField({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - const validType = ['Standalone', 'Replicaset'] - return validType.includes(modelPathValue) -} + function showStorageSizeField() { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + const validType = ['Standalone', 'Replicaset'] + return validType.includes(modelPathValue) + } -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, }, - }, - ) - const projects = resp?.data?.status?.projects - if (projects) { - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - namespaces = projectsNamespace - } else { - namespaces = resp?.data?.status?.namespaces || [] + ) + const projects = resp?.data?.status?.projects + if (projects) { + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + namespaces = projectsNamespace + } else { + namespaces = resp?.data?.status?.namespaces || [] + } + return namespaces + } catch (e) { + console.log(e) + return [] } - return namespaces - } catch (e) { - console.log(e) - return [] } -} - -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/spec/authSecret/name') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/spec/authSecret/password') + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found } -} -function isMachineCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue === 'custom' -} + function onCreateAuthSecretChange() { + const createAuthSecret = getValue(discriminator, '/createAuthSecret') + if (createAuthSecret) { + commit('wizard/model$delete', '/spec/authSecret/name') + } else if (createAuthSecret === false) { + commit('wizard/model$delete', '/spec/authSecret/password') + } + } -function isMachineNotCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue !== 'custom' && !!modelPathValue -} + function isMachineCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue === 'custom' + } -function getMachineListForOptions({ model, getValue }) { - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') + function isMachineNotCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue !== 'custom' && !!modelPathValue + } let array = [] + function getMachineListForOptions() { + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') - if (available.length) { - array = available.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - else { - let subText = '', - text = '' - const machineData = machinesFromPreset.find((val) => val.id === machine) - if (machineData) { - subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` - text = machineData.name ? machineData.name : machineData.id - } - return { text, subText, value: machine } - } - }) - } else { - array = machineList - .map((machine) => { + if (available.length) { + array = available.map((machine) => { if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + else { + let subText = '', + text = '' + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + text = machineData.name ? machineData.name : machineData.id + } + return { text, subText, value: machine } + } }) - .filter((val) => !!val) + } else { + array = machineList + .map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { text, subText, value: machine } + }) + .filter((val) => !!val) + } + return array } - return array -} -function setLimits({ model, getValue, commit, watchDependency }, resource, type) { - const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' - watchDependency(`model#${path}`) - const selectedMachine = getValue(model, path) || 'custom' - const reqCommitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - const comparePath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - - const resourceValue = getValue(model, comparePath) - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - - let cpu = '', - memory = '' - if (available.length && selectedMachine !== 'custom') { - const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) - if (machineData) { - cpu = machineData.limits.cpu - memory = machineData.limits.memory + function setLimits(resource, type) { + const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' + // watchDependency(`model#${path}`) + const selectedMachine = getValue(model, path) || 'custom' + const reqCommitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + const comparePath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + + const resourceValue = getValue(model, comparePath) + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + let cpu = '', + memory = '' + if (available.length && selectedMachine !== 'custom') { + const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) + if (machineData) { + cpu = machineData.limits.cpu + memory = machineData.limits.memory + } + } else { + if (selectedMachine === 'custom') { + cpu = resourceValue + memory = resourceValue + } else { + cpu = machines[selectedMachine].resources.limits.cpu + memory = machines[selectedMachine].resources.limits.memory + } } - } else { - if (selectedMachine === 'custom') { - cpu = resourceValue - memory = resourceValue + if (resource === 'memory') { + commit('wizard/model$update', { + path: reqCommitPath, + value: memory, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: memory, + force: true, + }) + return memory } else { - cpu = machines[selectedMachine].resources.limits.cpu - memory = machines[selectedMachine].resources.limits.memory + commit('wizard/model$update', { + path: reqCommitPath, + value: cpu, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: cpu, + force: true, + }) + return cpu } } - if (resource === 'memory') { + function setRequests(resource, type) { + const modelPath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + + const fullpath = `/spec/podResources/machine` + const modelPathValue = getValue(model, fullpath) + commit('wizard/model$update', { - path: reqCommitPath, - value: memory, + path: commitPath, + value: val, force: true, }) + + if (modelPathValue === 'custom') { + return + } + let commitCpuMemory, ModelPathValue + if (resource && type) { + const fullPath = `/spec/${type}/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/${type}/podResources/resources/requests/${resource}` + } else { + const fullPath = `/spec/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/podResources/resources/requests/${resource}` + } + let cpuMemoryValue + array.forEach((item) => { + if (item.value === ModelPathValue) { + // Parse subText like "CPU: 2, Memory: 2Gi" + const subText = item.subText || '' + if (resource === 'cpu') { + // Extract CPU value + const cpuMatch = subText.match(/CPU:\s*([^,]+)/) + cpuMemoryValue = cpuMatch ? cpuMatch[1].trim() : '' + } else if (resource === 'memory') { + // Extract Memory value + const memoryMatch = subText.match(/Memory:\s*(.+)/) + cpuMemoryValue = memoryMatch ? memoryMatch[1].trim() : '' + } + } + }) commit('wizard/model$update', { - path: comparePath, - value: memory, + path: commitCpuMemory, + value: cpuMemoryValue, force: true, }) - return memory - } else { + return cpuMemoryValue + } + + function setMachineToCustom(type) { + let path = '' + path = '/spec/admin/machineProfiles/default' + const machine = getValue(model, path) + return machine || 'custom' + } + + async function fetchJsons() { + 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 updateAlertValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const alert = isMonitorEnabled ? 'warning' : 'none' + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: reqCommitPath, - value: cpu, + path: '/form/alert/enabled', + value: alert, force: true, }) + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' commit('wizard/model$update', { - path: comparePath, - value: cpu, + path: '/spec/admin/monitoring/agent', + value: agent, force: true, }) - return cpu } -} - -function setRequests({ getValue, model, commit }, resource, type) { - const modelPath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - const val = getValue(model, modelPath) - commitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - commit('wizard/model$update', { - path: commitPath, - value: val, - force: true, - }) -} -function setMachineToCustom({ getValue, model }) { - const machine = getValue(model, '/spec/admin/machineProfiles/default') - return machine || 'custom' -} + function getCreateNameSpaceUrl() { + const user = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -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) + const domain = storeGet('/domain') || '' + if (domain.includes('bb.test')) { + return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } } - return { - ui: ui.data || {}, - language: language.data || {}, - functions, + const ifCapiProviderIsNotEmpty = () => { + // watchDependency('model#/form/capi/provider') + const val = getValue(model, '/form/capi/provider') + if (val) return true } -} - -function updateAlertValue({ commit, model, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const alert = isMonitorEnabled ? 'warning' : 'none' - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: alert, - force: true, - }) - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + const showMultiselectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + if (val === 'capz' && ifDedicated()) return true } -} - -const ifCapiProviderIsNotEmpty = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/provider') - const val = getValue(model, '/form/capi/provider') - if (val) return true -} - -const showMultiselectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') - if (val === 'capz' && ifDedicated({ model, getValue })) return true -} - -const showSelectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') - if (val !== 'capz' && ifDedicated({ model, getValue })) return true -} - -const ifDedicated = ({ model, getValue }) => { - const val = getValue(model, 'form/capi/dedicated') - if (val) return true -} + const showSelectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') + if (val !== 'capz' && ifDedicated()) return true + } -const dedicatedOnChange = ({ model, getValue, commit }) => { - const val = getValue(model, 'form/capi/dedicated') - if (!val) { - commit('wizard/model$delete', 'form/capi/zones') - commit('wizard/model$delete', 'form/capi/sku') + const ifDedicated = () => { + const val = getValue(model, 'form/capi/dedicated') + if (val) return true } -} -const ifZones = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/zones') - watchDependency('model#/form/capi/dedicated') - const zones = getValue(model, 'form/capi/zones') || [] - const isDedicated = getValue(model, 'form/capi/dedicated') - if (zones.length && isDedicated) return true -} + const dedicatedOnChange = () => { + const val = getValue(model, 'form/capi/dedicated') + if (!val) { + commit('wizard/model$delete', 'form/capi/zones') + commit('wizard/model$delete', 'form/capi/sku') + } + } -const zonesOnChange = ({ model, getValue, commit }) => { - const zones = getValue(model, 'form/capi/zones') || [] - if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') -} + const ifZones = () => { + // watchDependency('model#/form/capi/zones') + // watchDependency('model#/form/capi/dedicated') + const zones = getValue(model, 'form/capi/zones') || [] + const isDedicated = getValue(model, 'form/capi/dedicated') + if (zones.length && isDedicated) return true + } -async function getZones({ storeGet, axios, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const isDedicated = getValue(model, 'form/capi/dedicated') - if (isDedicated) { - try { - const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) - const val = resp.data.map((item) => { - return { value: item, text: item } - }) - return val - } catch (e) { - console.log(e) - return [] - } + const zonesOnChange = () => { + const zones = getValue(model, 'form/capi/zones') || [] + if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') } -} -async function getSKU({ storeGet, axios, model, getValue, watchDependency }) { - watchDependency('model#/form/capi/zones') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const zones = getValue(model, 'form/capi/zones') || [] - if (zones.length) { - try { - let url = `clustersv2/${owner}/${cluster}/vms?` - if (typeof zones === 'string') { - url += `zones=${encodeURIComponent(zones)}` - } else { - zones.forEach((item) => { - url += `zones=${encodeURIComponent(item)}&` + async function getZones() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const isDedicated = getValue(model, 'form/capi/dedicated') + if (isDedicated) { + try { + const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) + const val = resp.data.map((item) => { + return { value: item, text: item } }) - url = url.slice(0, -1) + return val + } catch (e) { + console.log(e) + return [] } - const resp = await axios.get(url) - const val = resp.data.map((item) => { - return { - value: item.name, - text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb]`, - } - }) - return val - } catch (e) { - console.log(e) - return [] } } -} - -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} - -function setStorageClass({ model, commit, getValue, discriminator, watchDependency }) { - const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' - let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' - const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] - const suffix = '-retain' - - const simpleClassList = storageClassList.filter((item) => { - return !item.endsWith(suffix) - }) - const retainClassList = storageClassList.filter((item) => { - return item.endsWith(suffix) - }) - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] - } else { - storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + async function getSKU() { + // watchDependency('model#/form/capi/zones') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const zones = getValue(model, 'form/capi/zones') || [] + if (zones.length) { + try { + let url = `clustersv2/${owner}/${cluster}/vms?` + if (typeof zones === 'string') { + url += `zones=${encodeURIComponent(zones)}` + } else { + zones.forEach((item) => { + url += `zones=${encodeURIComponent(item)}&` + }) + url = url.slice(0, -1) + } + const resp = await axios.get(url) + const val = resp.data.map((item) => { + return { + value: item.name, + text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb]`, + } + }) + return val + } catch (e) { + console.log(e) + return [] + } + } } - const isChangeable = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'storageClasses', - ) - if (isChangeable && storageClass) { - commit('wizard/model$update', { - path: '/spec/admin/storageClasses/default', - value: storageClass, - force: true, - }) + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false } -} - -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} - -function showArbiter({ watchDependency, model, getValue }) { - watchDependency('model#/spec/arbiter/enabled') - const isArbiterOn = getValue(model, '/spec/arbiter/enabled') || '' - const notStandalone = notEqualToDatabaseMode({ model, getValue, watchDependency }, 'Standalone') - return isArbiterOn && notStandalone -} - -function showRecovery({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/recovery') - const isRecoveryOn = getValue(discriminator, '/recovery') || '' - return isRecoveryOn -} - -function showHidden({ watchDependency, model, getValue }) { - watchDependency('model#/spec/hidden/enabled') - const isHiddenOn = getValue(model, '/spec/hidden/enabled') || '' - const notStandalone = notEqualToDatabaseMode({ model, getValue, watchDependency }, 'Standalone') - return isHiddenOn && notStandalone -} - -function clearArbiterHidden({ commit }) { - commit('wizard/model$update', { - path: `/spec/arbiter/enabled`, - value: false, - force: true, - }) - - commit('wizard/model$update', { - path: `/spec/hidden/enabled`, - value: false, - force: true, - }) -} - -function isConfigDatabaseOn({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configDatabase') - return getValue(discriminator, '/configDatabase') -} - -function isConfigAvailable({ getValue, model }) { - const val = getValue(model, '/spec/configuration') - return val !== '' -} -function clearConfiguration({ discriminator, getValue, commit }) { - const configOn = getValue(discriminator, '/configDatabase') + function setStorageClass() { + const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' + let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' + const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] + const suffix = '-retain' - if (!configOn) { - commit('wizard/model$delete', '/spec/configuration') - } -} + const simpleClassList = storageClassList.filter((item) => { + return !item.endsWith(suffix) + }) + const retainClassList = storageClassList.filter((item) => { + return item.endsWith(suffix) + }) -function returnFalse() { - return false -} + if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { + storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] + } else { + storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + } -let placement = [] -let versions = [] -let storageClass = [] -let clusterIssuers = [] -let nodetopologiesShared = [] -let nodetopologiesDedicated = [] -let features = [] -let namespaces = [] -let hostName = '' -let ip = '' -async function initBundle({ commit, model, getValue, axios, storeGet, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - let db = getValue(model, '/metadata/resource/kind') - db = db.toLowerCase() - let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` - const gatewayinfosurl = `/clusters/${owner}/${cluster}/proxy/meta.k8s.appscode.com/v1alpha1/gatewayinfos/${namespace}` - const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - try { - const resp = await axios.get(url) - features = resp.data.features || [] - placement = resp.data.placementpolicies || [] - versions = resp.data.versions || [] - storageClass = resp.data.storageclasses || [] - clusterIssuers = resp.data.clusterissuers || [] - nodetopologiesDedicated = resp.data.dedicated || [] - nodetopologiesShared = resp.data.shared || [] - - const response = await axios.get(annotationUrl) - const annotations = response.data?.metadata?.annotations || {} - const uidRange = annotations['openshift.io/sa.scc.uid-range'] - if (uidRange) { - const val = uidRange.split('/')[0] + const isChangeable = isToggleOn('storageClasses') + if (isChangeable && storageClass) { commit('wizard/model$update', { - path: '/spec/openshift/securityContext/runAsUser', - value: val, + path: '/spec/admin/storageClasses/default', + value: storageClass, force: true, }) } - - const gatewayinfosResp = await axios.get(gatewayinfosurl) - hostName = gatewayinfosResp.data?.spec?.hostName - ip = gatewayinfosResp.data?.spec?.ip - } catch (e) { - console.log(e) } - commit('wizard/model$update', { - path: '/spec/deletionPolicy', - value: getDefault({ getValue, model }, 'deletionPolicy'), - force: true, - }) - - if (!getValue(model, `/spec/admin/databases/MongoDB/mode/toggle`)) { - let defMode = getDefault({ getValue, model }, 'databases/MongoDB/mode') || '' - if (defMode === '') { - const arr = getValue(model, '/spec/databases/MongoDB/mode/available') || [] - if (arr.length) defMode = arr[0] - } - commit('wizard/model$update', { - path: '/spec/mode', - value: defMode, - force: true, - }) + function notEqualToDatabaseMode(mode) { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + return modelPathValue && modelPathValue !== mode } - if (!features.includes('tls')) { - commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: false, - force: true, - }) + function showArbiter() { + // watchDependency('model#/spec/arbiter/enabled') + const isArbiterOn = getValue(model, '/spec/arbiter/enabled') || '' + const notStandalone = notEqualToDatabaseMode('Standalone') + return isArbiterOn && notStandalone } - if (!features.includes('binding')) { - commit('wizard/model$update', { - path: '/spec/admin/expose/default', - value: false, - force: true, - }) + + function showRecovery() { + // watchDependency('discriminator#/recovery') + const isRecoveryOn = getValue(discriminator, '/recovery') || '' + return isRecoveryOn } - if (!features.includes('monitoring')) { - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: 'none', - force: true, - }) + + function showHidden() { + // watchDependency('model#/spec/hidden/enabled') + const isHiddenOn = getValue(model, '/spec/hidden/enabled') || '' + const notStandalone = notEqualToDatabaseMode('Standalone') + return isHiddenOn && notStandalone } - if (!features.includes('backup')) { + + function clearArbiterHidden() { commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', + path: `/spec/arbiter/enabled`, value: false, force: true, }) - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: '', - force: true, - }) - } - namespaces = getNamespaces({ axios, storeGet }) - setDiscriminatorValue('/bundleApiLoaded', true) -} - -function fetchNamespaces({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return namespaces -} - -function fetchOptions({ model, getValue, commit }, type) { - let kind = getValue(model, '/metadata/resource/kind') - - let returnArray = [] - if (type === 'clusterTier/placement') { - returnArray = placement - } else if (type === `databases/${kind}/versions`) { - returnArray = versions - } else if (type === 'storageClasses') { - returnArray = storageClass - } else if (type === 'clusterIssuers') { - returnArray = clusterIssuers - } - if (returnArray.length === 1) { - const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: path, - value: returnArray[0], + path: `/spec/hidden/enabled`, + value: false, force: true, }) } - return returnArray -} - -let archiverMap = [] -let archiverCalled = false - -function getAdminOptions({ getValue, model, watchDependency, axios, storeGet, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') - - if (type === 'storageClasses' && !archiverCalled) { - getArchiverName({ axios, storeGet }) + function isConfigDatabaseOn() { + // watchDependency('discriminator#/configDatabase') + return getValue(discriminator, '/configDatabase') } - const options = getValue(model, `/spec/admin/${type}/available`) || [] + function clearConfiguration() { + const configOn = getValue(discriminator, '/configDatabase') - if (options.length === 0) { - return fetchOptions({ model, getValue, commit }, type) - } - if (type.endsWith('/mode')) { - return ( - options?.map((item) => ({ - description: modeDetails[item]?.description || '', - text: modeDetails[item]?.text || '', - value: item, - })) || [] - ) + if (!configOn) { + commit('wizard/model$delete', '/spec/configuration') + } } - return options -} -function showArchiver({ watchDependency, getValue, model, commit }) { - watchDependency('model#/spec/mode') - const dbmode = getValue(model, '/spec/mode') - - if (dbmode === 'Standalone') { - commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, - force: true, - }) + function returnFalse() { return false } - return checkIfFeatureOn({ getValue, model }, 'archiver') -} - -async function getArchiverName({ axios, storeGet }) { - try { - archiverCalled = true - const params = storeGet('/route/params') - const { user, cluster, group, resource } = params - const url = `/clusters/${user}/${cluster}/proxy/storage.k8s.io/v1/storageclasses` - const resp = await axios.get(url) - - resp.data?.items?.forEach((item) => { - const annotations = item.metadata?.annotations - const classname = item.metadata?.name - const annotationKeyToFind = `${resource}.${group}/archiver` - archiverMap.push({ storageClass: classname, annotation: annotations[annotationKeyToFind] }) - return resp.data - }) - } catch (e) { - console.log(e) - } -} - -function onArchiverChange({ model, getValue, commit }) { - const isArchiverOn = getValue(model, '/spec/admin/archiver/enable/default') - const stClass = getValue(model, '/spec/admin/storageClasses/default') - const found = archiverMap.find((item) => item.storageClass === stClass) - - if (isArchiverOn && found?.annotation) - commit('wizard/model$update', { - path: '/spec/archiverName', - value: found.annotation, - force: true, - }) - else - commit('wizard/model$update', { - path: '/spec/archiverName', - value: '', - force: true, - }) -} - -function showArchiverAlert({ watchDependency, model, getValue, commit }) { - watchDependency('model#/spec/admin/storageClasses/default') - const mode = getValue(model, '/spec/mode') - if (mode === 'Standalone') return false + let placement = [] + let versions = [] + let storageClass = [] + let clusterIssuers = [] + let nodetopologiesShared = [] + let nodetopologiesDedicated = [] + let features = [] + let namespaces = [] + let hostName = '' + let ip = '' + async function initBundle() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + let db = getValue(model, '/metadata/resource/kind') + db = db.toLowerCase() + let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` + const gatewayinfosurl = `/clusters/${owner}/${cluster}/proxy/meta.k8s.appscode.com/v1alpha1/gatewayinfos/${namespace}` + const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` + try { + const resp = await axios.get(url) + features = resp.data.features || [] + placement = resp.data.placementpolicies || [] + versions = resp.data.versions || [] + storageClass = resp.data.storageclasses || [] + clusterIssuers = resp.data.clusterissuers || [] + nodetopologiesDedicated = resp.data.dedicated || [] + nodetopologiesShared = resp.data.shared || [] + + const response = await axios.get(annotationUrl) + const annotations = response.data?.metadata?.annotations || {} + const uidRange = annotations['openshift.io/sa.scc.uid-range'] + if (uidRange) { + const val = uidRange.split('/')[0] + commit('wizard/model$update', { + path: '/spec/openshift/securityContext/runAsUser', + value: val, + force: true, + }) + } - const stClass = getValue(model, '/spec/admin/storageClasses/default') - const found = archiverMap.find((item) => item.storageClass === stClass) - const show = !found?.annotation + const gatewayinfosResp = await axios.get(gatewayinfosurl) + hostName = gatewayinfosResp.data?.spec?.hostName + ip = gatewayinfosResp.data?.spec?.ip + } catch (e) { + console.log(e) + } - // toggle archiver to false when storageClass annotation not found - if (show) commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, + path: '/spec/deletionPolicy', + value: getDefault('deletionPolicy'), force: true, }) - else onArchiverChange({ model, getValue, commit }) - return show -} + if (!getValue(model, `/spec/admin/databases/MongoDB/mode/toggle`)) { + let defMode = getDefault('databases/MongoDB/mode') || '' + if (defMode === '') { + const arr = getValue(model, '/spec/databases/MongoDB/mode/available') || [] + if (arr.length) defMode = arr[0] + } + commit('wizard/model$update', { + path: '/spec/mode', + value: defMode, + force: true, + }) + } -async function getRecoveryNames({ getValue, model, watchDependency, storeGet, axios }, type) { - watchDependency(`model#/spec/init/archiver/${type}/namespace`) - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/spec/init/archiver/${type}/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${namespace}/repositories` - if (type === 'encryptionSecret') - url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - const options = [] - if (namespace) { + if (!features.includes('tls')) { + commit('wizard/model$update', { + path: '/spec/admin/tls/default', + value: false, + force: true, + }) + } + if (!features.includes('binding')) { + commit('wizard/model$update', { + path: '/spec/admin/expose/default', + value: false, + force: true, + }) + } + if (!features.includes('monitoring')) { + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: 'none', + force: true, + }) + } + if (!features.includes('backup')) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: '', + force: true, + }) + } + namespaces = getNamespaces() + setDiscriminatorValue('/bundleApiLoaded', true) + } + + function fetchNamespaces() { + // watchDependency('discriminator#/bundleApiLoaded') + return namespaces + } + + function fetchOptions(type) { + let kind = getValue(model, '/metadata/resource/kind') + + let returnArray = [] + if (type === 'clusterTier/placement') { + returnArray = placement + } else if (type === `databases/${kind}/versions`) { + returnArray = versions + } else if (type === 'storageClasses') { + returnArray = storageClass + } else if (type === 'clusterIssuers') { + returnArray = clusterIssuers + } + + if (returnArray.length === 1) { + const path = `/spec/admin/${type}/default` + commit('wizard/model$update', { + path: path, + value: returnArray[0], + force: true, + }) + } + + return returnArray + } + + let archiverMap = [] + let archiverCalled = false + + function getAdminOptions(type) { + // watchDependency('discriminator#/bundleApiLoaded') + + if (type === 'storageClasses' && !archiverCalled) { + getArchiverName() + } + + const options = getValue(model, `/spec/admin/${type}/available`) || [] + + if (options.length === 0) { + return fetchOptions(type) + } + if (type.endsWith('/mode')) { + return ( + options?.map((item) => ({ + description: modeDetails[item]?.description || '', + text: modeDetails[item]?.text || '', + value: item, + })) || [] + ) + } + return options + } + + function showArchiver() { + // watchDependency('model#/spec/mode') + const dbmode = getValue(model, '/spec/mode') + + if (dbmode === 'Standalone') { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + return false + } + return checkIfFeatureOn('archiver') + } + + async function getArchiverName() { try { + archiverCalled = true + const params = storeGet('/route/params') + const { user, cluster, group, resource } = params + const url = `/clusters/${user}/${cluster}/proxy/storage.k8s.io/v1/storageclasses` const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) + + resp.data?.items?.forEach((item) => { + const annotations = item.metadata?.annotations + const classname = item.metadata?.name + const annotationKeyToFind = `${resource}.${group}/archiver` + archiverMap.push({ storageClass: classname, annotation: annotations[annotationKeyToFind] }) + return resp.data }) } catch (e) { console.log(e) } } - return options -} -function checkIfFeatureOn({ getValue, model }, type) { - let val = getValue(model, `/spec/admin/${type}/toggle`) - if (type === 'backup' || type === 'archiver') { - val = getValue(model, `/spec/admin/${type}/enable/toggle`) - } - const backupVal = getValue(model, '/spec/backup/tool') + function onArchiverChange() { + const isArchiverOn = getValue(model, '/spec/admin/archiver/enable/default') + const stClass = getValue(model, '/spec/admin/storageClasses/default') + const found = archiverMap.find((item) => item.storageClass === stClass) - if (type === 'backup') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } else if (type === 'tls') { - return features.includes('tls') && val - } else if (type === 'expose') { - return features.includes('binding') && val - } else if (type === 'monitoring') { - return features.includes('monitoring') && val - } else if (type === 'archiver') { - return features.includes('backup') && val + if (isArchiverOn && found?.annotation) + commit('wizard/model$update', { + path: '/spec/archiverName', + value: found.annotation, + force: true, + }) + else + commit('wizard/model$update', { + path: '/spec/archiverName', + value: '', + force: true, + }) } -} -function isToggleOn({ getValue, model, discriminator, watchDependency, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') - watchDependency('model#/spec/admin/deployment/default') - const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') - let deploymentType = getValue(model, `/spec/admin/deployment/default`) - if (type === 'tls' || type === 'backup' || type === 'expose' || type === 'monitoring') { - return checkIfFeatureOn({ getValue, model }, type) - } else if ( - type === 'clusterTier' || - type === 'clusterTier/placement' || - type === 'clusterTier/nodeTopology' - ) { - if (deploymentType === 'Dedicated' && bundleApiLoaded) return true - else return false - } else if (type === 'deployment') { - const deploymentType = getValue(model, '/spec/admin/deployment/default') - if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + function showArchiverAlert() { + // watchDependency('model#/spec/admin/storageClasses/default') + + const mode = getValue(model, '/spec/mode') + if (mode === 'Standalone') return false + + const stClass = getValue(model, '/spec/admin/storageClasses/default') + const found = archiverMap.find((item) => item.storageClass === stClass) + const show = !found?.annotation + + // toggle archiver to false when storageClass annotation not found + if (show) commit('wizard/model$update', { - path: '/spec/admin/deployment/default', - value: 'Shared', + path: '/spec/admin/archiver/enable/default', + value: false, force: true, }) + else onArchiverChange() + + return show + } + + async function getRecoveryNames(type) { + // watchDependency(`model#/spec/init/archiver/${type}/namespace`) + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/spec/init/archiver/${type}/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${namespace}/repositories` + if (type === 'encryptionSecret') + url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` + const options = [] + if (namespace) { + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } } - return ( - getValue(model, `/spec/admin/${type}/toggle`) && - nodetopologiesDedicated.length && - bundleApiLoaded - ) - } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded -} + return options + } -function showAlerts({ watchDependency, model, getValue, discriminator }) { - watchDependency('discriminator#/monitoring') - const isMonitorEnabled = getValue(discriminator, '/monitoring') - return ( - isMonitorEnabled && isToggleOn({ getValue, model, discriminator, watchDependency }, 'alert') - ) -} + let backupToolInitialValue = '' + function checkIfFeatureOn(type) { + let val = getValue(model, `/spec/admin/${type}/toggle`) + if (type === 'backup' || type === 'archiver') { + val = getValue(model, `/spec/admin/${type}/enable/toggle`) + } + const backupVal = getValue(model, '/spec/backup/tool') + if (type === 'backup') { + if (backupToolInitialValue === '') { + backupToolInitialValue = + features.includes('backup') && backupVal === 'KubeStash' && val ? 'on' : 'off' + return features.includes('backup') && backupVal === 'KubeStash' && val + } else { + if (backupToolInitialValue === 'on') { + return true + } else { + return false + } + } + } else if (type === 'tls') { + return features.includes('tls') && val + } else if (type === 'expose') { + return features.includes('binding') && val + } else if (type === 'monitoring') { + return features.includes('monitoring') && val + } else if (type === 'archiver') { + return features.includes('backup') && val + } + } -function onBackupSwitch({ discriminator, getValue, commit }) { - const isBackupOn = getValue(discriminator, '/backup') - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: isBackupOn ? 'KubeStash' : '', - force: true, - }) -} + function isToggleOn(type) { + // watchDependency('discriminator#/bundleApiLoaded') + // watchDependency('model#/spec/admin/deployment/default') + const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') + let deploymentType = getValue(model, `/spec/admin/deployment/default`) + if (type === 'tls' || type === 'backup' || type === 'expose' || type === 'monitoring') { + return checkIfFeatureOn(type) + } else if ( + type === 'clusterTier' || + type === 'clusterTier/placement' || + type === 'clusterTier/nodeTopology' + ) { + if (deploymentType === 'Dedicated' && bundleApiLoaded) return true + else return false + } else if (type === 'deployment') { + const deploymentType = getValue(model, '/spec/admin/deployment/default') + if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + commit('wizard/model$update', { + path: '/spec/admin/deployment/default', + value: 'Shared', + force: true, + }) + } + return ( + getValue(model, `/spec/admin/${type}/toggle`) && + nodetopologiesDedicated.length && + bundleApiLoaded + ) + } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded + } + + function showAlerts() { + // watchDependency('discriminator#/monitoring') + const isMonitorEnabled = getValue(discriminator, '/monitoring') + return isMonitorEnabled && isToggleOn('alert') + } -async function getNodeTopology({ model, getValue, axios, storeGet, watchDependency }) { - watchDependency('model#/spec/admin/deployment/default') - watchDependency('model#/spec/admin/clusterTier/default') - const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' - const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' - let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + function onBackupSwitch() { + const isBackupOn = getValue(discriminator, '/backup') + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: isBackupOn ? 'KubeStash' : '', + force: true, + }) + } - const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + async function getNodeTopology() { + // watchDependency('model#/spec/admin/deployment/default') + // watchDependency('model#/spec/admin/clusterTier/default') + const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' + const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' + let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] - if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared - else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' - const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) - return filteredList -} + if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared + else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated -function filterNodeTopology(list, tier, provider) { - // first filter the list from value that exists from the filtered list got from API - const filteredlist = list + const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) + return filteredList + } - // filter the list based on clusterTier - if (provider === 'EKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('c') - else if (tier === 'MemoryOptimized') return item.startsWith('r') - else return !item.startsWith('c') && !item.startsWith('r') - }) - } else if (provider === 'AKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - else - return ( - !(item.startsWith('f') || item.startsWith('fx')) && - !( + function filterNodeTopology(list, tier, provider) { + // first filter the list from value that exists from the filtered list got from API + const filteredlist = list + + // filter the list based on clusterTier + if (provider === 'EKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('c') + else if (tier === 'MemoryOptimized') return item.startsWith('r') + else return !item.startsWith('c') && !item.startsWith('r') + }) + } else if (provider === 'AKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('e') || item.startsWith('eb') || item.startsWith('ec') || item.startsWith('m') || item.startsWith('d') ) - ) - }) - } else if (provider === 'GKE') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') - return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - else - return ( - !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && - !( + else + return ( + !(item.startsWith('f') || item.startsWith('fx')) && + !( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + ) + }) + } else if (provider === 'GKE') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') + return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('x4') || item.startsWith('m1') || item.startsWith('m2') || item.startsWith('m3') ) - ) - }) - } else return filteredlist -} + else + return ( + !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && + !( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + ) + }) + } else return filteredlist + } -function showIssuer({ model, getValue, watchDependency, discriminator }) { - watchDependency('model#/spec/admin/tls/default') - const isTlsEnabled = getValue(model, '/spec/admin/tls/default') - const isIssuerToggleEnabled = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'clusterIssuers', - ) - return isTlsEnabled && isIssuerToggleEnabled -} + function showIssuer() { + // watchDependency('model#/spec/admin/tls/default') + const isTlsEnabled = getValue(model, '/spec/admin/tls/default') + const isIssuerToggleEnabled = isToggleOn('clusterIssuers') + return isTlsEnabled && isIssuerToggleEnabled + } -function setMonitoring({ getValue, model }) { - const agent = getValue(model, '/spec/admin/monitoring/agent') || '' - return !!agent -} + function setMonitoring() { + const agent = getValue(model, '/spec/admin/monitoring/agent') || '' + return !!agent + } -function setBackup({ model, getValue }) { - const backup = getValue(model, '/spec/backup/tool') - const val = getValue(model, '/spec/admin/backup/enable/default') - return backup === 'KubeStash' && features.includes('backup') && val -} + function setBackup() { + const backup = getValue(model, '/spec/backup/tool') + const val = getValue(model, '/spec/admin/backup/enable/default') + return backup === 'KubeStash' && features.includes('backup') && val + } -function onAuthChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/authSecret/password', - value: '', - force: true, - }) -} + function onAuthChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/spec/authSecret/password', + value: '', + force: true, + }) + } -function onReferSecretChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) -} + function onReferSecretChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + } -function showAdditionalSettings({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return features.length -} + function showAdditionalSettings() { + // watchDependency('discriminator#/bundleApiLoaded') + return features.length + } -async function checkHostnameOrIP({ commit, model, getValue }) { - const tls = getValue(model, '/spec/admin/tls/default') - const expose = getValue(model, '/spec/admin/expose/default') - if (tls && expose) { - if (hostName) { + function checkHostnameOrIP() { + const tls = getValue(model, '/spec/admin/tls/default') + const expose = getValue(model, '/spec/admin/expose/default') + if (tls && expose) { + if (hostName) { + commit('wizard/model$update', { + path: '/spec/hostName', + value: hostName, + force: true, + }) + } else { + commit('wizard/model$update', { + path: '/spec/ip', + value: ip, + force: true, + }) + } + } else { commit('wizard/model$update', { path: '/spec/hostName', - value: hostName, + value: '', force: true, }) - } else { commit('wizard/model$update', { path: '/spec/ip', - value: ip, + value: '', force: true, }) } - } else { - commit('wizard/model$update', { - path: '/spec/hostName', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/ip', - value: '', - force: true, - }) } -} -function getDefault({ getValue, model }, type) { - const val = getValue(model, `/spec/admin/${type}/default`) || '' - return val -} + function getDefault(type) { + const val = getValue(model, `/spec/admin/${type}/default`) || '' + return val + } -function getDefaultValue({ getValue, model }, path) { - const val = getValue(model, `/${path}`) || '' - return val -} + function getDefaultValue(path) { + const val = getValue(model, `/${path}`) || '' + return val + } -function convertToLocal(input) { - const date = new Date(input) + function convertToLocal(input) { + const date = new Date(input) - if (isNaN(date.getTime())) { - return null + if (isNaN(date.getTime())) { + return null + } + + return date.toString() } - return date.toString() -} + function convertToUTC(localTime) { + const date = new Date(localTime) + if (isNaN(date.getTime())) return -function getComponentLogStats(snapshot) { - if (!snapshot || !snapshot.status || !snapshot.status.components) { - return null + const utcString = date.toISOString() + return utcString } - const components = snapshot.status.components - const appKind = snapshot.spec?.appRef?.kind + function onTimestampChange() { + const localTime = getValue(model, '/spec/init/archiver/recoveryTimestamp') + if (!localTime) return - if (appKind === 'MongoDB') { - for (const [key, value] of Object.entries(components)) { - if (key.endsWith('0') && value.logStats) { - return value.logStats - } + const utcString = convertToUTC(localTime) + + // Only update if the value is valid & not already in UTC format + if (utcString && localTime !== utcString) { + commit('wizard/model$update', { + path: '/spec/init/archiver/recoveryTimestamp', + value: utcString, + force: true, + }) } } - if (components['wal'] && components['wal'].logStats) { - return components['wal'].logStats + function getComponentLogStats(snapshot) { + if (!snapshot || !snapshot.status || !snapshot.status.components) { + return null + } + + const components = snapshot.status.components + const appKind = snapshot.spec?.appRef?.kind + + if (appKind === 'MongoDB') { + for (const [key, value] of Object.entries(components)) { + if (key.endsWith('0') && value.logStats) { + return value.logStats + } + } + } + + if (components['wal'] && components['wal'].logStats) { + return components['wal'].logStats + } + + return null } - return null -} + async function setPointInTimeRecovery() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const refNamespace = getValue(discriminator, '/refNamespace') + const refDBName = getValue(discriminator, '/refDBName') -async function setPointInTimeRecovery({ commit, axios, storeGet, discriminator, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const refNamespace = getValue(discriminator, '/refNamespace') - const refDBName = getValue(discriminator, '/refDBName') + try { + const repositoriesUrl = `clusters/${owner}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${refNamespace}/repositories/${refDBName}-full` + const snapshotsUrl = `clusters/${owner}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${refNamespace}/snapshots/${refDBName}-incremental-snapshot` + const repositoriesResp = await axios.get(repositoriesUrl) + const snapshotsResp = await axios.get(snapshotsUrl) - try { - const repositoriesUrl = `clusters/${owner}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${refNamespace}/repositories/${refDBName}-full` - const snapshotsUrl = `clusters/${owner}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${refNamespace}/snapshots/${refDBName}-incremental-snapshot` - const repositoriesResp = await axios.get(repositoriesUrl) - const snapshotsResp = await axios.get(snapshotsUrl) + commit('wizard/model$update', { + path: `/spec/init/archiver/encryptionSecret/name`, + value: repositoriesResp.data?.spec.encryptionSecret.name, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/encryptionSecret/namespace`, + value: repositoriesResp.data?.spec.encryptionSecret.namespace, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/fullDBRepository/name`, + value: `${refDBName}-full`, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/fullDBRepository/namespace`, + value: `${refNamespace}`, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/manifestRepository/name`, + value: `${refDBName}-manifest`, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/manifestRepository/namespace`, + value: `${refNamespace}`, + force: true, + }) - commit('wizard/model$update', { - path: `/spec/init/archiver/encryptionSecret/name`, - value: repositoriesResp.data?.spec.encryptionSecret.name, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/encryptionSecret/namespace`, - value: repositoriesResp.data?.spec.encryptionSecret.namespace, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/fullDBRepository/name`, - value: `${refDBName}-full`, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/fullDBRepository/namespace`, - value: `${refNamespace}`, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/manifestRepository/name`, - value: `${refDBName}-manifest`, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/manifestRepository/namespace`, - value: `${refNamespace}`, - force: true, - }) + const resp = getComponentLogStats(snapshotsResp.data) - const resp = getComponentLogStats(snapshotsResp.data) + commit('wizard/model$update', { + path: `/spec/init/archiver/recoveryTimestamp`, + value: convertToUTC(resp?.end), + force: true, + }) + commit('wizard/model$update', { + path: `/minDate`, + value: convertToUTC(resp?.start), + force: true, + }) + commit('wizard/model$update', { + path: `/maxDate`, + value: convertToUTC(resp?.end), + force: true, + }) + } catch (e) { + pointIntimeError = + e.response?.data?.message || 'Invalid name / namespace for recovery timestamp' + commit('wizard/model$update', { + path: `/spec/init/archiver/recoveryTimestamp`, + value: '', + force: true, + }) + commit('wizard/model$update', { + path: `/minDate`, + value: '', + force: true, + }) + commit('wizard/model$update', { + path: `/maxDate`, + value: '', + force: true, + }) + commit('wizard/model$delete', '/spec/init/archiver/encryptionSecret') + commit('wizard/model$delete', '/spec/init/archiver/fullDBRepository') + commit('wizard/model$delete', '/spec/init/archiver/manifestRepository') + console.log(e) + } + } - commit('wizard/model$update', { - path: `/spec/init/archiver/recoveryTimestamp`, - value: convertToLocal(resp?.end), - force: true, - }) - commit('wizard/model$update', { - path: `/minDate`, - value: convertToLocal(resp?.start), - force: true, - }) - commit('wizard/model$update', { - path: `/maxDate`, - value: convertToLocal(resp?.end), - force: true, - }) - } catch (e) { - commit('wizard/model$update', { - path: `/spec/init/archiver/recoveryTimestamp`, - value: '', - force: true, - }) - commit('wizard/model$update', { - path: `/minDate`, - value: '', - force: true, - }) - commit('wizard/model$update', { - path: `/maxDate`, - value: '', - force: true, - }) - console.log(e) + let pointIntimeError = '' + function pointInTimeErrorCheck() { + if (pointIntimeError.length) return pointIntimeError + return } -} -// horizon stuffs -function isTlsOn({ getValue, model, watchDependency }) { - watchDependency('model#/spec/admin/tls/default') - watchDependency('model#/spec/admin/expose/default') + // horizon stuffs + function isTlsOn() { + // watchDependency('model#/spec/admin/tls/default') + // watchDependency('model#/spec/admin/expose/default') - const tls = getValue(model, '/spec/admin/tls/default') - const expose = getValue(model, '/spec/admin/expose/default') - return tls && expose -} + const tls = getValue(model, '/spec/admin/tls/default') + const expose = getValue(model, '/spec/admin/expose/default') + return tls && expose + } -function isHorizonsOn({ getValue, discriminator, watchDependency }) { - watchDependency('discriminator#/enableHorizons') - const horizon = getValue(discriminator, '/enableHorizons') - return horizon -} + function isHorizonsOn() { + // watchDependency('discriminator#/enableHorizons') + const horizon = getValue(discriminator, '/enableHorizons') + return horizon + } -function onHorizonsChange({ getValue, commit, discriminator }) { - const val = getValue(discriminator, '/enableHorizons') - if (!val) { - commit({ - path: '/spec/replicaSet/horizons', - value: [], - force: true, - }) + function onHorizonsChange() { + const val = getValue(discriminator, '/enableHorizons') + if (!val) { + commit({ + path: '/spec/replicaSet/horizons', + value: [], + force: true, + }) + } } -} -function updateSuffix({ getValue, model, commit, watchDependency, discriminator }) { - const horizons = getValue(model, '/spec/replicaSet/horizons') || [] - const length = horizons?.length || 0 + function updateSuffix() { + const horizons = getValue(model, '/spec/replicaSet/horizons') || [] + const length = horizons?.length || 0 - const replicas = getValue(model, '/spec/replicaSet/replicas') || 0 + const replicas = getValue(model, '/spec/replicaSet/replicas') || 0 - if (replicas !== length && isHorizonsOn({ getValue, discriminator, watchDependency })) - commit('wizard/model$update', { - path: '/spec/hostName', - value: '', - force: true, - }) - else { - const common = getCommonPostfix(horizons) - if (common) + if (replicas !== length && isHorizonsOn()) commit('wizard/model$update', { path: '/spec/hostName', - value: common, + value: '', force: true, }) + else { + const common = getCommonPostfix(horizons) + if (common) + commit('wizard/model$update', { + path: '/spec/hostName', + value: common, + force: true, + }) + } } -} -function getCommonPostfix(strings) { - if (strings.length === 0) return '' + function getCommonPostfix(strings) { + if (strings.length === 0) return '' - const reversedParts = strings.map((str) => str.split('.').reverse()) - const first = reversedParts[0] + const reversedParts = strings.map((str) => str.split('.').reverse()) + const first = reversedParts[0] - const commonParts = [] + const commonParts = [] - for (let i = 0; i < first.length; i++) { - const part = first[i] - if (reversedParts.every((parts) => parts[i] === part)) { - commonParts.push(part) - } else { - break + for (let i = 0; i < first.length; i++) { + const part = first[i] + if (reversedParts.every((parts) => parts[i] === part)) { + commonParts.push(part) + } else { + break + } } - } - return commonParts.length ? commonParts.reverse().join('.') : '' -} + return commonParts.length ? commonParts.reverse().join('.') : '' + } -function isHorizonsValid({ getValue, model, watchDependency }) { - watchDependency('model#/spec/replicaSet/replicas') - const horizons = getValue(model, '/spec/replicaSet/horizons') || [] - const length = horizons?.length || 0 - const replicas = getValue(model, '/spec/replicaSet/replicas') || 0 + function isHorizonsValid() { + // watchDependency('model#/spec/replicaSet/replicas') + const horizons = getValue(model, '/spec/replicaSet/horizons') || [] + const length = horizons?.length || 0 + const replicas = getValue(model, '/spec/replicaSet/replicas') || 0 - if (length !== replicas) return `Horizons count need to be equal to ${replicas}` + if (length !== replicas) return `Horizons count need to be equal to ${replicas}` - const common = getCommonPostfix(horizons) - if (!common) return 'Horizons must have a common dot (.) seperated suffix' - return true -} + const common = getCommonPostfix(horizons) + if (!common) return 'Horizons must have a common dot (.) seperated suffix' + return true + } -return { - onReferSecretChange, - showReferSecretSwitch, - getDefaultValue, - showSecretDropdown, - showReferSecret, - getReferSecrets, - isConfigAvailable, - setPointInTimeRecovery, - checkHostnameOrIP, - isRancherManaged, - getRecoveryNames, - fetchNamespaces, - showRecovery, - showAdditionalSettings, - returnFalse, - initBundle, - isVariantAvailable, - fetchJsons, - showAuthPasswordField, - isEqualToModelPathValue, - showStorageSizeField, - getNamespaces, - onCreateAuthSecretChange, - isMachineNotCustom, - isMachineCustom, - getMachineListForOptions, - setLimits, - setRequests, - setMachineToCustom, - updateAlertValue, - getCreateNameSpaceUrl, - ifCapiProviderIsNotEmpty, - ifDedicated, - dedicatedOnChange, - ifZones, - zonesOnChange, - getZones, - getSKU, - showMultiselectZone, - showSelectZone, - setStorageClass, - showArbiter, - showHidden, - notEqualToDatabaseMode, - clearArbiterHidden, - isConfigDatabaseOn, - clearConfiguration, - isToggleOn, - getAdminOptions, - onBackupSwitch, - showAlerts, - showIssuer, - setMonitoring, - getNodeTopology, - filterNodeTopology, - onAuthChange, - setBackup, - getDefault, - onArchiverChange, - showArchiverAlert, - showArchiver, - isTlsOn, - isHorizonsOn, - updateSuffix, - onHorizonsChange, - isHorizonsValid, + return { + onReferSecretChange, + showReferSecretSwitch, + getDefaultValue, + showSecretDropdown, + showReferSecret, + getReferSecrets, + setPointInTimeRecovery, + pointInTimeErrorCheck, + checkHostnameOrIP, + isRancherManaged, + getRecoveryNames, + fetchNamespaces, + showRecovery, + showAdditionalSettings, + returnFalse, + initBundle, + isVariantAvailable, + fetchJsons, + showAuthPasswordField, + isEqualToModelPathValue, + showStorageSizeField, + getNamespaces, + onCreateAuthSecretChange, + isMachineNotCustom, + isMachineCustom, + getMachineListForOptions, + setLimits, + setRequests, + setMachineToCustom, + updateAlertValue, + getCreateNameSpaceUrl, + ifCapiProviderIsNotEmpty, + ifDedicated, + dedicatedOnChange, + ifZones, + zonesOnChange, + getZones, + getSKU, + showMultiselectZone, + showSelectZone, + setStorageClass, + showArbiter, + showHidden, + notEqualToDatabaseMode, + clearArbiterHidden, + isConfigDatabaseOn, + clearConfiguration, + isToggleOn, + getAdminOptions, + onBackupSwitch, + showAlerts, + showIssuer, + setMonitoring, + getNodeTopology, + filterNodeTopology, + onAuthChange, + setBackup, + getDefault, + onArchiverChange, + showArchiverAlert, + showArchiver, + isTlsOn, + isHorizonsOn, + updateSuffix, + onHorizonsChange, + isHorizonsValid, + onTimestampChange, + } } diff --git a/charts/kubedbcom-mongodb-editor/ui/edit-ui.yaml b/charts/kubedbcom-mongodb-editor/ui/edit-ui.yaml index 3327334828..ca0aaac393 100644 --- a/charts/kubedbcom-mongodb-editor/ui/edit-ui.yaml +++ b/charts/kubedbcom-mongodb-editor/ui/edit-ui.yaml @@ -1,2519 +1,1725 @@ -steps: -- form: - elements: - - disabled: true - label: - text: labels.database.name - onChange: onNameChange - schema: - $ref: schema#/properties/metadata/properties/release/properties/name - type: input - - disabled: true - fetch: getResources|core|v1|namespaces - label: - text: labels.namespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/metadata/properties/release/properties/namespace - type: select - - disableUnselect: true - disabled: true - fetch: getMongoDbVersions|catalog.kubedb.com|v1alpha1|mongodbversions - label: - text: labels.database.version - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/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/kubedbComMongoDB/properties/metadata/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/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/kubedbComMongoDB/properties/metadata/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/metadata/properties/annotations/additionalProperties - type: input - - hasDescription: true - label: - text: labels.deletionPolicy - 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/kubedbComMongoDB/properties/spec/properties/deletionPolicy - type: radio - - disabled: true - label: - text: labels.secret - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/authSecret/properties/name - type: input - type: single-step-form - id: basic - title: steps.0.label -- form: - elements: - - alias: reusable_alert - chart: - name: uibytebuildersdev-component-alert - version: v0.29.0 - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/form/properties/alert - type: reusable-element - type: single-step-form - id: alert - title: labels.alert -- form: +type: multi-step-form +step: + - type: single-step-form + id: backupconfiguration + # label: Backup + schema: schema/ elements: - - discriminator: - activeDatabaseMode: - default: Standalone - type: string - elements: - - if: isNotStandaloneMode - label: - text: labels.to_update_replicas - type: label-element - - customClass: mb-20 - if: isNotStandaloneMode - label: - text: labels.create_opsrequest - type: anchor - url: - params: - cluster: - $ref: store#/route/params/cluster - dbname: - $ref: model#/metadata/release/name - domain: - $ref: store#/domain - group: - $ref: model#/metadata/resource/group - kind: - $ref: model#/metadata/resource/kind - namespace: - $ref: model#/metadata/release/namespace - owner: - $ref: store#/route/params/user - resource: - $ref: model#/metadata/resource/name - version: - $ref: model#/metadata/resource/version - path: ${domain}/console/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/mongodbopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=HorizontalScaling - - computed: setDatabaseMode - disabled: true - hasDescription: true - label: - text: labels.database.mode - onChange: deleteDatabaseModePath + - type: radio + label: Schedule a Backup? + schema: temp/properties/scheduleBackup + isHorizontal: true options: - - description: options.database.mode.Standalone.description - text: options.database.mode.Standalone.label - value: Standalone - - description: options.database.mode.Replicaset.description - text: options.database.mode.Replicaset.label - value: Replicaset - - description: options.database.mode.Sharded.description - text: options.database.mode.Sharded.label - value: Sharded - schema: - $ref: discriminator#/activeDatabaseMode - type: radio - - disabled: true + - text: 'Yes' + value: 'yes' + - text: 'No' + value: 'no' + if: + type: function + name: showScheduleBackup + init: + type: func + value: initScheduleBackupForEdit + watcher: + func: onScheduleBackupChange + paths: + - temp/properties/scheduleBackup + - type: block-layout + label: Backup Form + showLabels: false + loader: initBackupData + if: + type: function + name: showBackupForm elements: - - label: - text: labels.replicaset.name - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/replicaSet/properties/name - type: input - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/replicas - type: input - if: isEqualToDatabaseMode|Replicaset - type: single-step-form - - disabled: true - elements: - - fetch: getStorageClassNames|common - label: - text: labels.storage.class - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/storage/properties/storageClassName - type: select - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/storage/properties/resources/properties/requests/properties/storage - type: input - if: showCommonStorageClassAndSizeField - type: single-step-form - - disabled: true - elements: - - elements: - - fetch: getStorageClassNames|shard - label: - text: labels.storage.class - onChange: setStorageClass - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/shardTopology/properties/shard/properties/storage/properties/storageClassName - type: select - - label: - text: labels.shardNodes - type: label-element - - elements: - - elements: - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/shardTopology/properties/shard/properties/storage/properties/resources/properties/requests/properties/storage - type: input - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/shardTopology/properties/shard/properties/storage/properties/resources/properties/requests - type: single-step-form - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/shardTopology/properties/shard/properties/storage/properties/resources - type: single-step-form - type: single-step-form - - label: - text: labels.shards - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/shardTopology/properties/shard/properties/shards - type: input - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/shardTopology/properties/shard/properties/replicas - type: input - - label: - text: labels.configServer - type: label-element - - elements: - - elements: - - elements: - - elements: - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/shardTopology/properties/configServer/properties/storage/properties/resources/properties/requests/properties/storage - type: input - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/shardTopology/properties/configServer/properties/storage/properties/resources/properties/requests - type: single-step-form - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/shardTopology/properties/configServer/properties/storage/properties/resources - type: single-step-form - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/shardTopology/properties/configServer/properties/storage - type: single-step-form - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/shardTopology/properties/configServer/properties/replicas - type: input - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/shardTopology/properties/configServer - type: single-step-form - - label: - text: labels.mongos - type: label-element - - elements: - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/shardTopology/properties/mongos/properties/replicas - type: input - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/shardTopology/properties/mongos - type: single-step-form - if: isEqualToDatabaseMode|Sharded - type: single-step-form - type: single-step-form - type: single-step-form - id: topology - title: steps.1.label -- form: - discriminator: - configureTLS: - default: true - type: boolean - elements: - - label: - text: labels.to_update_tls - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - params: - cluster: - $ref: store#/route/params/cluster - dbname: - $ref: model#/metadata/release/name - domain: - $ref: store#/domain - group: - $ref: model#/metadata/resource/group - kind: - $ref: model#/metadata/resource/kind - namespace: - $ref: model#/metadata/release/namespace - owner: - $ref: store#/route/params/user - resource: - $ref: model#/metadata/resource/name - version: - $ref: model#/metadata/resource/version - path: ${domain}/console/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/mongodbopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=ReconfigureTLS - - computed: isValueExistInModel|/resources/kubedbComMongoDB/spec/tls - disabled: true - label: - text: labels.enable_tls - onChange: onTlsConfigureChange - schema: - $ref: discriminator#/configureTLS - type: switch - - disabled: true - elements: - - computed: setClusterAuthMode - label: - text: labels.cluster_auth_mode - options: - - text: x509 - value: x509 - - text: sendX509 - value: sendX509 - - text: keyFile - value: keyFile - - text: sendKeyFile - value: sendKeyFile - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/clusterAuthMode - type: radio - - computed: setSSLMode - label: - text: labels.ssl_mode - options: - - text: requireSSL - value: requireSSL - - text: preferSSL - value: preferSSL - - text: allowSSL - value: allowSSL - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/sslMode - type: radio - - elements: - - computed: setApiGroup - disabled: true - label: - text: labels.api_group - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/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/kubedbComMongoDB/properties/spec/properties/tls/properties/issuerRef/properties/kind - type: select - - allowUserDefinedOption: true - fetch: getIssuerRefsName - label: - text: labels.name - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/tls/properties/issuerRef/properties/name - type: select - label: - text: labels.issuer_ref - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/tls/properties/issuerRef - type: single-step-form - - alias: reusable_certificates - chart: - name: uibytebuildersdev-component-certificates - version: v0.29.0 - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/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: + - type: radio + label: Select Backup Type + schema: temp/properties/backupType + isHorizontal: true + options: + - text: BackupConfig + value: BackupConfig + description: 'Create, Delete or Modify BackupConfig' + - text: BackupBlueprint + value: BackupBlueprint + description: Enable/Disable BackupBlueprint + if: + type: function + name: isBackupDataLoadedTrue + init: + type: func + value: setBackupType + loader: getTypes + watcher: + func: onBackupTypeChange + paths: + - temp/properties/backupType + - type: block-layout + label: Config + if: + type: function + name: isBackupType|BackupConfig + elements: + - type: select + label: Select Context + schema: temp/properties/backupConfigContext + validation: + type: required + loader: getContext + watcher: + func: onContextChange + paths: + - temp/properties/backupConfigContext + - type: select + label: Select BackupConfig + schema: temp/properties/config + validation: + type: required + if: + type: function + name: showConfigList + loader: getConfigList + watcher: + func: onConfigChange + paths: + - temp/properties/config + - type: input + label: Schedule + schema: temp/properties/schedule + validation: + type: required + if: + type: function + name: showSchedule + loader: + name: getDefaultSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions + watchPaths: + - temp/properties/config + watcher: + func: onInputChangeSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions|schedule + paths: + - temp/properties/schedule + - type: switch + label: Paused + fullwidth: true + schema: schema/properties/resources/properties/coreKubestashComBackupConfiguration/properties/spec/properties/paused + if: + type: function + name: showPause + watcher: + func: setPausedValue + paths: + - temp/properties/config + init: + type: func + value: setPausedValue + - type: block-layout + label: Blueprint + if: + type: function + name: isBackupType|BackupBlueprint + elements: + - type: switch + label: Enable Backup Blueprint + fullwidth: true + subtitle: Use a backup blueprint template to automatically configure backups for similar databases + schema: temp/properties/blueprintEnabled + init: + type: func + value: setBlueprintSwitch + watcher: + func: onBlueprintChange + paths: + - temp/properties/blueprintEnabled + - type: block-layout + label: Archiver + if: + type: function + name: isBackupType|Archiver + elements: + - type: switch + label: Enable Archiver + fullwidth: true + schema: temp/properties/archiverEnabled + init: + type: func + value: setArchiverSwitch + watcher: + func: onArchiverChange + paths: + - temp/properties/archiverEnabled + + - type: single-step-form + id: monitoring + loader: initMonitoring elements: - - disabled: disableInitializationSection - discriminator: - prePopulateDatabase: - type: string + - type: label-element + label: To update Exporter Resource section click on Create OpsRequest + - type: anchor + label: Create OpsRequest + schema: temp/properties/opsRequestUrl + init: + type: func + value: getOpsRequestUrl|scale-vertically + - type: switch + label: Enable Monitoring + fullwidth: true + schema: temp/properties/enableMonitoring + init: + type: func + value: isValueExistInModel|/resources/kubedbComMongoDB/spec/monitor + watcher: + func: onEnableMonitoringChange + paths: + - temp/properties/enableMonitoring + - type: block-layout + if: + type: function + name: showMonitoringSection elements: - - computed: initPrePopulateDatabase - 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 + - type: radio + label: Select a Monitoring Method + schema: schema/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/monitor/properties/agent + isHorizontal: true 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 + - text: Prometheus Operator + value: prometheus.io/operator + description: Inject metric exporter sidecar and creates a ServiceMonitor + - text: Custom ServiceMonitor + value: prometheus.io + description: Injects the metric exporter sidecar and let you customize ServiceMonitor + - text: Custom Scrapper + value: prometheus.io/builtin + description: Inject metric exporter sidecar and add Prometheus annotations to the stats Service + init: + type: static + value: prometheus.io/operator + watcher: + func: onAgentChange + paths: + - schema/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/monitor/properties/agent + - type: block-layout + label: ServiceMonitor Configuration + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComMongoDB/spec/monitor/agent elements: - - label: - text: labels.script.path - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/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/kubedbComMongoDB/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/kubedbComMongoDB/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 + - label: Scrapping Interval + schema: schema/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval + type: input + - type: block-layout + label: Service Monitor + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComMongoDB/spec/monitor/agent + elements: + - type: array-object-form + label: Endpoints + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/endpoints 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.29.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 + - type: switch + label: Honor labels + fullwidth: true + schema: honorLabels + - type: input + label: Interval + schema: interval + validation: + type: required + - type: input + label: Path + schema: path + validation: + type: required + - type: input + label: Port + schema: port + validation: + type: required + - type: select + multiple: true + label: Match Namespaces + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/namespaceSelector/properties/matchNames + loader: getResources|core|v1|namespaces + if: + type: function + name: returnFalse + - type: block-layout + showLabels: false + # schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector + if: + type: function + name: returnFalse 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.29.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/kubedbComMongoDB/properties/spec/properties/init/properties/waitForInitialRestore - type: switch - if: showInitializationForm - type: single-step-form - type: single-step-form - type: single-step-form - id: initialization - title: steps.3.label -- form: - discriminator: - repoInitialSelectionStatus: - type: string - scheduleBackup: - default: "yes" - type: string - elements: - - computed: initScheduleBackupForEdit - if: showScheduleBackup - 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: - backupType: - type: string - isBackupDataLoaded: - default: false - type: boolean - elements: - - computed: initBackupData - if: returnFalse - type: input - - computed: setBackupType - fetch: getTypes - hasDescription: true - if: isBackupDataLoadedTrue - label: - text: Select Backup Type - onChange: onBackupTypeChange - schema: - $ref: discriminator#/backupType - type: radio - - discriminator: - backupConfigContext: - type: string - config: - type: string - paused: - default: false - type: boolean - schedule: - type: string - elements: - - fetch: getContext - label: - text: Select Context - onChange: onContextChange - required: true - schema: - $ref: discriminator#/backupConfigContext - type: select - - fetch: getConfigList - if: showConfigList - label: - text: Select BackupConfig - onChange: onConfigChange - required: true - schema: - $ref: discriminator#/config - type: select - - computed: getDefaultSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions - if: showSchedule - label: - text: Schedule - onChange: onInputChangeSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions|schedule - required: true - schema: - $ref: discriminator#/schedule - type: input - - if: showPause - label: - text: Paused - schema: - $ref: schema#/properties/resources/properties/coreKubestashComBackupConfiguration/properties/spec/properties/paused - type: switch - if: isBackupType|BackupConfig - type: single-step-form - - discriminator: - blueprintEnabled: - default: false - type: boolean - elements: - - computed: setBlueprintSwitch - label: - text: Enable Backup Blueprint - onChange: onBlueprintChange - schema: - $ref: discriminator#/blueprintEnabled - type: switch - if: isBackupType|BackupBlueprint - type: single-step-form - - discriminator: - archiverEnabled: - default: false - type: boolean - elements: - - computed: setArchiverSwitch - label: - text: Enable Archiver - onChange: onArchiverChange - schema: - $ref: discriminator#/archiverEnabled - type: switch - if: isBackupType|Archiver - 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: - - label: - text: labels.to_update_exporter_resources - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - function: getOpsRequestUrl|VerticalScaling - - computed: isValueExistInModel|/resources/kubedbComMongoDB/spec/monitor - 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/kubedbComMongoDB/properties/spec/properties/monitor/properties/agent - type: radio - - elements: - - label: - text: labels.scrapping_interval - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval - type: input - if: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComMongoDB/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: object-item + label: Labels + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector/properties/matchLabels + - type: object-item + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/metadata/properties/labels + label : Labels + buttonClass: is-light is-outlined + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComMongoDB/spec/monitor/agent + # individualItemDisabilityCheck: disableLableChecker + - type: label-element + label: Exporter Configuration + schema: '' + - type: switch + label: Customize Exporter Sidecar + fullwidth: true + schema: temp/properties/customizeExporter + init: + type: static + value: true + watcher: + func: onCustomizeExporterChange + paths: + - temp/properties/customizeExporter + - type: block-layout + label: Customer Exporter Section + showLabels: false + loader: setMetadata + if: + type: function + name: showCustomizeExporterSection + elements: + - type: machine-compare + label: Resources + schema: schema/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/resources + if: + type: function + name: returnFalse + - type: label-element + label: Security Context + schema: '' + - type: input + schema: schema/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsUser + label: Run as User + - type: input + schema: schema/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup + label: Run as Group + - type: input + schema: schema/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/port + label: Port + - type: array-item-form + label: Args + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args + init: + type: static + value: ['--compatible-mode'] + element: 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/kubedbComMongoDB/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/kubedbComMongoDB/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: - - if: returnFalse - label: - text: labels.resources - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/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/kubedbComMongoDB/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/kubedbComMongoDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup - type: input - - label: - text: labels.port - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/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/kubedbComMongoDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args/items - type: input - label: - text: labels.args - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args - type: list-input-form - - alias: reusable_env - chart: - name: uibytebuildersdev-component-env - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/env - type: reusable-element - if: showCustomizeExporterSection - type: single-step-form - - computed: setMetadata - if: returnFalse - schema: - $ref: schema#/properties/metadata/properties/release/properties/name - type: input - if: showMonitoringSection - type: single-step-form - type: single-step-form - id: monitoring - title: steps.5.label -- form: + label: Args + # isSubsection: true + - type: block-layout + label: Metadata + showLabels: false + elements: + - type: array-object-form + init: + type: func + value: initEnvArray + label: Environment Variables + buttonClass: is-light is-outlined + watcher: + func: onEnvArrayChange + paths: + - temp/properties/env + schema: temp/properties/env + elements: + - type: input + label: Name + schema: name + validation: + type: required + - type: radio + label: Value From + schema: temp/properties/valueFromType + validation: + type: required + init: + type: func + value: setValueFrom + options: + - text: Input + value: input + - text: Secret + value: secret + - text: ConfigMap + value: configMap + watcher: + func: onValueFromChange + paths: + - temp/properties/valueFromType + - type: input + label: Value + schema: value + validation: + type: required + if: + name: isEqualToTemp|input + type: function + - type: select + if: + type: function + name: isEqualToTemp|configMap + label: ConfigMap Name + schema: valueFrom/properties/configMapKeyRef/properties/name + loader: + name: resourceNames|core|v1|configmaps + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: ConfigMap Key + schema: valueFrom/properties/configMapKeyRef/properties/key + if: + type: function + name: isEqualToTemp|configMap + loader: + name: getConfigMapKeys + watchPaths: + - schema/resources/kubedbComMongoDB/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/configMapKeyRef/name + - schema/metadata/release/namespace + - type: select + label: Secret Name + schema: valueFrom/properties/secretKeyRef/properties/name + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecrets + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: Secret Key + schema: valueFrom/properties/secretKeyRef/properties/key + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecretKeys + watchPaths: + - schema/resources/kubedbComMongoDB/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/secretKeyRef/name + - schema/metadata/release/namespace + + - type: single-step-form + id: compute-autoscaler + loader: getDbDetails elements: - - elements: - - alias: pod_template_standalone - chart: - name: uibytebuildersdev-component-pod-template - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - functionCallbacks: - isEditWizard: - $ref: functions#/returnTrue - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/podTemplate - type: reusable-element - type: single-step-form - type: single-step-form - id: pod-template - if: isNotShardModeSelected - title: steps.6.label -- form: - steps: - - form: - elements: - - elements: - - alias: pod_template_shard - chart: - name: uibytebuildersdev-component-pod-template - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - functionCallbacks: - isEditWizard: - $ref: functions#/returnTrue - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/shardTopology/properties/shard/properties/podTemplate - type: reusable-element - type: single-step-form - type: single-step-form - id: pod-template-shard - title: labels.shard - - form: - elements: - - elements: - - alias: pod_template_configserver - chart: - name: uibytebuildersdev-component-pod-template - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - functionCallbacks: - isEditWizard: - $ref: functions#/returnTrue - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/shardTopology/properties/configServer/properties/podTemplate - type: reusable-element - type: single-step-form - type: single-step-form - id: pod-template-config-server - title: labels.configServer - - form: - elements: - - elements: - - alias: pod_template_mongos - chart: - name: uibytebuildersdev-component-pod-template - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - functionCallbacks: - isEditWizard: - $ref: functions#/returnTrue - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/shardTopology/properties/mongos/properties/podTemplate - type: reusable-element - type: single-step-form - type: single-step-form - id: pod-template-mongos - title: labels.mongos - type: multi-step-form - id: pod-template-sharded-topology - if: isShardModeSelected - title: steps.7.label -- form: - elements: - - alias: reusable_service_templates - chart: - name: uibytebuildersdev-component-service-templates - version: v0.29.0 - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/serviceTemplates - type: reusable-element - type: single-step-form - id: networking - title: steps.8.label -- form: - elements: - - label: - text: labels.to_update_config - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - params: - cluster: - $ref: store#/route/params/cluster - dbname: - $ref: model#/metadata/release/name - domain: - $ref: store#/domain - group: - $ref: model#/metadata/resource/group - kind: - $ref: model#/metadata/resource/kind - namespace: - $ref: model#/metadata/release/namespace - owner: - $ref: store#/route/params/user - resource: - $ref: model#/metadata/resource/name - version: - $ref: model#/metadata/resource/version - path: ${domain}/console/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/mongodbopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=Reconfigure - - disabled: true + - type: block-layout + showLabels: false + loader: fetchTopologyMachines elements: - - discriminator: - configurationSource: - default: use-existing-config - type: string - elements: - - 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 - label: - text: labels.name - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/configSecret/properties/name - type: select - if: isNotShardModeSelected - type: single-step-form - - discriminator: - configurationSourceConfigServer: - default: use-existing-config - type: string - configurationSourceMongos: - default: use-existing-config - type: string - configurationSourceShard: - default: use-existing-config - type: string - elements: - - customClass: mb-10 - label: - text: labels.shardNodes - type: label-element - - computed: setConfigurationSourceShard - label: - text: labels.custom_config - onChange: onConfigurationSourceShardChange - 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 - - text: options.configuration_source.same_as_config_server.label - value: same-as-configserver-config-secret - - text: options.configuration_source.same_as_mongos.label - value: same-as-mongos-config-secret - schema: - $ref: discriminator#/configurationSourceShard - type: select - - allowUserDefinedOption: true - fetch: getSecrets - if: isEqualToDiscriminatorPath|use-existing-config|/configurationSourceShard - label: - text: labels.config_secret - onChange: onConfigSecretModelChange|shard|use-existing-config - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/shardTopology/properties/shard/properties/configSecret/properties/name - type: select - - customClass: mb-10 - label: - text: labels.configServerNodes - type: label-element - - computed: setConfigurationSourceConfigServer - label: - text: labels.custom_config - onChange: onConfigurationSourceConfigServerChange - 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 - - text: options.configuration_source.same_as_shard.label - value: same-as-shard-config-secret - - text: options.configuration_source.same_as_mongos.label - value: same-as-mongos-config-secret - schema: - $ref: discriminator#/configurationSourceConfigServer - type: select - - allowUserDefinedOption: true - fetch: getSecrets - if: isEqualToDiscriminatorPath|use-existing-config|/configurationSourceConfigServer - label: - text: labels.config_secret - onChange: onConfigSecretModelChange|configserver|use-existing-config - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/shardTopology/properties/configServer/properties/configSecret/properties/name - type: select - - customClass: mb-10 - label: - text: labels.mongosNodes - type: label-element - - computed: setConfigurationSourceMongos - label: - text: labels.custom_config - onChange: onConfigurationSourceMongosChange - 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 - - text: options.configuration_source.same_as_shard.label - value: same-as-shard-config-secret - - text: options.configuration_source.same_as_config_server.label - value: same-as-configserver-config-secret - schema: - $ref: discriminator#/configurationSourceMongos - type: select - - allowUserDefinedOption: true - fetch: getSecrets - if: isEqualToDiscriminatorPath|use-existing-config|/configurationSourceMongos - label: - text: labels.config_secret - onChange: onConfigSecretModelChange|mongos|use-existing-config - schema: - $ref: schema#/properties/resources/properties/kubedbComMongoDB/properties/spec/properties/shardTopology/properties/mongos/properties/configSecret/properties/name - type: select - if: isShardModeSelected - type: single-step-form - type: single-step-form - type: single-step-form - id: custom-config - title: steps.9.label -- form: - discriminator: - dbDetails: - default: false - type: boolean + # standalone mode + - type: switch + label: Trigger + fullwidth: true + if: + type: function + name: mongoTypeEqualsTo|standalone|compute + init: + type: func + value: setTrigger|autoscalingKubedbComMongoDBAutoscaler/spec/compute/standalone/trigger + schema: temp/properties/compute/properties/standalone/properties/trigger + watcher: + func: onTriggerChange|compute/standalone + paths: + - temp/properties/compute/properties/standalone/properties/trigger + - type: label-element + label: Pod lifetime threshold + subtitle: Specifies the duration a pod can exist before using considered for scaling decisions, ensuring resource optimization and workload stability + if: + type: function + name: mongoTypeEqualsTo|standalone|compute + - type: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone/properties/podLifeTimeThreshold + customClass: width-300 + if: + type: function + name: mongoTypeEqualsTo|standalone|compute + - type: block-layout + label: Standalone + if: + type: function + name: mongoTypeEqualsTo|standalone|compute + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-standalone-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|standalone|min + loader: + name: getMachines|standalone|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-standalone-max + watcher: + func: onMachineChange|standalone + paths: + - temp/properties/allowedMachine-standalone-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-standalone-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|standalone|max + loader: + name: getMachines|standalone|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-standalone-min + watcher: + func: onMachineChange|standalone + paths: + - temp/properties/allowedMachine-standalone-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|compute/standalone + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone/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/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone/properties/containerControlledValues + - type: block-layout + label: In Memory Storage + showLabels: true + if: + type: function + name: showStorageMemoryOption + # schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone/properties/inMemoryStorage + elements: + - type: threshold-input + label: Scaling Factor Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone/properties/inMemoryStorage/properties/scalingFactorPercentage + - type: threshold-input + label: Usage Threshold Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone/properties/inMemoryStorage/properties/usageThresholdPercentage + # replicaset mode + - type: switch + label: Trigger + fullwidth: true + if: + type: function + name: mongoTypeEqualsTo|replicaSet|compute + init: + type: func + value: setTrigger|autoscalingKubedbComMongoDBAutoscaler/spec/compute/replicaSet/trigger + schema: temp/properties/compute/properties/replicaSet/properties/trigger + watcher: + func: onTriggerChange|compute/replicaSet + paths: + - temp/properties/compute/properties/replicaSet/properties/trigger + - type: label-element + label: Pod lifetime threshold + subtitle: Specifies the duration a pod can exist before using considered for scaling decisions, ensuring resource optimization and workload stability + if: + type: function + name: mongoTypeEqualsTo|replicaSet|compute + - type: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet/properties/podLifeTimeThreshold + customClass: width-300 + if: + type: function + name: mongoTypeEqualsTo|replicaSet|compute + - type: block-layout + label: ReplicaSet + if: + type: function + name: mongoTypeEqualsTo|replicaSet|compute + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-replicaSet-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|replicaSet|min + loader: + name: getMachines|replicaSet|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-replicaSet-max + watcher: + func: onMachineChange|replicaSet + paths: + - temp/properties/allowedMachine-replicaSet-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-replicaSet-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|replicaSet|max + loader: + name: getMachines|replicaSet|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-replicaSet-min + watcher: + func: onMachineChange|replicaSet + paths: + - temp/properties/allowedMachine-replicaSet-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|compute/replicaSet + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet/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/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet/properties/containerControlledValues + - type: block-layout + label: In Memory Storage + if: + type: function + name: showStorageMemoryOption + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet/properties/inMemoryStorage + elements: + - type: threshold-input + label: Scaling Factor Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet/properties/inMemoryStorage/properties/scalingFactorPercentage + - type: threshold-input + label: Usage Threshold Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet/properties/inMemoryStorage/properties/usageThresholdPercentage + # type sharded + - type: block-layout + showLabels: false + if: + type: function + name: mongoTypeEqualsTo|sharded|compute + elements: + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComMongoDBAutoscaler/spec/compute/shard/trigger + schema: temp/properties/compute/properties/shard/properties/trigger + watcher: + func: onTriggerChange|compute/shard + paths: + - temp/properties/compute/properties/shard/properties/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard/properties/podLifeTimeThreshold + customClass: width-300 + - type: block-layout + label: Shard + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-shard-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|shard|min + loader: + name: getMachines|shard|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-shard-max + watcher: + func: onMachineChange|shard + paths: + - temp/properties/allowedMachine-shard-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-shard-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|shard|max + loader: + name: getMachines|shard|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-shard-min + watcher: + func: onMachineChange|shard + paths: + - temp/properties/allowedMachine-shard-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|compute/shard + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard/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/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard/properties/containerControlledValues + - type: block-layout + label: In Memory Storage + if: + type: function + name: showStorageMemoryOption + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard/properties/inMemoryStorage + elements: + - type: threshold-input + label: Scaling Factor Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard/properties/inMemoryStorage/properties/scalingFactorPercentage + - type: threshold-input + label: Usage Threshold Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard/properties/inMemoryStorage/properties/usageThresholdPercentage + + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComMongoDBAutoscaler/spec/compute/configServer/trigger + schema: temp/properties/compute/properties/configServer/properties/trigger + watcher: + func: onTriggerChange|compute/configServer + paths: + - temp/properties/compute/properties/configServer/properties/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer/properties/podLifeTimeThreshold + customClass: width-300 + - type: block-layout + label: Config Server + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-configServer-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|configServer|min + loader: + name: getMachines|configServer|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-configServer-max + watcher: + func: onMachineChange|configServer + paths: + - temp/properties/allowedMachine-configServer-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-configServer-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|configServer|max + loader: + name: getMachines|configServer|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-configServer-min + watcher: + func: onMachineChange|configServer + paths: + - temp/properties/allowedMachine-configServer-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|compute/configServer + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer/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/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer/properties/containerControlledValues + - type: block-layout + label: In Memory Storage + if: + type: function + name: showStorageMemoryOption + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer/properties/inMemoryStorage + elements: + - type: threshold-input + label: Scaling Factor Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer/properties/inMemoryStorage/properties/scalingFactorPercentage + - type: threshold-input + label: Usage Threshold Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer/properties/inMemoryStorage/properties/usageThresholdPercentage + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComMongoDBAutoscaler/spec/compute/arbiter/trigger + schema: temp/properties/compute/properties/arbiter/properties/trigger + watcher: + func: onTriggerChange|compute/arbiter + paths: + - temp/properties/compute/properties/arbiter/properties/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/properties/podLifeTimeThreshold + customClass: width-300 + - type: block-layout + label: Arbiter + showLabels: true + hideBlock: true + # schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-arbiter-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|arbiter|min + loader: + name: getMachines|arbiter|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-arbiter-max + watcher: + func: onMachineChange|arbiter + paths: + - temp/properties/allowedMachine-arbiter-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-arbiter-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|arbiter|max + loader: + name: getMachines|arbiter|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-arbiter-min + watcher: + func: onMachineChange|arbiter + paths: + - temp/properties/allowedMachine-arbiter-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|compute/arbiter + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/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/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/properties/containerControlledValues + - type: block-layout + label: In Memory Storage + if: + type: function + name: showStorageMemoryOption + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/properties/inMemoryStorage + elements: + - type: threshold-input + label: Scaling Factor Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/properties/inMemoryStorage/properties/scalingFactorPercentage + - type: threshold-input + label: Usage Threshold Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/properties/inMemoryStorage/properties/usageThresholdPercentage + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComMongoDBAutoscaler/spec/compute/hidden/trigger + schema: temp/properties/compute/properties/hidden/properties/trigger + watcher: + func: onTriggerChange|compute/hidden + paths: + - temp/properties/compute/properties/hidden/properties/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/properties/podLifeTimeThreshold + customClass: width-300 + - type: block-layout + label: Hidden + showLabels: true + hideBlock: true + # schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-hidden-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|hidden|min + loader: + name: getMachines|hidden|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-hidden-max + watcher: + func: onMachineChange|hidden + paths: + - temp/properties/allowedMachine-hidden-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-hidden-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|hidden|max + loader: + name: getMachines|hidden|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-hidden-min + watcher: + func: onMachineChange|hidden + paths: + - temp/properties/allowedMachine-hidden-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|compute/hidden + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/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/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/properties/containerControlledValues + - type: block-layout + label: In Memory Storage + if: + type: function + name: showStorageMemoryOption + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/properties/inMemoryStorage + elements: + - type: threshold-input + label: Scaling Factor Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/properties/inMemoryStorage/properties/scalingFactorPercentage + - type: threshold-input + label: Usage Threshold Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/properties/inMemoryStorage/properties/usageThresholdPercentage + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComMongoDBAutoscaler/spec/compute/mongos/trigger + schema: temp/properties/compute/properties/mongos/properties/trigger + watcher: + func: onTriggerChange|compute/mongos + paths: + - temp/properties/compute/properties/mongos/properties/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos/properties/podLifeTimeThreshold + customClass: width-300 + - type: block-layout + label: Mongos + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-mongos-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|mongos|min + loader: + name: getMachines|mongos|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-mongos-max + watcher: + func: onMachineChange|mongos + paths: + - temp/properties/allowedMachine-mongos-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-mongos-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|mongos|max + loader: + name: getMachines|mongos|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-mongos-min + watcher: + func: onMachineChange|mongos + paths: + - temp/properties/allowedMachine-mongos-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|compute/mongos + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos/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/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos/properties/containerControlledValues + - type: block-layout + label: In Memory Storage + if: + type: function + name: showStorageMemoryOption + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos/properties/inMemoryStorage + elements: + - type: threshold-input + label: Scaling Factor Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos/properties/inMemoryStorage/properties/scalingFactorPercentage + - type: threshold-input + label: Usage Threshold Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos/properties/inMemoryStorage/properties/usageThresholdPercentage + - type: block-layout + label: NodeTopology + if: + type: function + name: hasNoAnnotations + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology + elements: + - type: select + label: Select NodeTopology + loader: fetchNodeTopology + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name + - type: threshold-input + label: Scale Up DiffPercentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage + - type: threshold-input + label: Scale Down DiffPercentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + # schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/opsRequestOptions + elements: + - type: block-layout + label: Readiness Criteria + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/readinessCriteria + elements: + - type: threshold-input + label: Objects Count Diff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/readinessCriteria/properties/objectsCountDiffPercentage + - type: input + label: Oplog Max Lag Seconds + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/readinessCriteria/properties/oplogMaxLagSeconds + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: storage-autoscaler + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - type: input - - discriminator: - topologyMachines: - default: [] - type: array + - type: block-layout + showLabels: false elements: - - fetch: fetchTopologyMachines - if: returnFalse - schema: - $ref: discriminator#/topologyMachines - type: input - - elements: - - computed: setTrigger|autoscalingKubedbComMongoDBAutoscaler/spec/compute/standalone/trigger - label: - text: Trigger + # standalone mode + - type: switch + label: Trigger + fullwidth: true + if: + type: function + name: mongoTypeEqualsTo|standalone|storage + init: + type: func + value: setTrigger|autoscalingKubedbComMongoDBAutoscaler/spec/storage/standalone/trigger + schema: temp/properties/storage/properties/standalone/properties/trigger + watcher: + func: onTriggerChange|storage/standalone + paths: + - temp/properties/storage/properties/standalone/properties/trigger + - type: label-element + 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. + if: + type: function + name: mongoTypeEqualsTo|standalone|storage + - type: select + label: Mode + description: Select how the storage expansion should be handled. + if: + type: function + name: mongoTypeEqualsTo|standalone|storage options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone/properties/podLifeTimeThreshold - type: input - - label: - text: Resource DiffPercentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-standalone-max: - type: strin - allowedMachine-standalone-min: - type: string + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/standalone/properties/expansionMode + - type: block-layout + label: Standalone + if: + type: function + name: mongoTypeEqualsTo|standalone|storage + showLabels: true elements: - - computed: setAllowedMachine|standalone|min - disableUnselect: true - fetch: getMachines|standalone|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|standalone - schema: - $ref: discriminator#/properties/allowedMachine-standalone-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone/properties/minAllowed/properties/cpu - type: input - - label: - text: Memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|standalone|max - disableUnselect: true - fetch: getMachines|standalone|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|standalone - schema: - $ref: discriminator#/properties/allowedMachine-standalone-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone/properties/maxAllowed/properties/cpu - type: input - - label: - text: Memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|compute/standalone - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone/properties/controlledResources - type: multiselect - - label: - text: Container Controlled Values + - type: threshold-input + label: UsageThreshold (%) + subtitle: Set the threshold percentage of storage usage to trigger scaling. + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/standalone/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/standalone/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComMongoDB/spec/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComMongoDBAutoscaler/spec/storage/standalone/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/standalone/properties/scalingRules + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/standalone/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComMongoDBAutoscaler/spec/storage/standalone/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/standalone/properties/upperBound + # replicaset mode + - type: switch + label: Trigger + fullwidth: true + if: + type: function + name: mongoTypeEqualsTo|replicaSet|storage + init: + type: func + value: setTrigger|autoscalingKubedbComMongoDBAutoscaler/spec/storage/replicaSet/trigger + schema: temp/properties/storage/properties/replicaSet/properties/trigger + watcher: + func: onTriggerChange|storage/replicaSet + paths: + - temp/properties/storage/properties/replicaSet/properties/trigger + - type: label-element + 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. + if: + type: function + name: mongoTypeEqualsTo|replicaSet|storage + - type: select + label: Mode + description: Select how the storage expansion should be handled. + if: + type: function + name: mongoTypeEqualsTo|replicaSet|storage options: - - text: Requests And Limits - value: RequestsAndLimits - - text: Requests Only - value: RequestsOnly - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone/properties/containerControlledValues - type: select - - elements: - - label: - text: Scaling Factor Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone/properties/inMemoryStorage/properties/scalingFactorPercentage - type: input - - label: - text: Usage Threshold Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone/properties/inMemoryStorage/properties/usageThresholdPercentage - type: input - label: - text: In Memory Storage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone/properties/inMemoryStorage - show_label: true - type: single-step-form - if: mongoTypeEqualsTo|standalone|compute - label: - text: Standalone - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/standalone - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComMongoDBAutoscaler/spec/compute/replicaSet/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-replicaSet-max: - type: string - allowedMachine-replicaSet-min: - type: string + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/replicaSet/properties/expansionMode + - type: block-layout + label: ReplicaSet + if: + type: function + name: mongoTypeEqualsTo|replicaSet|storage + showLabels: true elements: - - computed: setAllowedMachine|replicaSet|min - disableUnselect: true - fetch: getMachines|replicaSet|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|replicaSet - schema: - $ref: discriminator#/properties/allowedMachine-replicaSet-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|replicaSet|max - disableUnselect: true - fetch: getMachines|replicaSet|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|replicaSet - schema: - $ref: discriminator#/properties/allowedMachine-replicaSet-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|compute/replicaSet - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet/properties/controlledResources - type: multiselect - - label: - text: Container Controlled Values - options: - - text: Requests And Limits - value: RequestsAndLimits - - text: Requests Only - value: RequestsOnly - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet/properties/containerControlledValues - type: select - - elements: - - label: - text: Scaling Factor Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet/properties/inMemoryStorage/properties/scalingFactorPercentage - type: input - - label: - text: Usage Threshold Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet/properties/inMemoryStorage/properties/usageThresholdPercentage - type: input - label: - text: In Memory Storage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet/properties/inMemoryStorage - show_label: true - type: single-step-form - if: mongoTypeEqualsTo|replicaSet|compute - label: - text: ReplicaSet - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/replicaSet - show_label: true - type: single-step-form - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComMongoDBAutoscaler/spec/compute/shard/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-shard-max: - type: string - allowedMachine-shard-min: - type: string - elements: - - computed: setAllowedMachine|shard|min - disableUnselect: true - fetch: getMachines|shard|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|shard - schema: - $ref: discriminator#/properties/allowedMachine-shard-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|shard|max - disableUnselect: true - fetch: getMachines|shard|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|shard - schema: - $ref: discriminator#/properties/allowedMachine-shard-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|compute/shard - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard/properties/controlledResources - type: multiselect - - label: - text: Container Controlled Values - options: - - text: Requests And Limits - value: RequestsAndLimits - - text: Requests Only - value: RequestsOnly - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard/properties/containerControlledValues - type: select - - elements: - - label: - text: Scaling Factor Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard/properties/inMemoryStorage/properties/scalingFactorPercentage - type: input - - label: - text: Usage Threshold Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard/properties/inMemoryStorage/properties/usageThresholdPercentage - type: input - label: - text: In Memory Storage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard/properties/inMemoryStorage - show_label: true - type: single-step-form - label: - text: Shard - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/shard - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComMongoDBAutoscaler/spec/compute/configServer/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-configServer-max: - type: string - allowedMachine-configServer-min: - type: string - elements: - - computed: setAllowedMachine|configServer|min - disableUnselect: true - fetch: getMachines|configServer|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|configServer - schema: - $ref: discriminator#/properties/allowedMachine-configServer-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|configServer|max - disableUnselect: true - fetch: getMachines|configServer|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|configServer - schema: - $ref: discriminator#/properties/allowedMachine-configServer-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|compute/configServer - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer/properties/controlledResources - type: multiselect - - label: - text: Container Controlled Values - options: - - text: Requests And Limits - value: RequestsAndLimits - - text: Requests Only - value: RequestsOnly - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer/properties/containerControlledValues - type: select - - elements: - - label: - text: Scaling Factor Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer/properties/inMemoryStorage/properties/scalingFactorPercentage - type: input - - label: - text: Usage Threshold Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer/properties/inMemoryStorage/properties/usageThresholdPercentage - type: input - label: - text: In Memory Storage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer/properties/inMemoryStorage - show_label: true - type: single-step-form - label: - text: Config Server - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/configServer - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComMongoDBAutoscaler/spec/compute/arbiter/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/properties/resourceDiffPercentage - type: input - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/properties/minAllowed/properties/memory - type: input - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/properties/minAllowed - show_label: true - type: single-step-form - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/properties/maxAllowed/properties/memory - type: input - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/properties/maxAllowed - show_label: true - type: single-step-form - - fetch: setControlledResources|compute/arbiter - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/properties/controlledResources - type: multiselect - - label: - text: Container Controlled Values - options: - - text: Requests And Limits - value: RequestsAndLimits - - text: Requests Only - value: RequestsOnly - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/properties/containerControlledValues - type: select - - elements: - - label: - text: Scaling Factor Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/properties/inMemoryStorage/properties/scalingFactorPercentage - type: input - - label: - text: Usage Threshold Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/properties/inMemoryStorage/properties/usageThresholdPercentage - type: input - label: - text: In Memory Storage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter/properties/inMemoryStorage - show_label: true - type: single-step-form - hideForm: true - label: - text: Arbiter - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/arbiter - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComMongoDBAutoscaler/spec/compute/hidden/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/properties/resourceDiffPercentage - type: input - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/properties/minAllowed/properties/memory - type: input - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/properties/minAllowed - show_label: true - type: single-step-form - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/properties/maxAllowed/properties/memory - type: input - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/properties/maxAllowed - show_label: true - type: single-step-form - - fetch: setControlledResources|compute/hidden - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/properties/controlledResources - type: multiselect - - label: - text: Container Controlled Values - options: - - text: Requests And Limits - value: RequestsAndLimits - - text: Requests Only - value: RequestsOnly - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/properties/containerControlledValues - type: select - - elements: - - label: - text: Scaling Factor Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/properties/inMemoryStorage/properties/scalingFactorPercentage - type: input - - label: - text: Usage Threshold Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/properties/inMemoryStorage/properties/usageThresholdPercentage - type: input - label: - text: In Memory Storage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden/properties/inMemoryStorage - show_label: true - type: single-step-form - hideForm: true - label: - text: Hidden - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/hidden - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComMongoDBAutoscaler/spec/compute/mongos/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-mongos-max: - type: string - allowedMachine-mongos-min: - type: string - elements: - - computed: setAllowedMachine|mongos|min - disableUnselect: true - fetch: getMachines|mongos|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|mongos - schema: - $ref: discriminator#/properties/allowedMachine-mongos-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|mongos|max - disableUnselect: true - fetch: getMachines|mongos|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|mongos - schema: - $ref: discriminator#/properties/allowedMachine-mongos-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - type: single-step-form - type: single-step-form - - fetch: setControlledResources|compute/mongos - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos/properties/controlledResources - type: multiselect - - label: - text: Container Controlled Values - options: - - text: Requests And Limits - value: RequestsAndLimits - - text: Requests Only - value: RequestsOnly - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos/properties/containerControlledValues - type: select - - elements: - - label: - text: Scaling Factor Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos/properties/inMemoryStorage/properties/scalingFactorPercentage - type: input - - label: - text: Usage Threshold Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos/properties/inMemoryStorage/properties/usageThresholdPercentage - type: input - label: - text: In Memory Storage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos/properties/inMemoryStorage - show_label: true - type: single-step-form - label: - text: Mongos - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/mongos - show_label: true - type: single-step-form - if: mongoTypeEqualsTo|sharded|compute - type: single-step-form - - elements: - - fetch: fetchNodeTopology - label: - text: Select NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name - type: select - - if: isNodeTopologySelected - label: - text: Scale Up DiffPercentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage - type: input - - if: isNodeTopologySelected - label: - text: Scale Down DiffPercentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage - type: input - if: hasNoAnnotations - label: - text: NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology - show_label: true - type: single-step-form - type: single-step-form - - elements: - - elements: - - label: - text: Objects Count Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/readinessCriteria/properties/objectsCountDiffPercentage - type: input - - label: - text: Oplog Max Lag Seconds - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/readinessCriteria/properties/oplogMaxLagSeconds - type: input - label: - text: Readiness Criteria - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/readinessCriteria - show_label: true - type: single-step-form - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: compute-autoscaler - title: steps.10.label -- form: - discriminator: - dbDetails: - default: false - type: boolean - elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComMongoDBAutoscaler/spec/storage/standalone/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/standalone/properties/trigger - type: select - - label: - text: Expansion Mode - options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/standalone/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/standalone/properties/usageThreshold - type: input - - addFormLabel: Scaling Rules - element: - elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/standalone/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/standalone/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComMongoDBAutoscaler/spec/storage/standalone/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/standalone/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: Scaling Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/standalone/properties/scalingThreshold - type: input - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComMongoDBAutoscaler/spec/storage/standalone/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/standalone/properties/upperBound - type: input - if: mongoTypeEqualsTo|standalone|storage - label: - text: Standalone - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/standalone - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComMongoDBAutoscaler/spec/storage/replicaSet/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/replicaSet/properties/trigger - type: select - - label: - text: Expansion Mode + - type: threshold-input + label: UsageThreshold (%) + subtitle: Set the threshold percentage of storage usage to trigger scaling. + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/replicaSet/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/replicaSet/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComMongoDB/spec/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComMongoDBAutoscaler/spec/storage/replicaSet/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/replicaSet/properties/scalingRules + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/replicaSet/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComMongoDBAutoscaler/spec/storage/replicaSet/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/replicaSet/properties/upperBound + # sharded mode + - type: switch + label: Trigger + fullwidth: true + if: + type: function + name: mongoTypeEqualsTo|sharded|storage + init: + type: func + value: setTrigger|autoscalingKubedbComMongoDBAutoscaler/spec/storage/shard/trigger + schema: temp/properties/storage/properties/shard/properties/trigger + watcher: + func: onTriggerChange|storage/shard + paths: + - temp/properties/storage/properties/shard/properties/trigger + - type: label-element + 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. + if: + type: function + name: mongoTypeEqualsTo|sharded|storage + - type: select + label: Mode + description: Select how the storage expansion should be handled. + if: + type: function + name: mongoTypeEqualsTo|sharded|storage options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/replicaSet/properties/expansionMode - type: select - - label: - text: usageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/replicaSet/properties/usageThreshold - type: input - - addFormLabel: Scaling Rules - element: - elements: - - label: - text: aApplies Upto - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/replicaSet/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/replicaSet/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComMongoDBAutoscaler/spec/storage/replicaSet/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/replicaSet/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: Scaling Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/replicaSet/properties/scalingThreshold - type: input - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComMongoDBAutoscaler/spec/storage/replicaSet/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/replicaSet/properties/upperBound - type: input - if: mongoTypeEqualsTo|replicaSet|storage - label: - text: ReplicaSet - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/replicaSet - show_label: true - type: single-step-form - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComMongoDBAutoscaler/spec/storage/shard/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/shard/properties/trigger - type: select - - label: - text: Expansion Mode - options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/shard/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/shard/properties/usageThreshold - type: input - - addFormLabel: Scaling Rules - element: + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/shard/properties/expansionMode + - type: block-layout + showLabels: false + if: + type: function + name: mongoTypeEqualsTo|sharded|storage + elements: + - type: block-layout + label: Shard + showLabels: true elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/shard/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/shard/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComMongoDBAutoscaler/spec/storage/shard/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/shard/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComMongoDBAutoscaler/spec/storage/shard/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/shard/properties/upperBound - type: input - - label: - text: Scaling Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/shard/properties/scalingThreshold - type: input - label: - text: Shard - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/shard - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComMongoDBAutoscaler/spec/storage/configServer/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/configServer/properties/trigger - type: select - - label: - text: Expansion Mode - options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/configServer/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/configServer/properties/usageThreshold - type: input - - addFormLabel: Scaling Rules - element: + - type: threshold-input + label: UsageThreshold (%) + subtitle: Set the threshold percentage of storage usage to trigger scaling. + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/shard/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/shard/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComMongoDB/spec/shardTopology/shard/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComMongoDBAutoscaler/spec/storage/shard/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/shard/properties/scalingRules + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/shard/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComMongoDBAutoscaler/spec/storage/shard/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/shard/properties/upperBound + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComMongoDBAutoscaler/spec/storage/configServer/trigger + schema: temp/properties/storage/properties/configServer/properties/trigger + watcher: + func: onTriggerChange|storage/configServer + paths: + - temp/properties/storage/properties/configServer/properties/trigger + - type: label-element + 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: select + label: Mode + description: Select how the storage expansion should be handled. + options: + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/configServer/properties/expansionMode + - type: block-layout + label: Config Server + showLabels: true elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/configServer/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/configServer/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComMongoDBAutoscaler/spec/storage/configServer/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/configServer/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComMongoDBAutoscaler/spec/storage/configServer/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/configServer/properties/upperBound - type: input - - label: - text: Scaling Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/configServer/properties/scalingThreshold - type: input - label: - text: ConfigServer - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/configServer - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComMongoDBAutoscaler/spec/storage/hidden/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/hidden/properties/trigger - type: select - - label: - text: Expansion Mode - options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/hidden/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/hidden/properties/usageThreshold - type: input - - addFormLabel: Scaling Rules - element: + - type: threshold-input + label: UsageThreshold (%) + subtitle: Set the threshold percentage of storage usage to trigger scaling. + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/configServer/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/configServer/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComMongoDB/spec/shardTopology/configServer/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComMongoDBAutoscaler/spec/storage/configServer/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/configServer/properties/scalingRules + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/configServer/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComMongoDBAutoscaler/spec/storage/configServer/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/configServer/properties/upperBound + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComMongoDBAutoscaler/spec/storage/hidden/trigger + schema: temp/properties/storage/properties/hidden/properties/trigger + watcher: + func: onTriggerChange|storage/hidden + paths: + - temp/properties/storage/properties/hidden/properties/trigger + - type: label-element + 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: select + label: Mode + description: Select how the storage expansion should be handled. + options: + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/hidden/properties/expansionMode + - type: block-layout + label: Hidden + showLabels: true + if: + name: isHidden|resources/kubedbComMongoDB/spec/hidden + type: function elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/hidden/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/hidden/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComMongoDBAutoscaler/spec/storage/hidden/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/hidden/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComMongoDBAutoscaler/spec/storage/hidden/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/hidden/properties/upperBound - type: input - - label: - text: Scaling Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/hidden/properties/scalingThreshold - type: input - label: - text: Hidden - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/hidden - show_label: true - type: single-step-form - if: mongoTypeEqualsTo|sharded|storage - type: single-step-form - type: single-step-form - - elements: - - elements: - - label: - text: Objects Count Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/readinessCriteria/properties/objectsCountDiffPercentage - type: input - - label: - text: Oplog Max Lag Seconds - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/readinessCriteria/properties/oplogMaxLagSeconds - type: input - label: - text: Readiness Criteria - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/readinessCriteria - show_label: true - type: single-step-form - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: storage-autoscaler - title: steps.11.label -- form: - discriminator: - binding: - default: false - type: boolean + - type: threshold-input + label: UsageThreshold (%) + subtitle: Set the threshold percentage of storage usage to trigger scaling. + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/hidden/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/hidden/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComMongoDB/spec/hidden/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComMongoDBAutoscaler/spec/storage/hidden/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/hidden/properties/scalingRules + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/hidden/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComMongoDBAutoscaler/spec/storage/hidden/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/storage/properties/hidden/properties/upperBound + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + elements: + - type: block-layout + label: Readiness Criteria + showLabels: true + elements: + - type: threshold-input + label: Objects Count Diff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/readinessCriteria/properties/objectsCountDiffPercentage + - type: input + label: Oplog Max Lag Seconds + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/readinessCriteria/properties/oplogMaxLagSeconds + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComMongoDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: binding elements: - - computed: isBindingAlreadyOn - label: - text: Expose Database - onChange: addOrRemoveBinding - schema: - $ref: discriminator#/properties/binding - type: switch - type: single-step-form - id: binding - title: Gateway Binding -type: multi-step-form + - type: switch + label: Expose Database + schema: temp/properties/binding + fullwidth: true + init: + type: func + value: isBindingAlreadyOn + watcher: + func: addOrRemoveBinding + paths: + - temp/properties/binding \ No newline at end of file diff --git a/charts/kubedbcom-mongodb-editor/ui/functions.js b/charts/kubedbcom-mongodb-editor/ui/functions.js index 6b7d18b846..e96f5e5684 100644 --- a/charts/kubedbcom-mongodb-editor/ui/functions.js +++ b/charts/kubedbcom-mongodb-editor/ui/functions.js @@ -1,2198 +1,2387 @@ -// ************************* common functions ******************************************** -// eslint-disable-next-line no-empty-pattern -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) +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + +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('/env', []) + setDiscriminatorValue('/valueFromType', 'input') + + // Compute 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', '') + + // ************************* common functions ******************************************** + // eslint-disable-next-line no-empty-pattern + 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, + } } - return { - ui: ui.data || {}, - language: language.data || {}, - functions, + function initMonitoring() { + const env = + getValue(model, '/resources/kubedbComMongoDB/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) } -} -function disableLableChecker({ itemCtx }) { - const { key } = itemCtx - if (key.startsWith('app.kubernetes.io') || key.includes('helm')) return true - else return false -} + function disableLableChecker({ itemCtx }) { + const { key } = itemCtx + if (key.startsWith('app.kubernetes.io') || key.includes('helm')) return true + else return false + } -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } -async function getResources({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 } } } }, - }, - ) + 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) || [] + 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 [] + } + } - 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 isConfigMapTypeValueFrom() { + const valueFrom = getValue(discriminator, '/valueFrom') + return !!(valueFrom && valueFrom.configMapKeyRef) + } + + function isSecretTypeValueFrom() { + const valueFrom = getValue(discriminator, '/valueFrom') + return !!(valueFrom && valueFrom.secretKeyRef) + } + + function isInputTypeValueFrom() { + return !isConfigMapTypeValueFrom() && !isSecretTypeValueFrom() + } + + 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 isEqualToDiscriminatorPath( - { discriminator, getValue, watchDependency }, - value, - discriminatorPath, -) { - watchDependency('discriminator#' + discriminatorPath) - const discriminatorValue = getValue(discriminator, discriminatorPath) - return discriminatorValue === value -} + function isEqualToDiscriminatorPath( + { discriminator, getValue, watchDependency }, + value, + discriminatorPath, + ) { + watchDependency('discriminator#' + discriminatorPath) + const discriminatorValue = getValue(discriminator, discriminatorPath) + return discriminatorValue === value + } -function setValueFromModel({ getValue, model }, path) { - return getValue(model, path) -} + function setValueFromModel({ getValue, model }, path) { + return getValue(model, path) + } -function isNotShardModeSelected({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComMongoDB/spec') - const hasShardTopology = getValue(model, '/resources/kubedbComMongoDB/spec/shardTopology') - return !hasShardTopology -} + function isEqualToTemp(value, index) { + //watchDependency('discriminator#/valueFromType') + const valueFrom = getValue(discriminator, `/env/${index}/temp/valueFromType`) + return valueFrom === value + } -function isShardModeSelected({ model, getValue, watchDependency, commit }) { - const resp = !isNotShardModeSelected({ model, getValue, watchDependency }) - if (resp) { - commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/configSecret') - commit('wizard/model$delete', '/resources/secret_config') + // function isEqualToValueFromType(index, value) { + // //watchDependency('discriminator#/valueFromType') + // // const valueFrom = getValue(discriminator, '/valueFromType') + // const valueFrom = getValue( + // model, + // '/resources/kubedbComMongoDB/spec/monitor/prometheus/exporter/env', + // ) + // return valueFrom[index].valueFromType === value + // } + + function isNotShardModeSelected({ model, getValue, watchDependency }) { + watchDependency('model#/resources/kubedbComMongoDB/spec') + const hasShardTopology = getValue(model, '/resources/kubedbComMongoDB/spec/shardTopology') + return !hasShardTopology } - return resp -} -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function isShardModeSelected({ model, getValue, watchDependency, commit }) { + const resp = !isNotShardModeSelected({ model, getValue, watchDependency }) + if (resp) { + commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/configSecret') + commit('wizard/model$delete', '/resources/secret_config') + } + return resp + } + + 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}` - 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 } }, + }, + }) - 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) + } - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + return ans } - return ans -} + async function getResourceList(axios, storeGet, { group, version, resource }) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` - 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 } }, + }, + }) - 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) + } - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + return ans } - return ans -} - -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - 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, - }) + async function resourceNames(group, version, resource) { + const namespace = getValue(model, '/metadata/release/namespace') + // watchDependency('model#/metadata/release/namespace') - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) + let resources = await getNamespacedResourceList(axios, storeGet, { + namespace, + group, + version, + resource, }) - } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) } - }) -} - -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - 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, + } }) } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { + let resources = await getResourceList(axios, storeGet, { + group, + version, + resource, + }) -function returnTrue() { - return true -} + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } -function returnStringYes() { - return 'yes' -} + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -// ************************* Basic Info ********************************************** -async function getMongoDbVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function returnTrue() { + return true + } - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, - }, - }, + function returnStringYes() { + return 'yes' } - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, + // ************************* Basic Info ********************************************** + async function getMongoDbVersions({ axios, storeGet }, group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + + const queryParams = { + filter: { + items: { + metadata: { name: null }, + spec: { version: null, deprecated: null }, + }, }, - ) + } - const resources = (resp && resp.data && resp.data.items) || [] + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: queryParams, + }, + ) - // keep only non deprecated versions - const filteredMongoDbVersions = resources.filter((item) => item.spec && !item.spec.deprecated) + const resources = (resp && resp.data && resp.data.items) || [] - filteredMongoDbVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredMongoDbVersions - } catch (e) { - console.log(e) - return [] + // keep only non deprecated versions + const filteredMongoDbVersions = resources.filter((item) => item.spec && !item.spec.deprecated) + + filteredMongoDbVersions.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + const specVersion = (item.spec && item.spec.version) || '' + item.text = `${name} (${specVersion})` + item.value = name + return true + }) + return filteredMongoDbVersions + } catch (e) { + console.log(e) + return [] + } } -} -// ************************* Auth Secret Field ****************************************** -function showAuthPasswordField({ model, getValue, watchDependency }) { - watchDependency('model#/resources') - const modelPathValue = getValue(model, '/resources') - return !!( - modelPathValue && - modelPathValue.secret && - modelPathValue.secret.metadata && - modelPathValue.secret.metadata.name && - !showAuthSecretField({ model, getValue, watchDependency }) - ) -} + // ************************* Auth Secret Field ****************************************** + function showAuthPasswordField({ model, getValue, watchDependency }) { + watchDependency('model#/resources') + const modelPathValue = getValue(model, '/resources') + return !!( + modelPathValue && + modelPathValue.secret && + modelPathValue.secret.metadata && + modelPathValue.secret.metadata.name && + !showAuthSecretField({ model, getValue, watchDependency }) + ) + } -function showAuthSecretField({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComMongoDB/spec') - const modelPathValue = getValue(model, '/resources/kubedbComMongoDB/spec') - return !!(modelPathValue && modelPathValue.authSecret && modelPathValue.authSecret.name) -} + function showAuthSecretField({ model, getValue, watchDependency }) { + watchDependency('model#/resources/kubedbComMongoDB/spec') + const modelPathValue = getValue(model, '/resources/kubedbComMongoDB/spec') + return !!(modelPathValue && modelPathValue.authSecret && modelPathValue.authSecret.name) + } -function showNewSecretCreateField({ model, getValue, watchDependency, commit }) { - const resp = - !showAuthSecretField({ model, getValue, watchDependency }) && - !showAuthPasswordField({ model, getValue, watchDependency }) - const secret = getValue(model, '/resources/secret_auth') - if (resp && !secret) { - commit('wizard/model$update', { - path: '/resources/secret_auth', - value: { - data: { - password: '', + function showNewSecretCreateField({ model, getValue, watchDependency, commit }) { + const resp = + !showAuthSecretField({ model, getValue, watchDependency }) && + !showAuthPasswordField({ model, getValue, watchDependency }) + const secret = getValue(model, '/resources/secret_auth') + if (resp && !secret) { + commit('wizard/model$update', { + path: '/resources/secret_auth', + value: { + data: { + password: '', + }, }, - }, - force: true, - }) + force: true, + }) + } + return resp } - return resp -} -// ********************* Database Mode *********************** -function isNotStandaloneMode({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - return mode !== 'Standalone' -} + // ********************* Database Mode *********************** + function isNotStandaloneMode({ discriminator, getValue, watchDependency }) { + watchDependency('discriminator#/activeDatabaseMode') + const mode = getValue(discriminator, '/activeDatabaseMode') + return mode !== 'Standalone' + } -function showCommonStorageClassAndSizeField({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - const validType = ['Standalone', 'Replicaset'] - return validType.includes(mode) -} -function setDatabaseMode({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/resources/kubedbComMongoDB/spec') + function showCommonStorageClassAndSizeField({ discriminator, getValue, watchDependency }) { + watchDependency('discriminator#/activeDatabaseMode') + const mode = getValue(discriminator, '/activeDatabaseMode') + const validType = ['Standalone', 'Replicaset'] + return validType.includes(mode) + } + function setDatabaseMode({ model, getValue, watchDependency }) { + const modelPathValue = getValue(model, '/resources/kubedbComMongoDB/spec') - watchDependency('model#/resources/kubedbComMongoDB/spec') - if (modelPathValue.shardTopology) { - return 'Sharded' - } else if (modelPathValue.replicaSet) { - return 'Replicaset' - } else { - return 'Standalone' + watchDependency('model#/resources/kubedbComMongoDB/spec') + if (modelPathValue.shardTopology) { + return 'Sharded' + } else if (modelPathValue.replicaSet) { + return 'Replicaset' + } else { + return 'Standalone' + } } -} -let storageClassList = [] -async function getStorageClassNames( - { axios, storeGet, commit, model, getValue, watchDependency, discriminator }, - mode, -) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const databaseModeShard = getValue(discriminator, '/activeDatabaseMode') === 'Sharded' - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/storage.k8s.io/v1/storageclasses`, - { - params: { - filter: { items: { metadata: { name: null, annotations: null } } }, + let storageClassList = [] + async function getStorageClassNames( + { axios, storeGet, commit, model, getValue, watchDependency, discriminator }, + mode, + ) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + + const databaseModeShard = getValue(discriminator, '/activeDatabaseMode') === 'Sharded' + + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/storage.k8s.io/v1/storageclasses`, + { + params: { + filter: { items: { metadata: { name: null, annotations: null } } }, + }, }, - }, - ) + ) - const resources = (resp && resp.data && resp.data.items) || [] + 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 - }) - storageClassList = resources - const path = - mode === 'shard' - ? '/resources/kubedbComMongoDB/spec/shardTopology/shard/storage/storageClassName' - : '/resources/kubedbComMongoDB/spec/storage/storageClassName' - const initialStorageClass = getValue(model, path) - if (!initialStorageClass) setStorageClass({ getValue, commit, model, discriminator }) - return resources -} + resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true + }) + storageClassList = resources + const path = + mode === 'shard' + ? '/resources/kubedbComMongoDB/spec/shardTopology/shard/storage/storageClassName' + : '/resources/kubedbComMongoDB/spec/storage/storageClassName' + const initialStorageClass = getValue(model, path) + if (!initialStorageClass) setStorageClass({ getValue, commit, model, discriminator }) + return resources + } -function setStorageClass({ getValue, commit, model, discriminator }) { - const deletionPolicy = getValue(model, 'resources/kubedbComMongoDB/spec/deletionPolicy') || '' - const suffix = '-retain' - let storageClass = '' + function setStorageClass({ getValue, commit, model, discriminator }) { + const deletionPolicy = getValue(model, 'resources/kubedbComMongoDB/spec/deletionPolicy') || '' + const suffix = '-retain' + let storageClass = '' - const simpleClassList = storageClassList.filter((item) => { - return !item.metadata?.name?.endsWith(suffix) - }) + const simpleClassList = storageClassList.filter((item) => { + return !item.metadata?.name?.endsWith(suffix) + }) - const retainClassList = storageClassList.filter((item) => { - return item.metadata?.name?.endsWith(suffix) - }) + const retainClassList = storageClassList.filter((item) => { + return item.metadata?.name?.endsWith(suffix) + }) - const defaultSimpleList = simpleClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] - ) - }) + const defaultSimpleList = simpleClassList.filter((item) => { + return ( + item.metadata && + item.metadata.annotations && + item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] + ) + }) - const defaultRetainList = retainClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] - ) - }) - - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - if (simpleClassList.length > 1) { - const found = defaultSimpleList.length ? defaultSimpleList[0] : simpleClassList[0] - storageClass = found.value - } else if (simpleClassList.length === 1) { - storageClass = simpleClassList[0]?.value + const defaultRetainList = retainClassList.filter((item) => { + return ( + item.metadata && + item.metadata.annotations && + item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] + ) + }) + + if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { + if (simpleClassList.length > 1) { + const found = defaultSimpleList.length ? defaultSimpleList[0] : simpleClassList[0] + storageClass = found.value + } else if (simpleClassList.length === 1) { + storageClass = simpleClassList[0]?.value + } else { + const found = defaultRetainList.length + ? defaultRetainList[0].value + : storageClassList.length + ? storageClassList[0].value + : '' + storageClass = found + } } else { - const found = defaultRetainList.length - ? defaultRetainList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found - } - } else { - if (retainClassList.length > 1) { - const found = defaultRetainList.length ? defaultRetainList[0] : retainClassList[0] - storageClass = found.value - } else if (retainClassList.length === 1) { - storageClass = retainClassList[0]?.value + if (retainClassList.length > 1) { + const found = defaultRetainList.length ? defaultRetainList[0] : retainClassList[0] + storageClass = found.value + } else if (retainClassList.length === 1) { + storageClass = retainClassList[0]?.value + } else { + const found = defaultSimpleList.length + ? defaultSimpleList[0].value + : storageClassList.length + ? storageClassList[0].value + : '' + storageClass = found + } + } + + const mode = getValue(discriminator, '/activeDatabaseMode') + + if (mode === 'Sharded') { + commit('wizard/model$update', { + path: '/resources/kubedbComMongoDB/spec/shardTopology/shard/storage/storageClassName', + value: storageClass, + force: true, + }) + commit('wizard/model$update', { + path: '/resources/kubedbComMongoDB/spec/shardTopology/configServer/storage/storageClassName', + value: storageClass, + force: true, + }) + commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/storage') } else { - const found = defaultSimpleList.length - ? defaultSimpleList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found + commit('wizard/model$update', { + path: '/resources/kubedbComMongoDB/spec/storage/storageClassName', + value: storageClass, + force: true, + }) } } - const mode = getValue(discriminator, '/activeDatabaseMode') - - if (mode === 'Sharded') { - commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB/spec/shardTopology/shard/storage/storageClassName', - value: storageClass, - force: true, - }) + function updateConfigServerStorageClass({ getValue, model, commit }) { + const storageClass = + getValue( + model, + '/resources/kubedbComMongoDB/spec/shardTopology/shard/storage/storageClassName', + ) || '' commit('wizard/model$update', { path: '/resources/kubedbComMongoDB/spec/shardTopology/configServer/storage/storageClassName', value: storageClass, force: true, }) - commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/storage') - } else { - commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB/spec/storage/storageClassName', - value: storageClass, - force: true, - }) } -} - -function updateConfigServerStorageClass({ getValue, model, commit }) { - const storageClass = - getValue( - model, - '/resources/kubedbComMongoDB/spec/shardTopology/shard/storage/storageClassName', - ) || '' - commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB/spec/shardTopology/configServer/storage/storageClassName', - value: storageClass, - force: true, - }) -} - -function deleteDatabaseModePath({ discriminator, getValue, commit, model }) { - const mode = getValue(discriminator, '/activeDatabaseMode') - const modelSpec = getValue(model, '/resources/kubedbComMongoDB/spec') - if (mode === 'Sharded') { - commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/replicaSet') - commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/replicas') - commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/storage') - commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/podTemplate') - commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/configSecret') - - commit('wizard/model$delete', '/resources/secret_config') - if (!modelSpec.shardTopology) { - commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB/spec/shardTopology', - value: { - configServer: { - replicas: 3, - storage: { - resources: { - requests: { - storage: '', + function deleteDatabaseModePath({ discriminator, getValue, commit, model }) { + const mode = getValue(discriminator, '/activeDatabaseMode') + const modelSpec = getValue(model, '/resources/kubedbComMongoDB/spec') + if (mode === 'Sharded') { + commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/replicaSet') + commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/replicas') + commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/storage') + commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/podTemplate') + commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/configSecret') + + commit('wizard/model$delete', '/resources/secret_config') + + if (!modelSpec.shardTopology) { + commit('wizard/model$update', { + path: '/resources/kubedbComMongoDB/spec/shardTopology', + value: { + configServer: { + replicas: 3, + storage: { + resources: { + requests: { + storage: '', + }, }, }, }, - }, - mongos: { - replicas: 2, - }, - shard: { - replicas: 3, - shards: 3, - storage: { - resources: { - requests: { - storage: '', + mongos: { + replicas: 2, + }, + shard: { + replicas: 3, + shards: 3, + storage: { + resources: { + requests: { + storage: '', + }, }, }, }, }, - }, - force: true, - }) - } - } else if (mode === 'Replicaset') { - commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/shardTopology') + force: true, + }) + } + } else if (mode === 'Replicaset') { + commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/shardTopology') + + commit('wizard/model$delete', '/resources/secret_shard_config') + commit('wizard/model$delete', '/resources/secret_configserver_config') + commit('wizard/model$delete', '/resources/secret_mongos_config') + + if (!modelSpec.replicaSet) { + commit('wizard/model$update', { + path: '/resources/kubedbComMongoDB/spec/replicaSet', + value: { name: '' }, + force: true, + }) + commit('wizard/model$update', { + path: '/resources/kubedbComMongoDB/spec/replicas', + value: 3, + force: true, + }) + } + } else if (mode === 'Standalone') { + commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/shardTopology') - commit('wizard/model$delete', '/resources/secret_shard_config') - commit('wizard/model$delete', '/resources/secret_configserver_config') - commit('wizard/model$delete', '/resources/secret_mongos_config') + commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/replicaSet') + commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/replicas') - if (!modelSpec.replicaSet) { - commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB/spec/replicaSet', - value: { name: '' }, - force: true, - }) - commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB/spec/replicas', - value: 3, - force: true, - }) + commit('wizard/model$delete', '/resources/secret_shard_config') + commit('wizard/model$delete', '/resources/secret_configserver_config') + commit('wizard/model$delete', '/resources/secret_mongos_config') } - } else if (mode === 'Standalone') { - commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/shardTopology') - - commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/replicaSet') - commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/replicas') + } - commit('wizard/model$delete', '/resources/secret_shard_config') - commit('wizard/model$delete', '/resources/secret_configserver_config') - commit('wizard/model$delete', '/resources/secret_mongos_config') + function isEqualToDatabaseMode({ getValue, watchDependency, discriminator }, value) { + watchDependency('discriminator#/activeDatabaseMode') + const mode = getValue(discriminator, '/activeDatabaseMode') + return mode === value } -} -function isEqualToDatabaseMode({ getValue, watchDependency, discriminator }, value) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - return mode === value -} + // ************************** TLS ******************************88 -// ************************** TLS ******************************88 + function setApiGroup() { + return 'cert-manager.io' + } -function setApiGroup() { - return 'cert-manager.io' -} + async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + watchDependency('model#/resources/kubedbComMongoDB/spec/tls/issuerRef/apiGroup') + watchDependency('model#/resources/kubedbComMongoDB/spec/tls/issuerRef/kind') + watchDependency('model#/metadata/release/namespace') + const apiGroup = getValue(model, '/resources/kubedbComMongoDB/spec/tls/issuerRef/apiGroup') + const kind = getValue(model, '/resources/kubedbComMongoDB/spec/tls/issuerRef/kind') + const namespace = getValue(model, '/metadata/release/namespace') -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - watchDependency('model#/resources/kubedbComMongoDB/spec/tls/issuerRef/apiGroup') - watchDependency('model#/resources/kubedbComMongoDB/spec/tls/issuerRef/kind') - watchDependency('model#/metadata/release/namespace') - const apiGroup = getValue(model, '/resources/kubedbComMongoDB/spec/tls/issuerRef/apiGroup') - const kind = getValue(model, '/resources/kubedbComMongoDB/spec/tls/issuerRef/kind') - const namespace = getValue(model, '/metadata/release/namespace') + let url + if (kind === 'Issuer') { + url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/namespaces/${namespace}/issuers` + } else if (kind === 'ClusterIssuer') { + url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/clusterissuers` + } - let url - if (kind === 'Issuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/namespaces/${namespace}/issuers` - } else if (kind === 'ClusterIssuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/clusterissuers` - } + if (!url) return [] - if (!url) return [] + try { + const resp = await axios.get(url) - try { - const resp = await axios.get(url) + const resources = (resp && resp.data && resp.data.items) || [] - 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 [] + } + } - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + async function hasIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { + const resp = await getIssuerRefsName({ + axios, + storeGet, + getValue, + model, + watchDependency, }) - return resources - } catch (e) { - console.log(e) - return [] - } -} -async function hasIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await getIssuerRefsName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) + return !!(resp && resp.length) + } - return !!(resp && resp.length) -} + async function hasNoIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { + const resp = await hasIssuerRefName({ + axios, + storeGet, + getValue, + model, + watchDependency, + }) -async function hasNoIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await hasIssuerRefName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) + return !resp + } - return !resp -} + function setClusterAuthMode({ model, getValue }) { + const val = getValue(model, '/resources/kubedbComMongoDB/spec/clusterAuthMode') + return val || 'x509' + } -function setClusterAuthMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComMongoDB/spec/clusterAuthMode') - return val || 'x509' -} + function setSSLMode({ model, getValue }) { + const val = getValue(model, '/resources/kubedbComMongoDB/spec/sslMode') + return val || 'requireSSL' + } -function setSSLMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComMongoDB/spec/sslMode') - return val || 'requireSSL' -} + function showTlsConfigureSection({ watchDependency, discriminator, getValue }) { + watchDependency('discriminator#/configureTLS') + const configureStatus = getValue(discriminator, '/configureTLS') + return configureStatus + } -function showTlsConfigureSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configureTLS') - const configureStatus = getValue(discriminator, '/configureTLS') - return configureStatus -} + function onTlsConfigureChange({ discriminator, getValue, commit }) { + const configureStatus = getValue(discriminator, '/configureTLS') + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComMongoDB/spec/tls', + value: { issuerRef: {}, certificates: [] }, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/tls') + commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/clusterAuthMode') + commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/sslMode') + } + } -function onTlsConfigureChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/configureTLS') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB/spec/tls', - value: { issuerRef: {}, certificates: [] }, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/tls') - commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/clusterAuthMode') - commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/sslMode') + function getAliasOptions() { + return ['server', 'client', 'metrics-exporter'] } -} -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} + /****** Monitoring *********/ -/****** Monitoring *********/ + function showMonitoringSection() { + // watchDependency('discriminator#/enableMonitoring') + const configureStatus = getValue(discriminator, '/enableMonitoring') + return configureStatus + } -function showMonitoringSection({ watchDependency, discriminator, getValue }) { - 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/kubedbComMongoDB/spec/monitor', + value: {}, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/monitor') + } -function onEnableMonitoringChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/enableMonitoring') - if (configureStatus) { + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB/spec/monitor', - value: {}, + path: '/form/alert/enabled', + value: configureStatus ? 'warning' : 'none', force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComMongoDB/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, getValue }) { - watchDependency('discriminator#/customizeExporter') - const configureStatus = getValue(discriminator, '/customizeExporter') - return configureStatus -} + function showCustomizeExporterSection() { + // watchDependency('discriminator#/customizeExporter') + const configureStatus = getValue(discriminator, '/customizeExporter') + return configureStatus + } -function onCustomizeExporterChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/customizeExporter') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB/spec/monitor/prometheus/exporter', - value: {}, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/monitor/prometheus/exporter') + function onCustomizeExporterChange() { + const configureStatus = getValue(discriminator, '/customizeExporter') + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComMongoDB/spec/monitor/prometheus/exporter', + value: {}, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/monitor/prometheus/exporter') + } } -} -// ********************************* Initialization & Backup ************************************* + // ********************************* Initialization & Backup ************************************* -const stashAppscodeComRestoreSession_init = { - spec: { - repository: { - name: '', - }, - rules: [ - { - snapshots: ['latest'], - }, - ], - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', + const stashAppscodeComRestoreSession_init = { + spec: { + repository: { name: '', }, + rules: [ + { + snapshots: ['latest'], + }, + ], + target: { + ref: { + apiVersion: 'appcatalog.appscode.com/v1alpha1', + kind: 'AppBinding', + name: '', + }, + }, }, - }, -} -const initScript = { - scriptPath: '', - secret: { - secretName: '', - }, -} -const stashAppscodeComRepository_init_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', + } + const initScript = { + scriptPath: '', + secret: { + secretName: '', + }, + } + const stashAppscodeComRepository_init_repo = { + spec: { + backend: { + gcs: { + bucket: '', + prefix: '', + }, + storageSecretName: '', }, - storageSecretName: '', }, - }, -} -const stashAppscodeComRepository_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', + } + const stashAppscodeComRepository_repo = { + spec: { + backend: { + gcs: { + bucket: '', + prefix: '', + }, + storageSecretName: '', }, - storageSecretName: '', }, - }, -} -const restoreSessionInitRunTimeSettings = { - container: { - resources: { - requests: { - cpu: '', - memory: '', + } + const restoreSessionInitRunTimeSettings = { + container: { + resources: { + requests: { + cpu: '', + memory: '', + }, + limits: { + cpu: '', + memory: '', + }, }, - limits: { - cpu: '', - memory: '', + nice: { + adjustment: null, }, - }, - nice: { - adjustment: null, - }, - ionice: { - class: null, - classData: null, - }, - securityContext: { - privileged: false, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', + ionice: { + class: null, + classData: null, }, + securityContext: { + privileged: false, + runAsNonRoot: false, + runAsUser: null, + runAsGroup: null, + seLinuxOptions: { + level: '', + role: '', + type: '', + user: '', + }, + }, + env: [], + envFrom: [], }, - env: [], - envFrom: [], - }, - pod: { - serviceAccountName: '', - imagePullSecrets: [], - securityContext: { - fsGroup: null, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', + pod: { + serviceAccountName: '', + imagePullSecrets: [], + securityContext: { + fsGroup: null, + runAsNonRoot: false, + runAsUser: null, + runAsGroup: null, + seLinuxOptions: { + level: '', + role: '', + type: '', + user: '', + }, }, }, - }, -} + } -const stashAppscodeComBackupConfiguration = { - spec: { - repository: { - name: '', - }, - retentionPolicy: { - keepLast: 5, - name: 'keep-last-5', - prune: true, - }, - schedule: '*/5 * * * *', - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', + const stashAppscodeComBackupConfiguration = { + spec: { + repository: { name: '', }, + retentionPolicy: { + keepLast: 5, + name: 'keep-last-5', + prune: true, + }, + schedule: '*/5 * * * *', + target: { + ref: { + apiVersion: 'appcatalog.appscode.com/v1alpha1', + kind: 'AppBinding', + name: '', + }, + }, }, - }, -} - -function disableInitializationSection({ model, getValue, watchDependency }) { - const initialized = getValue(model, '/resources/kubedbComMongoDB/spec/init/initialized') - watchDependency('model#/resources/kubedbComMongoDB/spec/init/initialized') - return !!initialized -} + } -function valueExists(value, getValue, path) { - const val = getValue(value, path) - if (val) return true - else return false -} + function disableInitializationSection({ model, getValue, watchDependency }) { + const initialized = getValue(model, '/resources/kubedbComMongoDB/spec/init/initialized') + watchDependency('model#/resources/kubedbComMongoDB/spec/init/initialized') + return !!initialized + } -function initPrePopulateDatabase({ getValue, model }) { - const waitForInitialRestore = getValue( - model, - '/resources/kubedbComMongoDB/spec/init/waitForInitialRestore', - ) - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - const script = getValue(model, '/resources/kubedbComMongoDB/spec/init/script') + function valueExists(value, getValue, path) { + const val = getValue(value, path) + if (val) return true + else return false + } - return waitForInitialRestore || !!stashAppscodeComRestoreSession_init || !!script ? 'yes' : 'no' -} + function initPrePopulateDatabase({ getValue, model }) { + const waitForInitialRestore = getValue( + model, + '/resources/kubedbComMongoDB/spec/init/waitForInitialRestore', + ) + const stashAppscodeComRestoreSession_init = getValue( + model, + '/resources/stashAppscodeComRestoreSession_init', + ) + const script = getValue(model, '/resources/kubedbComMongoDB/spec/init/script') -function onPrePopulateDatabaseChange({ commit, getValue, discriminator, model }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - if (prePopulateDatabase === 'no') { - // delete related properties - commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB/spec/init/waitForInitialRestore', - value: false, - }) - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/init/script') - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else { - const dbName = getValue(model, '/metadata/release/name') - // set stashAppscodeComRestoreSession_init if it doesn't exist - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - force: true, - }) + return waitForInitialRestore || !!stashAppscodeComRestoreSession_init || !!script ? 'yes' : 'no' + } + function onPrePopulateDatabaseChange({ commit, getValue, discriminator, model }) { + const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') + if (prePopulateDatabase === 'no') { + // delete related properties commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, + path: '/resources/kubedbComMongoDB/spec/init/waitForInitialRestore', + value: false, }) + commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') + commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/init/script') + commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') + } else { + const dbName = getValue(model, '/metadata/release/name') + // set stashAppscodeComRestoreSession_init if it doesn't exist + if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { + commit('wizard/model$update', { + path: '/resources/stashAppscodeComRestoreSession_init', + value: stashAppscodeComRestoreSession_init, + force: true, + }) + + commit('wizard/model$update', { + path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', + value: dbName, + force: true, + }) + } } } -} -function initDataSource({ getValue, model }) { - const script = getValue(model, '/resources/kubedbComMongoDB/spec/init/script') - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) + function initDataSource({ getValue, model }) { + const script = getValue(model, '/resources/kubedbComMongoDB/spec/init/script') + const stashAppscodeComRestoreSession_init = getValue( + model, + '/resources/stashAppscodeComRestoreSession_init', + ) - if (script) return 'script' - else if (stashAppscodeComRestoreSession_init) return 'stashBackup' - else return undefined -} + if (script) return 'script' + else if (stashAppscodeComRestoreSession_init) return 'stashBackup' + else return undefined + } -function onDataSourceChange({ commit, getValue, discriminator, model }) { - const dataSource = getValue(discriminator, '/dataSource') + function onDataSourceChange({ commit, getValue, discriminator, model }) { + const dataSource = getValue(discriminator, '/dataSource') - commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB/spec/init/waitForInitialRestore', - value: dataSource === 'stashBackup', - force: true, - }) + commit('wizard/model$update', { + path: '/resources/kubedbComMongoDB/spec/init/waitForInitialRestore', + value: dataSource === 'stashBackup', + force: true, + }) - if (dataSource === 'script') { - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') + if (dataSource === 'script') { + commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') + + // create a new script if there is no script property + if (!valueExists(model, getValue, '/resources/kubedbComMongoDB/spec/init/script')) + commit('wizard/model$update', { + path: '/resources/kubedbComMongoDB/spec/init/script', + value: initScript, + }) + } else if (dataSource === 'stashBackup') { + commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/init/script') + + // create a new stashAppscodeComRestoreSession_init if there is no stashAppscodeComRestoreSession_init property + if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { + const dbName = getValue(model, '/metadata/release/name') + + commit('wizard/model$update', { + path: '/resources/stashAppscodeComRestoreSession_init', + value: stashAppscodeComRestoreSession_init, + }) + + commit('wizard/model$update', { + path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', + value: dbName, + force: true, + }) + } + } + } - // create a new script if there is no script property - if (!valueExists(model, getValue, '/resources/kubedbComMongoDB/spec/init/script')) - commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB/spec/init/script', - value: initScript, - }) - } else if (dataSource === 'stashBackup') { - commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/init/script') + // // for script + function initVolumeType({ getValue, model }) { + const configMap = getValue(model, '/resources/kubedbComMongoDB/spec/init/script/configMap/name') + const secret = getValue(model, '/resources/kubedbComMongoDB/spec/init/script/secret/secretName') - // create a new stashAppscodeComRestoreSession_init if there is no stashAppscodeComRestoreSession_init property - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - const dbName = getValue(model, '/metadata/release/name') + if (configMap) return 'configMap' + else if (secret) return 'secret' + else return undefined + } - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - }) + function onVolumeTypeChange({ commit, getValue, discriminator, model }) { + const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') + if (sourceVolumeType === 'configMap') { + // add configMap object and delete secret object + commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/init/script/secret') - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) + if (!valueExists(model, getValue, '/resources/kubedbComMongoDB/spec/init/script/configMap')) { + commit('wizard/model$update', { + path: '/resources/kubedbComMongoDB/spec/init/script/configMap', + value: { + name: '', + }, + }) + } + } else if (sourceVolumeType === 'secret') { + // delete configMap object and add secret object + commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/init/script/configMap') + + if (!valueExists(model, getValue, '/resources/kubedbComMongoDB/spec/init/script/secret')) { + commit('wizard/model$update', { + path: '/resources/kubedbComMongoDB/spec/init/script/secret', + value: { + secretName: '', + }, + }) + } } } -} -// // for script -function initVolumeType({ getValue, model }) { - const configMap = getValue(model, '/resources/kubedbComMongoDB/spec/init/script/configMap/name') - const secret = getValue(model, '/resources/kubedbComMongoDB/spec/init/script/secret/secretName') + function showInitializationForm({ getValue, discriminator, watchDependency }) { + const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') + watchDependency('discriminator#/prePopulateDatabase') + return prePopulateDatabase === 'yes' + } - if (configMap) return 'configMap' - else if (secret) return 'secret' - else return undefined -} + function showScriptOrStashForm({ getValue, discriminator, watchDependency }, value) { + const dataSource = getValue(discriminator, '/dataSource') + watchDependency('discriminator#/dataSource') + return dataSource === value + } -function onVolumeTypeChange({ commit, getValue, discriminator, model }) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - if (sourceVolumeType === 'configMap') { - // add configMap object and delete secret object - commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/init/script/secret') + function showConfigMapOrSecretName({ getValue, discriminator, watchDependency }, value) { + const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') + watchDependency('discriminator#/sourceVolumeType') + return sourceVolumeType === value + } + + // for stash backup + function initializeNamespace({ getValue, model }) { + const namespace = getValue(model, '/metadata/release/namespace') + return namespace + } - if (!valueExists(model, getValue, '/resources/kubedbComMongoDB/spec/init/script/configMap')) { + function showRepositorySelectOrCreate({ getValue, discriminator, watchDependency }, value) { + const repositoryChoise = getValue(discriminator, '/repositoryChoise') + watchDependency('discriminator#/repositoryChoise') + + return repositoryChoise === value + } + + function onInitRepositoryChoiseChange({ getValue, discriminator, commit, model }) { + const repositoryChoise = getValue(discriminator, '/repositoryChoise') + if (repositoryChoise === 'select') { + // delete stashAppscodeComRepository_init_repo from model + commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') + } else if (repositoryChoise === 'create') { + // add stashAppscodeComRepository_init_repo to model commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB/spec/init/script/configMap', - value: { - name: '', - }, + path: 'resources/stashAppscodeComRepository_init_repo', + value: stashAppscodeComRepository_init_repo, }) - } - } else if (sourceVolumeType === 'secret') { - // delete configMap object and add secret object - commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/init/script/configMap') - if (!valueExists(model, getValue, '/resources/kubedbComMongoDB/spec/init/script/secret')) { + const repositoryName = `${getValue(model, '/metadata/release/name')}-init-repo` + // set this name in stashAppscodeComRestoreSession_init commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB/spec/init/script/secret', - value: { - secretName: '', - }, + path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', + value: repositoryName, }) } } -} - -function showInitializationForm({ getValue, discriminator, watchDependency }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - watchDependency('discriminator#/prePopulateDatabase') - return prePopulateDatabase === 'yes' -} -function showScriptOrStashForm({ getValue, discriminator, watchDependency }, value) { - const dataSource = getValue(discriminator, '/dataSource') - watchDependency('discriminator#/dataSource') - return dataSource === value -} - -function showConfigMapOrSecretName({ getValue, discriminator, watchDependency }, value) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - watchDependency('discriminator#/sourceVolumeType') - return sourceVolumeType === value -} - -// for stash backup -function initializeNamespace({ getValue, model }) { - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} - -function showRepositorySelectOrCreate({ getValue, discriminator, watchDependency }, value) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - return repositoryChoise === value -} - -function onInitRepositoryChoiseChange({ getValue, discriminator, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - if (repositoryChoise === 'select') { - // delete stashAppscodeComRepository_init_repo from model - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else if (repositoryChoise === 'create') { - // add stashAppscodeComRepository_init_repo to model - commit('wizard/model$update', { - path: 'resources/stashAppscodeComRepository_init_repo', - value: stashAppscodeComRepository_init_repo, - }) - - const repositoryName = `${getValue(model, '/metadata/release/name')}-init-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: repositoryName, - }) + function initCustomizeRestoreJobRuntimeSettings({ getValue, model }) { + const runtimeSettings = getValue( + model, + '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', + ) + if (runtimeSettings) return 'yes' + else return 'no' } -} - -function initCustomizeRestoreJobRuntimeSettings({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} -function initCustomizeRestoreJobRuntimeSettingsForBackup({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} + function initCustomizeRestoreJobRuntimeSettingsForBackup({ getValue, model }) { + const runtimeSettings = getValue( + model, + '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', + ) + if (runtimeSettings) return 'yes' + else return 'no' + } -function onCustomizeRestoreJobRuntimeSettingsChange({ commit, getValue, discriminator, model }) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', + function onCustomizeRestoreJobRuntimeSettingsChange({ commit, getValue, discriminator, model }) { + const customizeRestoreJobRuntimeSettings = getValue( + discriminator, + '/customizeRestoreJobRuntimeSettings', ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, + if (customizeRestoreJobRuntimeSettings === 'no') { + commit( + 'wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - value: restoreSessionInitRunTimeSettings, - }) + } else if (customizeRestoreJobRuntimeSettings === 'yes') { + if ( + !valueExists( + model, + getValue, + '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', + ) + ) { + // set new value + commit('wizard/model$update', { + path: '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', + value: restoreSessionInitRunTimeSettings, + }) + } } } -} -function onCustomizeRestoreJobRuntimeSettingsChangeForBackup({ - commit, - getValue, - discriminator, - model, -}) { - const customizeRestoreJobRuntimeSettings = getValue( + function onCustomizeRestoreJobRuntimeSettingsChangeForBackup({ + commit, + getValue, discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', + model, + }) { + const customizeRestoreJobRuntimeSettings = getValue( + discriminator, + '/customizeRestoreJobRuntimeSettings', ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, + if (customizeRestoreJobRuntimeSettings === 'no') { + commit( + 'wizard/model$delete', '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - value: {}, - force: true, - }) + } else if (customizeRestoreJobRuntimeSettings === 'yes') { + if ( + !valueExists( + model, + getValue, + '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', + ) + ) { + // set new value + commit('wizard/model$update', { + path: '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', + value: {}, + force: true, + }) + } } } -} -function showRuntimeForm({ discriminator, getValue, watchDependency }, value) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - watchDependency('discriminator#/customizeRestoreJobRuntimeSettings') - return customizeRestoreJobRuntimeSettings === value -} + function showRuntimeForm({ discriminator, getValue, watchDependency }, value) { + const customizeRestoreJobRuntimeSettings = getValue( + discriminator, + '/customizeRestoreJobRuntimeSettings', + ) + watchDependency('discriminator#/customizeRestoreJobRuntimeSettings') + return customizeRestoreJobRuntimeSettings === value + } -async function getImagePullSecrets({ getValue, model, watchDependency, axios, storeGet }) { - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') + async function getImagePullSecrets({ getValue, model, watchDependency, axios, storeGet }) { + const namespace = getValue(model, '/metadata/release/namespace') + watchDependency('model#/metadata/release/namespace') - let resources = await getNamespacedResourceList(axios, storeGet, { - namespace, - group: 'core', - version: 'v1', - resource: 'secrets', - }) + let resources = await getNamespacedResourceList(axios, storeGet, { + namespace, + group: 'core', + version: 'v1', + resource: 'secrets', + }) - resources = resources.filter((item) => { - const validType = ['kubernetes.io/dockerconfigjson'] - return validType.includes(item.type) - }) + resources = resources.filter((item) => { + const validType = ['kubernetes.io/dockerconfigjson'] + return validType.includes(item.type) + }) - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: { name: name }, - } - }) -} + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: { name: name }, + } + }) + } -function showBackupOptions({ discriminator, getValue, watchDependency }, backup) { - const backupEnabled = getValue(discriminator, '/backupEnabled') - if (backupEnabled) { - if (backup === 'alert') return true - else return false - } else { - if (backup === 'alert') return false - else return true + function showBackupOptions({ discriminator, getValue, watchDependency }, backup) { + const backupEnabled = getValue(discriminator, '/backupEnabled') + if (backupEnabled) { + if (backup === 'alert') return true + else return false + } else { + if (backup === 'alert') return false + else return true + } } -} -function isBlueprintOption({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/blueprintOptions') - const blueprintOptions = getValue(discriminator, '/blueprintOptions') - return blueprintOptions === value -} + function isBlueprintOption({ discriminator, getValue, watchDependency }, value) { + watchDependency('discriminator#/blueprintOptions') + const blueprintOptions = getValue(discriminator, '/blueprintOptions') + return blueprintOptions === value + } -function ifUsagePolicy({ discriminator, getValue, watchDependency, model }, value) { - watchDependency( - 'model#/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', - ) - const usagePolicy = getValue( - model, - '/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', - ) - return usagePolicy === value -} + function ifUsagePolicy({ discriminator, getValue, watchDependency, model }, value) { + watchDependency( + 'model#/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', + ) + const usagePolicy = getValue( + model, + '/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', + ) + return usagePolicy === value + } -async function getBlueprints({ getValue, model, setDiscriminatorValue, axios, storeGet }, backup) { - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const url = `clusters/${username}/${clusterName}/proxy/core.kubestash.com/v1alpha1/backupblueprints` + async function getBlueprints( + { getValue, model, setDiscriminatorValue, axios, storeGet }, + backup, + ) { + const username = storeGet('/route/params/user') + const clusterName = storeGet('/route/params/cluster') + const url = `clusters/${username}/${clusterName}/proxy/core.kubestash.com/v1alpha1/backupblueprints` - try { - const resp = await axios.get(url) - let data = resp.data.items - return data - } catch (e) { - console.log(e) + try { + const resp = await axios.get(url) + let data = resp.data.items + return data + } catch (e) { + console.log(e) + } } -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function isRancherManaged({ storeGet }) { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } -async function fetchNamespaces({ axios, storeGet }) { - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const group = storeGet('/route/params/group') - const version = storeGet('/route/params/version') - const resource = storeGet('/route/params/resource') + async function fetchNamespaces({ axios, storeGet }) { + const username = storeGet('/route/params/user') + const clusterName = storeGet('/route/params/cluster') + const group = storeGet('/route/params/group') + const version = storeGet('/route/params/version') + const resource = storeGet('/route/params/resource') - const url = `clusters/${username}/${clusterName}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews` + const url = `clusters/${username}/${clusterName}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews` - try { - const resp = await axios.post(url, { - _recurringCall: false, - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], - }, - }) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] + try { + const resp = await axios.post(url, { + _recurringCall: false, + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, + }) + if (resp.data?.status?.projects) { + const projects = resp.data?.status?.projects + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } + } catch (e) { + console.log(e) } - } catch (e) { - console.log(e) + return [] } - return [] -} -async function fetchNames( - { getValue, axios, storeGet, watchDependency, discriminator }, - version, - type, - discriminatorName, -) { - watchDependency(`discriminator#/${discriminatorName}`) - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const namespace = getValue(discriminator, `${discriminatorName}`) - const url = - type !== 'secrets' - ? `clusters/${username}/${clusterName}/proxy/storage.kubestash.com/${version}/namespaces/${namespace}/${type}` - : `clusters/${username}/${clusterName}/proxy/core/${version}/namespaces/${namespace}/${type}` - try { - if (namespace) { - const resp = await axios.get(url) - let data = resp.data.items - if (type === 'secrets') data = data.filter((ele) => !!ele.data['RESTIC_PASSWORD']) - data = data.map((ele) => ele.metadata.name) - return data + async function fetchNames( + { getValue, axios, storeGet, watchDependency, discriminator }, + version, + type, + discriminatorName, + ) { + watchDependency(`discriminator#/${discriminatorName}`) + const username = storeGet('/route/params/user') + const clusterName = storeGet('/route/params/cluster') + const namespace = getValue(discriminator, `${discriminatorName}`) + const url = + type !== 'secrets' + ? `clusters/${username}/${clusterName}/proxy/storage.kubestash.com/${version}/namespaces/${namespace}/${type}` + : `clusters/${username}/${clusterName}/proxy/core/${version}/namespaces/${namespace}/${type}` + try { + if (namespace) { + const resp = await axios.get(url) + let data = resp.data.items + if (type === 'secrets') data = data.filter((ele) => !!ele.data['RESTIC_PASSWORD']) + data = data.map((ele) => ele.metadata.name) + return data + } + } catch (e) { + console.log(e) } - } catch (e) { - console.log(e) + return [] } - return [] -} -// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// FOR Backup Configuration + // FOR Backup Configuration -// schedule backup + // schedule backup -function getBackupConfigsAndAnnotations(getValue, model) { - const stashAppscodeComBackupConfiguration = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration', - ) + function getBackupConfigsAndAnnotations(getValue, model) { + const stashAppscodeComBackupConfiguration = getValue( + model, + '/resources/stashAppscodeComBackupConfiguration', + ) - const coreKubestashComBackupConfiguration = getValue( - model, - '/resources/coreKubestashComBackupConfiguration', - ) - const kubeStashTarget = coreKubestashComBackupConfiguration?.spec?.target + const coreKubestashComBackupConfiguration = getValue( + model, + '/resources/coreKubestashComBackupConfiguration', + ) + const kubeStashTarget = coreKubestashComBackupConfiguration?.spec?.target - const mongoDB = getValue(model, '/resources/kubedbComMongoDB') - const mongoDbKind = mongoDB?.apiVersion?.split('/')?.at(0) + const mongoDB = getValue(model, '/resources/kubedbComMongoDB') + const mongoDbKind = mongoDB?.apiVersion?.split('/')?.at(0) - let isKubeStash = false - if ( - mongoDB?.kind === kubeStashTarget?.kind && - mongoDB?.metadata?.name === kubeStashTarget?.name && - mongoDB?.metadata?.namespace === kubeStashTarget?.namespace && - mongoDbKind === kubeStashTarget?.apiGroup - ) { - isKubeStash = true - } + let isKubeStash = false + if ( + mongoDB?.kind === kubeStashTarget?.kind && + mongoDB?.metadata?.name === kubeStashTarget?.name && + mongoDB?.metadata?.namespace === kubeStashTarget?.namespace && + mongoDbKind === kubeStashTarget?.apiGroup + ) { + isKubeStash = true + } - const kubedbComMongoDBAnnotations = - getValue(model, '/resources/kubedbComMongoDB/metadata/annotations') || {} + const kubedbComMongoDBAnnotations = + getValue(model, '/resources/kubedbComMongoDB/metadata/annotations') || {} - const isBluePrint = Object.keys(kubedbComMongoDBAnnotations).some( - (k) => - k === 'stash.appscode.com/backup-blueprint' || - k === 'stash.appscode.com/schedule' || - k.startsWith('params.stash.appscode.com/'), - ) + const isBluePrint = Object.keys(kubedbComMongoDBAnnotations).some( + (k) => + k === 'stash.appscode.com/backup-blueprint' || + k === 'stash.appscode.com/schedule' || + k.startsWith('params.stash.appscode.com/'), + ) - return { - stashAppscodeComBackupConfiguration, - isBluePrint, - isKubeStash, + return { + stashAppscodeComBackupConfiguration, + isBluePrint, + isKubeStash, + } + } + + function deleteKubeDbComMongDbAnnotation(getValue, model, commit) { + const annotations = getValue(model, '/resources/kubedbComMongoDB/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/kubedbComMongoDB/metadata/annotations', + value: filteredAnnotations, + }) } -} -function deleteKubeDbComMongDbAnnotation(getValue, model, commit) { - const annotations = getValue(model, '/resources/kubedbComMongoDB/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/kubedbComMongoDB/metadata/annotations', - value: filteredAnnotations, - }) -} + function addKubeDbComMongDbAnnotation(getValue, model, commit, key, value, force) { + const annotations = getValue(model, '/resources/kubedbComMongoDB/metadata/annotations') || {} -function addKubeDbComMongDbAnnotation(getValue, model, commit, key, value, force) { - const annotations = getValue(model, '/resources/kubedbComMongoDB/metadata/annotations') || {} + if (annotations[key] === undefined) { + annotations[key] = value + } else if (force) { + annotations[key] = value + } - if (annotations[key] === undefined) { - annotations[key] = value - } else if (force) { - annotations[key] = value + commit('wizard/model$update', { + path: '/resources/kubedbComMongoDB/metadata/annotations', + value: annotations, + force: true, + }) } - commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB/metadata/annotations', - value: annotations, - force: true, - }) -} - -function initScheduleBackupForEdit({ getValue, model, setDiscriminatorValue }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) + function initScheduleBackupForEdit() { + const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( + getValue, + model, + ) - initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) + initRepositoryChoiseForEdit() - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} + if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' + else return 'no' + } -function initScheduleBackup({ getValue, model }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) + function initScheduleBackup({ getValue, model }) { + const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( + getValue, + model, + ) - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} + if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' + else return 'no' + } -function onScheduleBackupChange({ commit, getValue, discriminator, model }) { - const scheduleBackup = getValue(discriminator, '/scheduleBackup') + 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 KubeDBComMongoDB annotation - deleteKubeDbComMongDbAnnotation(getValue, model, commit) - } else { - const { isBluePrint } = getBackupConfigsAndAnnotations(getValue, model) + if (scheduleBackup === 'no') { + // delete stashAppscodeComBackupConfiguration + commit('wizard/model$delete', '/resources/stashAppscodeComBackupConfiguration') + commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') + // delete annotation from KubeDBComMongoDB annotation + deleteKubeDbComMongDbAnnotation(getValue, model, commit) + } else { + const { isBluePrint } = getBackupConfigsAndAnnotations(getValue, model) - // create stashAppscodeComBackupConfiguration and initialize it if not exists + // create stashAppscodeComBackupConfiguration and initialize it if not exists - const dbName = getValue(model, '/metadata/release/name') + 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, - }) + 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, + }) + } } } -} -// backup form -function showBackupForm({ getValue, discriminator, watchDependency }) { - const scheduleBackup = getValue(discriminator, '/scheduleBackup') - watchDependency('discriminator#/scheduleBackup') - - if (scheduleBackup === 'yes') return true - else return false -} + // backup form + function showBackupForm() { + const scheduleBackup = getValue(discriminator, '/scheduleBackup') + // watchDependency('discriminator#/scheduleBackup') + if (scheduleBackup === 'yes') return true + else return false + } -// backup configuration form -function initalizeTargetReferenceName({ getValue, model, watchDependency }) { - const databaseName = getValue(model, '/metadata/release/name') - watchDependency('model#/metadata/release/name') + // backup configuration form + function initalizeTargetReferenceName({ getValue, model, watchDependency }) { + const databaseName = getValue(model, '/metadata/release/name') + watchDependency('model#/metadata/release/name') - return databaseName -} + return databaseName + } -// restore session repository -function setInitialRestoreSessionRepo({ getValue, model }) { - const value = getValue(model, 'resources/stashAppscodeComRepository_init_repo') - return value ? 'create' : 'select' -} + // restore session repository + function setInitialRestoreSessionRepo({ getValue, model }) { + const value = getValue(model, 'resources/stashAppscodeComRepository_init_repo') + return value ? 'create' : 'select' + } -// backup config repository -function initRepositoryChoise({ getValue, model }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) + // backup config repository + function initRepositoryChoise({ getValue, model }) { + const stashAppscodeComRepository_repo = getValue( + model, + '/resources/stashAppscodeComRepository_repo', + ) - if (stashAppscodeComRepository_repo) return 'create' - else return 'select' -} + if (stashAppscodeComRepository_repo) return 'create' + else return 'select' + } -function initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' - setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) + function initRepositoryChoiseForEdit() { + const stashAppscodeComRepository_repo = getValue( + model, + '/resources/stashAppscodeComRepository_repo', + ) + const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' + setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) + + return repoInitialSelectionStatus + } + + function onRepositoryChoiseChange({ getValue, discriminator, watchDependency, commit, model }) { + const repositoryChoise = getValue(discriminator, '/repositoryChoise') + watchDependency('discriminator#/repositoryChoise') + + if (repositoryChoise === 'select') { + // delete the stashAppscodeComRepository_repo + commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') + } else if (repositoryChoise === 'create') { + // create new stashAppscodeComRepository_repo + if (!valueExists(model, getValue, '/resources/stashAppscodeComRepository_repo')) { + commit('wizard/model$update', { + path: '/resources/stashAppscodeComRepository_repo', + value: stashAppscodeComRepository_repo, + }) + const repositoryName = `${getValue(model, '/metadata/release/name')}-repo` + // set this name in stashAppscodeComRestoreSession_init + commit('wizard/model$update', { + path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', + value: repositoryName, + }) + } + } + } - return repoInitialSelectionStatus -} + function onRepositoryNameChange({ getValue, model, commit }) { + const repositoryName = getValue( + model, + 'resources/stashAppscodeComRepository_repo/metadata/name', + ) + // set this name in stashAppscodeComRestoreSession_init + commit('wizard/model$update', { + path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', + value: repositoryName, + }) + } -function onRepositoryChoiseChange({ getValue, discriminator, watchDependency, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') + function onInputChange( + { getValue, discriminator, watchDependency, commit, model }, + modelPath, + field, + subfield, + discriminatorName, + ) { + const value = getValue(discriminator, `/${discriminatorName}`) + const backends = getValue(model, modelPath) || [] + if (field !== 'encryptionSecret') backends[0][field][subfield] = value + else backends[0]['repositories'][0][field][subfield] = value + commit('wizard/model$update', { + path: modelPath, + value: backends, + }) + } + function setFileValueFromStash({ getValue, commit, model }, modelPath, field, subfield, value) { + const backends = getValue(model, modelPath) + if (field !== 'encryptionSecret') backends[0][field][subfield] = value + else backends[0]['repositories'][0][field][subfield] = value + commit('wizard/model$update', { + path: modelPath, + value: backends, + }) + } - if (repositoryChoise === 'select') { - // delete the stashAppscodeComRepository_repo - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') - } else if (repositoryChoise === 'create') { - // create new stashAppscodeComRepository_repo - if (!valueExists(model, getValue, '/resources/stashAppscodeComRepository_repo')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRepository_repo', - value: stashAppscodeComRepository_repo, - }) - const repositoryName = `${getValue(model, '/metadata/release/name')}-repo` - // set this name in stashAppscodeComRestoreSession_init + 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: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, + path: modelPath, + value: session, + force: true, }) } } -} - -function onRepositoryNameChange({ getValue, model, commit }) { - const repositoryName = getValue(model, 'resources/stashAppscodeComRepository_repo/metadata/name') - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) -} - -function onInputChange( - { getValue, discriminator, watchDependency, commit, model }, - modelPath, - field, - subfield, - discriminatorName, -) { - const value = getValue(discriminator, `/${discriminatorName}`) - const backends = getValue(model, modelPath) || [] - if (field !== 'encryptionSecret') backends[0][field][subfield] = value - else backends[0]['repositories'][0][field][subfield] = value - commit('wizard/model$update', { - path: modelPath, - value: backends, - }) -} -function setFileValueFromStash({ getValue, commit, model }, modelPath, field, subfield, value) { - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') backends[0][field][subfield] = value - else backends[0]['repositories'][0][field][subfield] = value - commit('wizard/model$update', { - path: modelPath, - value: backends, - }) -} -function onInputChangeSchedule( - { getValue, discriminator, commit, model }, - modelPath, - discriminatorName, -) { - const value = getValue(discriminator, `/${discriminatorName}`) - const session = getValue(model, modelPath) || [] - if (session.length) { + function setInitSchedule( + { getValue, discriminator, watchDependency, commit, model }, + modelPath, + value, + ) { + const session = getValue(model, modelPath) session[0].scheduler.schedule = value commit('wizard/model$update', { path: modelPath, value: session, - force: true, }) } -} -function setInitSchedule( - { getValue, discriminator, watchDependency, commit, model }, - modelPath, - value, -) { - const session = getValue(model, modelPath) - session[0].scheduler.schedule = value - commit('wizard/model$update', { - path: modelPath, - value: session, - }) -} - -function getDefault({ getValue, model }, modelPath, field, subfield) { - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') return backends[0][field][subfield] - else { - return backends[0]['repositories'][0][field][subfield] + function getDefault({ getValue, model }, modelPath, field, subfield) { + const backends = getValue(model, modelPath) + if (field !== 'encryptionSecret') return backends[0][field][subfield] + else { + return backends[0]['repositories'][0][field][subfield] + } } -} -function getDefaultSchedule({ getValue, model, watchDependency }, modelPath) { - watchDependency('discriminator#/config') - const session = getValue(model, modelPath) - return session?.length ? session[0]?.scheduler.schedule : '' -} + 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 : '' + } + + // restructure backup modal + + 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/kubedbComMongoDB') + initialDbMetadata = objectCopy(dbResource.metadata) + initialArchiver = dbResource.spec?.archiver ? objectCopy(dbResource.spec?.archiver) : undefined -// restructure backup modal - -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({ storeGet, axios, getValue, model, setDiscriminatorValue }) { - // 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/kubedbComMongoDB') - 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}` + // 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) - const archAnnotation = resp.data?.metadata?.annotations - const annotationKeyToFind = `${resource}.${group}/archiver` - if (archAnnotation[annotationKeyToFind]) { - isArchiverAvailable = true - archiverObjectToCommit = { - ref: { - name: archAnnotation[annotationKeyToFind], - namespace: 'kubedb', - }, - } - } + + valuesFromWizard = objectCopy(resp.data?.resources?.coreKubestashComBackupConfiguration) || {} } 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 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 without metadata name if not found with metadata name - if (!config) - config = configs?.find( + // 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, ) - // set backup switch here - isBackupOn = !!config + // 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 initial data from stash-presets - const stashPreset = storeGet('/backup/stashPresets') - if (stashPreset) { - const { retentionPolicy, encryptionSecret, schedule, storageRef } = stashPreset + // set backup switch here + isBackupOn = !!config - const tempBackends = valuesFromWizard.spec?.backends - tempBackends[0]['storageRef'] = storageRef - tempBackends[0]['retentionPolicy'] = retentionPolicy - valuesFromWizard.spec['backends'] = tempBackends + // set initial data from stash-presets + const stashPreset = storeGet('/backup/stashPresets') + if (stashPreset) { + const { retentionPolicy, encryptionSecret, schedule, storageRef } = stashPreset - 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}` + const tempBackends = valuesFromWizard.spec?.backends + tempBackends[0]['storageRef'] = storageRef + tempBackends[0]['retentionPolicy'] = retentionPolicy + valuesFromWizard.spec['backends'] = tempBackends - tempSessions[0]['repositories'] = tempRepositories - tempSessions[0]['scheduler']['schedule'] = schedule - valuesFromWizard.spec['sessions'] = tempSessions - } + 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}` - 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, - } + tempSessions[0]['repositories'] = tempRepositories + tempSessions[0]['scheduler']['schedule'] = schedule + valuesFromWizard.spec['sessions'] = tempSessions + } - setDiscriminatorValue('isBackupDataLoaded', true) -} + 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, + } -function isBackupDataLoadedTrue({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/isBackupDataLoaded') - return !!getValue(discriminator, '/isBackupDataLoaded') -} + setDiscriminatorValue('isBackupDataLoaded', true) + } -async function setBackupType() { - return 'BackupConfig' -} + function isBackupDataLoadedTrue() { + // watchDependency('discriminator#/isBackupDataLoaded') + return !!getValue(discriminator, '/isBackupDataLoaded') + } -async function getTypes() { - const arr = [ - { - description: 'Create, Delete or Modify BackupConfig', - text: 'BackupConfig', - value: 'BackupConfig', - }, - { - description: 'Enable/Disable BackupBlueprint', - text: 'BackupBlueprint', - value: 'BackupBlueprint', - }, - ] + function setBackupType() { + return 'BackupConfig' + } - if ((dbResource?.spec?.replicaSet || dbResource?.spec?.shardTopology) && isArchiverAvailable) { - arr.push({ - description: 'Enable/Disable Archiver', - text: 'Archiver', - value: 'Archiver', - }) + 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 } - return arr -} -function onBackupTypeChange({ commit, getValue, discriminator }) { - const type = getValue(discriminator, '/backupType') - commit('wizard/model$update', { - path: '/backupType', - value: type, - force: true, - }) - if (!isBackupOnModel) { - commit('wizard/model$delete', '/resources/coreKubestashComBackupConfiguration') - } else { + function onBackupTypeChange() { + const type = getValue(discriminator, '/backupType') commit('wizard/model$update', { - path: '/resources/coreKubestashComBackupConfiguration', - value: objectCopy(initialModel), + 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/kubedbComMongoDB', + value: objectCopy(dbResource), force: true, }) } - commit('wizard/model$delete', '/context') - commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB', - value: objectCopy(dbResource), - force: true, - }) -} -function isBackupType({ watchDependency, getValue, discriminator }, type) { - watchDependency('discriminator#/backupType') - const selectedType = getValue(discriminator, '/backupType') + function isBackupType(type) { + // watchDependency('discriminator#/backupType') + const selectedType = getValue(discriminator, '/backupType') - return selectedType === type -} + return selectedType === type + } -function setBlueprintSwitch() { - const annotations = initialDbMetadata?.annotations + function setBlueprintSwitch() { + const annotations = initialDbMetadata?.annotations - return !!( - annotations['blueprint.kubestash.com/name'] && annotations['blueprint.kubestash.com/namespace'] - ) -} + return !!( + annotations['blueprint.kubestash.com/name'] && + annotations['blueprint.kubestash.com/namespace'] + ) + } -function onBlueprintChange({ getValue, discriminator, commit, model, storeGet }) { - const blueprintSwitch = getValue(discriminator, '/blueprintEnabled') - if (blueprintSwitch) addLabelAnnotation(commit, storeGet, 'annotations') - else deleteLabelAnnotation(commit, 'annotations') -} + function onBlueprintChange() { + const blueprintSwitch = getValue(discriminator, '/blueprintEnabled') + if (blueprintSwitch) addLabelAnnotation(commit, storeGet, 'annotations') + else deleteLabelAnnotation(commit, 'annotations') + } -function setArchiverSwitch() { - const archiver = dbResource?.spec?.archiver - return !!archiver -} + function setArchiverSwitch() { + const archiver = dbResource?.spec?.archiver + return !!archiver + } + + function onArchiverChange() { + const archiverSwitch = getValue(discriminator, '/archiverEnabled') + const path = 'resources/kubedbComMongoDB/spec/archiver' + if (archiverSwitch) { + commit('wizard/model$update', { + path: path, + value: initialArchiver ? initialArchiver : archiverObjectToCommit, + }) + } else { + commit('wizard/model$delete', path) + } + } + + function addLabelAnnotation(commit, storeGet, 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' + } -function onArchiverChange({ getValue, discriminator, commit, model, storeGet }) { - const archiverSwitch = getValue(discriminator, '/archiverEnabled') - const path = 'resources/kubedbComMongoDB/spec/archiver' - if (archiverSwitch) { commit('wizard/model$update', { - path: path, - value: initialArchiver ? initialArchiver : archiverObjectToCommit, + path: `/resources/kubedbComMongoDB/metadata/${type}`, + value: obj, + force: true, }) - } else { - commit('wizard/model$delete', path) } -} -function addLabelAnnotation(commit, storeGet, type) { - const obj = objectCopy(initialDbMetadata[type]) + function deleteLabelAnnotation(commit, type) { + const obj = 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' - } + 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/kubedbComMongoDB/metadata/${type}`, - value: obj, - force: true, - }) -} + commit('wizard/model$update', { + path: `/resources/kubedbComMongoDB/metadata/${type}`, + value: obj, + force: true, + }) + } -function deleteLabelAnnotation(commit, type) { - const obj = initialDbMetadata[type] + function getContext() { + if (isBackupOn) return ['Create', 'Delete', 'Modify'] + return ['Create'] + } - if (type === 'annotations') { - delete obj['blueprint.kubestash.com/name'] - delete obj['blueprint.kubestash.com/namespace'] - } else delete obj['kubedb.com/archiver'] + 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) + } - commit('wizard/model$update', { - path: `/resources/kubedbComMongoDB/metadata/${type}`, - value: obj, - force: true, - }) -} + 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 getContext() { - if (isBackupOn) return ['Create', 'Delete', 'Modify'] - return ['Create'] -} + function onConfigChange() { + const configName = getValue(discriminator, '/config') + const configs = objectCopy(backupConfigurationsFromStore) + const configDetails = configs?.find((item) => item?.metadata?.name === configName) -function onContextChange({ getValue, discriminator, commit, model }) { - 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, + value: configDetails, force: true, }) } -} -function getConfigList({ storeGet }) { - 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 showPause() { + // watchDependency('discriminator#/backupConfigContext') + // watchDependency('discriminator#/config') + const contex = getValue(discriminator, '/backupConfigContext') + const configName = getValue(discriminator, '/config') + return !!configName && contex === 'Modify' + } -function onConfigChange({ getValue, discriminator, commit, storeGet, model }) { - const configName = getValue(discriminator, '/config') - const configs = objectCopy(backupConfigurationsFromStore) - const configDetails = configs?.find((item) => item?.metadata?.name === configName) + 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 + } - commit('wizard/model$update', { - path: '/resources/coreKubestashComBackupConfiguration', - value: configDetails, - force: true, - }) -} + function showConfigList() { + // watchDependency('discriminator#/backupConfigContext') + const contex = getValue(discriminator, '/backupConfigContext') + return contex === 'Modify' || contex === 'Delete' + } -function showPause({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/backupConfigContext') - watchDependency('discriminator#/config') - const contex = getValue(discriminator, '/backupConfigContext') - const configName = getValue(discriminator, '/config') - return !!configName && contex === 'Modify' -} + 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 showConfigList({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/backupConfigContext') - const contex = getValue(discriminator, '/backupConfigContext') - return contex === 'Modify' || contex === 'Delete' -} + function getNamespaceArray() { + return namespaceList + } -function showSchedule({ watchDependency, getValue, discriminator }) { - 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 -} + // backup blueprint form + function getMongoAnnotations(getValue, model) { + const annotations = getValue(model, '/resources/kubedbComMongoDB/metadata/annotations') + return { ...annotations } || {} + } -function getNamespaceArray() { - return namespaceList -} + function initFromAnnotationValue({ getValue, model }, key) { + const annotations = getMongoAnnotations(getValue, model) + return annotations[key] + } -// backup blueprint form -function getMongoAnnotations(getValue, model) { - const annotations = getValue(model, '/resources/kubedbComMongoDB/metadata/annotations') - return { ...annotations } || {} -} + function onBackupBlueprintNameChange({ getValue, discriminator, commit, model }) { + const backupBlueprintName = getValue(discriminator, '/backupBlueprintName') + addKubeDbComMongDbAnnotation( + getValue, + model, + commit, + 'stash.appscode.com/backup-blueprint', + backupBlueprintName, + true, + ) + } -function initFromAnnotationValue({ getValue, model }, key) { - const annotations = getMongoAnnotations(getValue, model) - return annotations[key] -} + function onBackupBlueprintScheduleChange({ getValue, discriminator, commit, model }) { + const backupBlueprintSchedule = getValue(discriminator, '/schedule') + addKubeDbComMongDbAnnotation( + getValue, + model, + commit, + 'stash.appscode.com/schedule', + backupBlueprintSchedule, + true, + ) + } -function onBackupBlueprintNameChange({ getValue, discriminator, commit, model }) { - const backupBlueprintName = getValue(discriminator, '/backupBlueprintName') - addKubeDbComMongDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/backup-blueprint', - backupBlueprintName, - true, - ) -} + function initFromAnnotationKeyValue({ getValue, model }, prefix) { + const annotations = getMongoAnnotations(getValue, model) + const newOb = {} + Object.keys(annotations).forEach((key) => { + if (key.startsWith(prefix)) { + const newKey = key.replace(prefix, '') + newOb[newKey] = annotations[key] + } + }) + return newOb + } -function onBackupBlueprintScheduleChange({ getValue, discriminator, commit, model }) { - const backupBlueprintSchedule = getValue(discriminator, '/schedule') - addKubeDbComMongDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/schedule', - backupBlueprintSchedule, - true, - ) -} + function onTaskParametersChange({ getValue, discriminator, model, commit }) { + const taskParameters = getValue(discriminator, '/taskParameters') -function initFromAnnotationKeyValue({ getValue, model }, prefix) { - const annotations = getMongoAnnotations(getValue, model) - const newOb = {} - Object.keys(annotations).forEach((key) => { - if (key.startsWith(prefix)) { - const newKey = key.replace(prefix, '') - newOb[newKey] = annotations[key] - } - }) - return newOb -} + const taskParamterKeys = Object.keys(taskParameters).map( + (tp) => `params.stash.appscode.com/${tp}`, + ) + const oldAnnotations = getValue(model, '/resources/kubedbComMongoDB/metadata/annotations') || {} + const newAnnotations = {} -function onTaskParametersChange({ getValue, discriminator, model, commit }) { - const taskParameters = getValue(discriminator, '/taskParameters') + const filteredAnnotationKeys = Object.keys(oldAnnotations).filter( + (key) => !taskParamterKeys.includes(key) && !key.startsWith('params.stash.appscode.com/'), + ) - const taskParamterKeys = Object.keys(taskParameters).map( - (tp) => `params.stash.appscode.com/${tp}`, - ) - const oldAnnotations = getValue(model, '/resources/kubedbComMongoDB/metadata/annotations') || {} - const newAnnotations = {} + filteredAnnotationKeys.forEach((key) => { + newAnnotations[key] = oldAnnotations[key] + }) - const filteredAnnotationKeys = Object.keys(oldAnnotations).filter( - (key) => !taskParamterKeys.includes(key) && !key.startsWith('params.stash.appscode.com/'), - ) + Object.keys(taskParameters).forEach((tpk) => { + newAnnotations[`params.stash.appscode.com/${tpk}`] = taskParameters[tpk] + }) + + commit('wizard/model$update', { + path: '/resources/kubedbComMongoDB/metadata/annotations', + value: newAnnotations, + }) + } + + function isValueExistInModel(path) { + const modelValue = getValue(model, path) + return !!modelValue + } + + function onNamespaceChange({ commit, model, getValue }) { + const namespace = getValue(model, '/metadata/release/namespace') + const agent = getValue(model, '/resources/kubedbComMongoDB/spec/monitor/agent') + if (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + value: [namespace], + force: true, + }) + } + } + + function onLabelChange({ commit, model, getValue }) { + const labels = getValue(model, '/resources/kubedbComMongoDB/spec/metadata/labels') - filteredAnnotationKeys.forEach((key) => { - newAnnotations[key] = oldAnnotations[key] - }) + const agent = getValue(model, '/resources/kubedbComMongoDB/spec/monitor/agent') - Object.keys(taskParameters).forEach((tpk) => { - newAnnotations[`params.stash.appscode.com/${tpk}`] = taskParameters[tpk] - }) + if (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', + value: labels, + force: true, + }) + } + } - commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB/metadata/annotations', - value: newAnnotations, - }) -} + function onNameChange({ commit, model, getValue }) { + const dbName = getValue(model, '/metadata/release/name') -function isValueExistInModel({ model, getValue }, path) { - const modelValue = getValue(model, path) - return !!modelValue -} + const agent = getValue(model, '/resources/kubedbComMongoDB/spec/monitor/agent') -function onNamespaceChange({ commit, model, getValue }) { - const namespace = getValue(model, '/metadata/release/namespace') - const agent = getValue(model, '/resources/kubedbComMongoDB/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', - value: [namespace], - force: true, - }) - } -} + const labels = getValue(model, '/resources/kubedbComMongoDB/spec/metadata/labels') -function onLabelChange({ commit, model, getValue }) { - const labels = getValue(model, '/resources/kubedbComMongoDB/spec/metadata/labels') + if (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', + value: labels, + force: true, + }) + } - const agent = getValue(model, '/resources/kubedbComMongoDB/spec/monitor/agent') + const scheduleBackup = getValue(model, '/resources/stashAppscodeComBackupConfiguration') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) - } -} + if (scheduleBackup) { + commit('wizard/model$update', { + path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', + value: dbName, + force: true, + }) + const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_repo') + if (creatingNewRepo) { + commit('wizard/model$update', { + path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', + value: `${dbName}-repo`, + force: true, + }) + } + } -function onNameChange({ commit, model, getValue }) { - const dbName = getValue(model, '/metadata/release/name') + const prePopulateDatabase = getValue(model, '/resources/stashAppscodeComRestoreSession_init') - const agent = getValue(model, '/resources/kubedbComMongoDB/spec/monitor/agent') + if (prePopulateDatabase) { + commit('wizard/model$update', { + path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', + value: dbName, + force: true, + }) + const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_init_repo') + if (creatingNewRepo) { + commit('wizard/model$update', { + path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', + value: `${dbName}-init-repo`, + force: true, + }) + } + } - const labels = getValue(model, '/resources/kubedbComMongoDB/spec/metadata/labels') + // to reset configSecret name field + const hasSecretConfig = getValue(model, '/resources/secret_config') + if (hasSecretConfig) { + commit('wizard/model$update', { + path: '/resources/kubedbComMongoDB/spec/configSecret/name', + value: `${dbName}-config`, + force: true, + }) + } - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) - } + // to reset shard configSecret name field + const hasSecretShardConfig = getValue(model, '/resources/secret_shard_config') + if (hasSecretShardConfig) { + commit('wizard/model$update', { + path: '/resources/kubedbComMongoDB/spec/shardTopology/shard/configSecret/name', + value: `${dbName}-shard-config`, + force: true, + }) + } - const scheduleBackup = getValue(model, '/resources/stashAppscodeComBackupConfiguration') + // to reset shard configSecret name field + const hasSecretConfigServerConfig = getValue(model, '/resources/secret_configserver_config') + if (hasSecretConfigServerConfig) { + commit('wizard/model$update', { + path: '/resources/kubedbComMongoDB/spec/shardTopology/configServer/configSecret/name', + value: `${dbName}-configserver-config`, + force: true, + }) + } - if (scheduleBackup) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_repo') - if (creatingNewRepo) { + // to reset mongos configSecret name field + const hasSecretMongosConfig = getValue(model, '/resources/secret_mongos_config') + if (hasSecretMongosConfig) { commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: `${dbName}-repo`, + path: '/resources/kubedbComMongoDB/spec/shardTopology/mongos/configSecret/name', + value: `${dbName}-mongos-config`, force: true, }) } } - const prePopulateDatabase = getValue(model, '/resources/stashAppscodeComRestoreSession_init') + function returnFalse() { + return false + } - if (prePopulateDatabase) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_init_repo') - if (creatingNewRepo) { + function onAgentChange() { + const agent = getValue(model, '/resources/kubedbComMongoDB/spec/monitor/agent') + if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: `${dbName}-init-repo`, + path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', + value: [], force: true, }) + + onNamespaceChange({ commit, model, getValue }) + onLabelChange({ commit, model, getValue }) + } else { + commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') } } - // to reset configSecret name field - const hasSecretConfig = getValue(model, '/resources/secret_config') - if (hasSecretConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB/spec/configSecret/name', - value: `${dbName}-config`, - force: true, - }) - } + /************************************* Database Secret Section ********************************************/ - // to reset shard configSecret name field - const hasSecretShardConfig = getValue(model, '/resources/secret_shard_config') - if (hasSecretShardConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB/spec/shardTopology/shard/configSecret/name', - value: `${dbName}-shard-config`, - force: true, - }) + function getCreateAuthSecret({ model, getValue }) { + const authSecret = getValue(model, '/resources/kubedbComMongoDB/spec/authSecret') + + return !authSecret } - // to reset shard configSecret name field - const hasSecretConfigServerConfig = getValue(model, '/resources/secret_configserver_config') - if (hasSecretConfigServerConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB/spec/shardTopology/configServer/configSecret/name', - value: `${dbName}-configserver-config`, - force: true, - }) + function showExistingSecretSection({ getValue, watchDependency, discriminator }) { + watchDependency('discriminator#/createAuthSecret') + + const hasAuthSecretName = getValue(discriminator, '/createAuthSecret') + return !hasAuthSecretName } - // to reset mongos configSecret name field - const hasSecretMongosConfig = getValue(model, '/resources/secret_mongos_config') - if (hasSecretMongosConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB/spec/shardTopology/mongos/configSecret/name', - value: `${dbName}-mongos-config`, - force: true, + function showPasswordSection({ getValue, watchDependency, discriminator }) { + return !showExistingSecretSection({ + getValue, + watchDependency, + discriminator, }) } -} -function returnFalse() { - return false -} + function setAuthSecretPassword({ model, getValue }) { + const encodedPassword = getValue(model, '/resources/secret_auth/data/password') + return encodedPassword ? decodePassword({}, encodedPassword) : '' + } -function onAgentChange({ commit, model, getValue }) { - const agent = getValue(model, '/resources/kubedbComMongoDB/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', - value: [], - force: true, - }) + function onAuthSecretPasswordChange({ getValue, discriminator, commit }) { + const stringPassword = getValue(discriminator, '/password') - onNamespaceChange({ commit, model, getValue }) - onLabelChange({ commit, model, getValue }) - } else { - commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') + if (stringPassword) { + commit('wizard/model$update', { + path: '/resources/secret_auth/data/password', + value: encodePassword({}, stringPassword), + force: true, + }) + commit('wizard/model$update', { + path: '/resources/secret_auth/data/username', + value: encodePassword({}, 'root'), + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/secret_auth') + } } -} -/************************************* Database Secret Section ********************************************/ - -function getCreateAuthSecret({ model, getValue }) { - const authSecret = getValue(model, '/resources/kubedbComMongoDB/spec/authSecret') + // eslint-disable-next-line no-empty-pattern + function encodePassword({}, value) { + return btoa(value) + } - return !authSecret -} + // eslint-disable-next-line no-empty-pattern + function decodePassword({}, value) { + return atob(value) + } -function showExistingSecretSection({ getValue, watchDependency, discriminator }) { - watchDependency('discriminator#/createAuthSecret') + function onCreateAuthSecretChange({ discriminator, getValue, commit }) { + const createAuthSecret = getValue(discriminator, '/createAuthSecret') + if (createAuthSecret) { + commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/authSecret') + } else if (createAuthSecret === false) { + commit('wizard/model$delete', '/resources/secret_auth') + } + } - const hasAuthSecretName = getValue(discriminator, '/createAuthSecret') - return !hasAuthSecretName -} + 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') -function showPasswordSection({ getValue, watchDependency, discriminator }) { - return !showExistingSecretSection({ - getValue, - watchDependency, - discriminator, - }) -} + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }, + ) -function setAuthSecretPassword({ model, getValue }) { - const encodedPassword = getValue(model, '/resources/secret_auth/data/password') - return encodedPassword ? decodePassword({}, encodedPassword) : '' -} + const secrets = (resp && resp.data && resp.data.items) || [] -function onAuthSecretPasswordChange({ getValue, discriminator, commit }) { - const stringPassword = getValue(discriminator, '/password') + const filteredSecrets = secrets.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) - if (stringPassword) { - commit('wizard/model$update', { - path: '/resources/secret_auth/data/password', - value: encodePassword({}, stringPassword), - force: true, - }) - commit('wizard/model$update', { - path: '/resources/secret_auth/data/username', - value: encodePassword({}, 'root'), - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/secret_auth') + 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 [] + } } -} - -// eslint-disable-next-line no-empty-pattern -function encodePassword({}, value) { - return btoa(value) -} -// eslint-disable-next-line no-empty-pattern -function decodePassword({}, value) { - return atob(value) -} + 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/kubedbComMongoDB/spec/monitor/prometheus/exporter/env/${index}/valueFrom/secretKeyRef/name`, + ) -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/authSecret') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/resources/secret_auth') - } -} + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/secretKeyRef/name') -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') + if (!secretName) return [] - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets/${secretName}`, + ) - const secrets = (resp && resp.data && resp.data.items) || [] + const secret = (resp && resp.data && resp.data.data) || {} - const filteredSecrets = secrets.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) + const secretKeys = Object.keys(secret).map((item) => ({ + text: item, + value: item, + })) - 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 [] + return secretKeys + } catch (e) { + console.log(e) + return [] + } } -} -//////////////////////////////////////// Service Monitor ////////////////////////////////////////////////////// + //////////////////////////////////////// Service Monitor ////////////////////////////////////////////////////// -//////////////////// service monitor /////////////////// + //////////////////// service monitor /////////////////// -function isEqualToServiceMonitorType({ rootModel, watchDependency }, value) { - watchDependency('rootModel#/spec/type') - return rootModel && rootModel.spec && rootModel.spec.type === value -} + function isEqualToServiceMonitorType({ rootModel, watchDependency }, value) { + watchDependency('rootModel#/spec/type') + return rootModel && rootModel.spec && rootModel.spec.type === value + } -//////////////////// custom config ///////////////// -function onConfigurationSourceChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSource') - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_config') - } else { - const value = getValue(model, '/resources/secret_config') - if (!value) { + //////////////////// custom config ///////////////// + function onConfigurationSourceChange({ getValue, discriminator, commit, model }) { + const configurationSource = getValue(discriminator, '/configurationSource') + if (configurationSource === 'use-existing-config') { + commit('wizard/model$delete', '/resources/secret_config') + } else { + const value = getValue(model, '/resources/secret_config') + if (!value) { + commit('wizard/model$update', { + path: '/resources/secret_config', + value: {}, + force: true, + }) + } + const configSecretName = `${getValue(model, '/metadata/release/name')}-config` commit('wizard/model$update', { - path: '/resources/secret_config', - value: {}, + path: '/resources/kubedbComMongoDB/spec/configSecret/name', + value: configSecretName, force: true, }) } + } + + function onConfigurationChange({ getValue, commit, discriminator, model }) { + const value = getValue(discriminator, '/configuration') + commit('wizard/model$update', { + path: '/resources/secret_config/stringData/mongod.conf', + value: value, + force: true, + }) const configSecretName = `${getValue(model, '/metadata/release/name')}-config` commit('wizard/model$update', { path: '/resources/kubedbComMongoDB/spec/configSecret/name', @@ -2200,976 +2389,1105 @@ function onConfigurationSourceChange({ getValue, discriminator, commit, model }) force: true, }) } -} - -function onConfigurationChange({ getValue, commit, discriminator, model }) { - const value = getValue(discriminator, '/configuration') - commit('wizard/model$update', { - path: '/resources/secret_config/stringData/mongod.conf', - value: value, - force: true, - }) - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB/spec/configSecret/name', - value: configSecretName, - force: true, - }) -} -function setConfigurationSource({ model, getValue }) { - const modelValue = getValue(model, '/resources/secret_config') - if (modelValue) { - return 'create-new-config' + function setConfigurationSource({ model, getValue }) { + const modelValue = getValue(model, '/resources/secret_config') + if (modelValue) { + return 'create-new-config' + } + return 'use-existing-config' } - return 'use-existing-config' -} - -function setSecretConfigNamespace({ getValue, model, watchDependency }) { - watchDependency('model#/metadata/release/namespace') - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} - -//////////////////// custom config for sharded topology ///////////////// -function setConfigurationSourceShard({ model, getValue, discriminator }) { - const src = getValue(discriminator, '/configurationSourceShard') - if (src) return src - const value = getValue(model, '/resources/secret_shard_config') - return value ? 'create-new-config' : 'use-existing-config' -} + function setSecretConfigNamespace({ getValue, model, watchDependency }) { + watchDependency('model#/metadata/release/namespace') + const namespace = getValue(model, '/metadata/release/namespace') + return namespace + } -function setConfigurationSourceConfigServer({ model, getValue, discriminator }) { - const src = getValue(discriminator, '/configurationSourceConfigServer') - if (src) return src - const value = getValue(model, '/resources/secret_configserver_config') - return value ? 'create-new-config' : 'use-existing-config' -} + //////////////////// custom config for sharded topology ///////////////// -function setConfigurationSourceMongos({ model, getValue, discriminator }) { - const src = getValue(discriminator, '/configurationSourceMongos') - if (src) return src - const value = getValue(model, '/resources/secret_mongos_config') - return value ? 'create-new-config' : 'use-existing-config' -} + function setConfigurationSourceShard({ model, getValue, discriminator }) { + const src = getValue(discriminator, '/configurationSourceShard') + if (src) return src + const value = getValue(model, '/resources/secret_shard_config') + return value ? 'create-new-config' : 'use-existing-config' + } -function isSchemaOf(schema) { - if (schema === 'discriminator#/configurationSourceShard') { - return 'shard' - } else if (schema === 'discriminator#/configurationSourceConfigServer') { - return 'configserver' - } else { - return 'mongos' + function setConfigurationSourceConfigServer({ model, getValue, discriminator }) { + const src = getValue(discriminator, '/configurationSourceConfigServer') + if (src) return src + const value = getValue(model, '/resources/secret_configserver_config') + return value ? 'create-new-config' : 'use-existing-config' } -} -function disableConfigSourceOption({ - itemCtx, - discriminator, - getValue, - watchDependency, - elementUi, -}) { - watchDependency('discriminator#/configurationSourceShard') - watchDependency('discriminator#/configurationSourceConfigServer') - watchDependency('discriminator#/configurationSourceMongos') - const configSrcShard = getValue(discriminator, '/configurationSourceShard') - const configSrcConfigServer = getValue(discriminator, '/configurationSourceConfigServer') - const configSrcMongos = getValue(discriminator, '/configurationSourceMongos') - if ( - itemCtx.value !== 'use-existing-config' && - itemCtx.value !== 'create-new-config' && - (configSrcShard === `same-as-${isSchemaOf(elementUi.schema.$ref)}-config-secret` || - configSrcConfigServer === `same-as-${isSchemaOf(elementUi.schema.$ref)}-config-secret` || - configSrcMongos === `same-as-${isSchemaOf(elementUi.schema.$ref)}-config-secret`) - ) { - return true + function setConfigurationSourceMongos({ model, getValue, discriminator }) { + const src = getValue(discriminator, '/configurationSourceMongos') + if (src) return src + const value = getValue(model, '/resources/secret_mongos_config') + return value ? 'create-new-config' : 'use-existing-config' } - if ( - itemCtx.value === 'same-as-shard-config-secret' && - configSrcShard !== 'use-existing-config' && - configSrcShard !== 'create-new-config' - ) { - return true + + function isSchemaOf(schema) { + if (schema === 'discriminator#/configurationSourceShard') { + return 'shard' + } else if (schema === 'discriminator#/configurationSourceConfigServer') { + return 'configserver' + } else { + return 'mongos' + } } - if ( - itemCtx.value === 'same-as-configserver-config-secret' && - configSrcConfigServer !== 'use-existing-config' && - configSrcConfigServer !== 'create-new-config' - ) { - return true + + function disableConfigSourceOption({ + itemCtx, + discriminator, + getValue, + watchDependency, + elementUi, + }) { + watchDependency('discriminator#/configurationSourceShard') + watchDependency('discriminator#/configurationSourceConfigServer') + watchDependency('discriminator#/configurationSourceMongos') + const configSrcShard = getValue(discriminator, '/configurationSourceShard') + const configSrcConfigServer = getValue(discriminator, '/configurationSourceConfigServer') + const configSrcMongos = getValue(discriminator, '/configurationSourceMongos') + if ( + itemCtx.value !== 'use-existing-config' && + itemCtx.value !== 'create-new-config' && + (configSrcShard === `same-as-${isSchemaOf(elementUi.schema.$ref)}-config-secret` || + configSrcConfigServer === `same-as-${isSchemaOf(elementUi.schema.$ref)}-config-secret` || + configSrcMongos === `same-as-${isSchemaOf(elementUi.schema.$ref)}-config-secret`) + ) { + return true + } + if ( + itemCtx.value === 'same-as-shard-config-secret' && + configSrcShard !== 'use-existing-config' && + configSrcShard !== 'create-new-config' + ) { + return true + } + if ( + itemCtx.value === 'same-as-configserver-config-secret' && + configSrcConfigServer !== 'use-existing-config' && + configSrcConfigServer !== 'create-new-config' + ) { + return true + } + if ( + itemCtx.value === 'same-as-mongos-config-secret' && + configSrcMongos !== 'use-existing-config' && + configSrcMongos !== 'create-new-config' + ) { + return true + } + return false + } + + function onConfigurationSourceMongosChange({ getValue, discriminator, commit, model }) { + const configurationSource = getValue(discriminator, '/configurationSourceMongos') + const configSecretName = `${getValue(model, '/metadata/release/name')}-mongos-config` + if (configurationSource === 'use-existing-config') { + commit('wizard/model$delete', '/resources/secret_mongos_config') + onConfigSecretModelChange( + { commit, model, getValue, discriminator }, + 'mongos', + configurationSource, + '/configurationMongos', + ) + } else if (configurationSource === 'create-new-config') { + const value = getValue(model, '/resources/secret_mongos_config') + if (!value) { + commit('wizard/model$update', { + path: '/resources/secret_mongos_config', + value: {}, + force: true, + }) + } + commit('wizard/model$update', { + path: '/resources/kubedbComMongoDB/spec/shardTopology/mongos/configSecret/name', + value: configSecretName, + force: true, + }) + onConfigSecretModelChange( + { commit, model, getValue, discriminator }, + 'mongos', + configurationSource, + '/configurationMongos', + ) + } else if (configurationSource === 'same-as-shard-config-secret') { + transferConfigSecret({ commit, model, getValue }, 'shard', 'mongos') + } else if (configurationSource === 'same-as-configserver-config-secret') { + transferConfigSecret({ commit, model, getValue }, 'configserver', 'mongos') + } } - if ( - itemCtx.value === 'same-as-mongos-config-secret' && - configSrcMongos !== 'use-existing-config' && - configSrcMongos !== 'create-new-config' - ) { - return true + + function onConfigurationSourceShardChange({ getValue, discriminator, commit, model }) { + const configurationSource = getValue(discriminator, '/configurationSourceShard') + const configSecretName = `${getValue(model, '/metadata/release/name')}-shard-config` + if (configurationSource === 'use-existing-config') { + commit('wizard/model$delete', '/resources/secret_shard_config') + onConfigSecretModelChange( + { commit, model, getValue, discriminator }, + 'shard', + configurationSource, + '/configurationShard', + ) + } else if (configurationSource === 'create-new-config') { + const value = getValue(model, '/resources/secret_shard_config') + if (!value) { + commit('wizard/model$update', { + path: '/resources/secret_shard_config', + value: {}, + force: true, + }) + } + commit('wizard/model$update', { + path: '/resources/kubedbComMongoDB/spec/shardTopology/shard/configSecret/name', + value: configSecretName, + force: true, + }) + onConfigSecretModelChange( + { commit, model, getValue, discriminator }, + 'shard', + configurationSource, + '/configurationShard', + ) + } else if (configurationSource === 'same-as-configserver-config-secret') { + transferConfigSecret({ commit, model, getValue }, 'configserver', 'shard') + } else if (configurationSource === 'same-as-mongos-config-secret') { + transferConfigSecret({ commit, model, getValue }, 'mongos', 'shard') + } } - return false -} -function onConfigurationSourceMongosChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSourceMongos') - const configSecretName = `${getValue(model, '/metadata/release/name')}-mongos-config` - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_mongos_config') - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'mongos', - configurationSource, - '/configurationMongos', - ) - } else if (configurationSource === 'create-new-config') { - const value = getValue(model, '/resources/secret_mongos_config') - if (!value) { + function onConfigurationSourceConfigServerChange({ getValue, discriminator, commit, model }) { + const configurationSource = getValue(discriminator, '/configurationSourceConfigServer') + const configSecretName = `${getValue(model, '/metadata/release/name')}-configserver-config` + if (configurationSource === 'use-existing-config') { + commit('wizard/model$delete', '/resources/secret_configserver_config') + onConfigSecretModelChange( + { commit, model, getValue, discriminator }, + 'configserver', + configurationSource, + '/configurationConfigServer', + ) + } else if (configurationSource === 'create-new-config') { + const value = getValue(model, '/resources/secret_configserver_config') + if (!value) { + commit('wizard/model$update', { + path: '/resources/secret_configserver_config', + value: {}, + force: true, + }) + } commit('wizard/model$update', { - path: '/resources/secret_mongos_config', - value: {}, + path: '/resources/kubedbComMongoDB/spec/shardTopology/configServer/configSecret/name', + value: configSecretName, force: true, }) + onConfigSecretModelChange( + { commit, model, getValue, discriminator }, + 'configserver', + configurationSource, + '/configurationConfigServer', + ) + } else if (configurationSource === 'same-as-shard-config-secret') { + const configurationSourceReference = getValue(discriminator, '/configurationSourceShard') + transferConfigSecret( + { commit, model, getValue }, + 'shard', + 'configserver', + configurationSourceReference, + ) + } else if (configurationSource === 'same-as-mongos-config-secret') { + const configurationSourceReference = getValue(discriminator, '/configurationSourceMongos') + transferConfigSecret( + { commit, model, getValue }, + 'mongos', + 'configserver', + configurationSourceReference, + ) } - commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB/spec/shardTopology/mongos/configSecret/name', - value: configSecretName, - force: true, - }) - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'mongos', - configurationSource, - '/configurationMongos', - ) - } else if (configurationSource === 'same-as-shard-config-secret') { - transferConfigSecret({ commit, model, getValue }, 'shard', 'mongos') - } else if (configurationSource === 'same-as-configserver-config-secret') { - transferConfigSecret({ commit, model, getValue }, 'configserver', 'mongos') } -} -function onConfigurationSourceShardChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSourceShard') - const configSecretName = `${getValue(model, '/metadata/release/name')}-shard-config` - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_shard_config') - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'shard', - configurationSource, - '/configurationShard', - ) - } else if (configurationSource === 'create-new-config') { - const value = getValue(model, '/resources/secret_shard_config') - if (!value) { + function transferConfigSecret({ commit, model, getValue }, src, des) { + const isShardedMode = getValue(model, '/resources/kubedbComMongoDB/spec/shardTopology') + if (isShardedMode) { commit('wizard/model$update', { - path: '/resources/secret_shard_config', - value: {}, + path: `/resources/kubedbComMongoDB/spec/shardTopology/${ + des === 'configserver' ? 'configServer' : des + }/configSecret/name`, + value: getValue( + model, + `/resources/kubedbComMongoDB/spec/shardTopology/${ + src === 'configserver' ? 'configServer' : src + }/configSecret/name`, + ), force: true, }) + + commit('wizard/model$delete', `/resources/secret_${des}_config`) } - commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB/spec/shardTopology/shard/configSecret/name', - value: configSecretName, - force: true, - }) - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'shard', - configurationSource, - '/configurationShard', - ) - } else if (configurationSource === 'same-as-configserver-config-secret') { - transferConfigSecret({ commit, model, getValue }, 'configserver', 'shard') - } else if (configurationSource === 'same-as-mongos-config-secret') { - transferConfigSecret({ commit, model, getValue }, 'mongos', 'shard') } -} -function onConfigurationSourceConfigServerChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSourceConfigServer') - const configSecretName = `${getValue(model, '/metadata/release/name')}-configserver-config` - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_configserver_config') - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'configserver', - configurationSource, - '/configurationConfigServer', - ) - } else if (configurationSource === 'create-new-config') { - const value = getValue(model, '/resources/secret_configserver_config') - if (!value) { + function onConfigSecretModelChange( + { commit, model, getValue, discriminator }, + configType, + configSrc, + discriminatorPath, + ) { + if (configSrc === 'create-new-config') { + const value = getValue(discriminator, discriminatorPath) commit('wizard/model$update', { - path: '/resources/secret_configserver_config', - value: {}, + path: `/resources/secret_${configType}_config/stringData/mongod.conf`, + value: value, force: true, }) } - commit('wizard/model$update', { - path: '/resources/kubedbComMongoDB/spec/shardTopology/configServer/configSecret/name', - value: configSecretName, - force: true, - }) - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'configserver', - configurationSource, - '/configurationConfigServer', - ) - } else if (configurationSource === 'same-as-shard-config-secret') { - const configurationSourceReference = getValue(discriminator, '/configurationSourceShard') - transferConfigSecret( - { commit, model, getValue }, - 'shard', - 'configserver', - configurationSourceReference, - ) - } else if (configurationSource === 'same-as-mongos-config-secret') { - const configurationSourceReference = getValue(discriminator, '/configurationSourceMongos') - transferConfigSecret( - { commit, model, getValue }, - 'mongos', - 'configserver', - configurationSourceReference, - ) + const configSrcShard = getValue(discriminator, '/configurationSourceShard') + const configSrcConfigServer = getValue(discriminator, '/configurationSourceConfigServer') + const configSrcMongos = getValue(discriminator, '/configurationSourceMongos') + + if (configSrcShard === `same-as-${configType}-config-secret`) { + transferConfigSecret({ commit, model, getValue }, configType, 'shard') + } + if (configSrcConfigServer === `same-as-${configType}-config-secret`) { + transferConfigSecret({ commit, model, getValue }, configType, 'configserver') + } + if (configSrcMongos === `same-as-${configType}-config-secret`) { + transferConfigSecret({ commit, model, getValue }, configType, 'mongos') + } } -} -function transferConfigSecret({ commit, model, getValue }, src, des) { - const isShardedMode = getValue(model, '/resources/kubedbComMongoDB/spec/shardTopology') - if (isShardedMode) { - commit('wizard/model$update', { - path: `/resources/kubedbComMongoDB/spec/shardTopology/${ - des === 'configserver' ? 'configServer' : des - }/configSecret/name`, - value: getValue( - model, - `/resources/kubedbComMongoDB/spec/shardTopology/${ - src === 'configserver' ? 'configServer' : src - }/configSecret/name`, - ), - force: true, - }) + function setConfiguration({ model, getValue }) { + return getValue(model, '/resources/secret_config/stringData/mongod.conf') + } - commit('wizard/model$delete', `/resources/secret_${des}_config`) + function setConfigurationShard({ model, getValue }) { + const value = getValue(model, '/resources/secret_shard_config/stringData/mongod.conf') + return value } -} -function onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - configType, - configSrc, - discriminatorPath, -) { - if (configSrc === 'create-new-config') { - const value = getValue(discriminator, discriminatorPath) - commit('wizard/model$update', { - path: `/resources/secret_${configType}_config/stringData/mongod.conf`, - value: value, - force: true, - }) + function setConfigurationConfigServer({ model, getValue }) { + const value = getValue(model, '/resources/secret_configserver_config/stringData/mongod.conf') + return value } - const configSrcShard = getValue(discriminator, '/configurationSourceShard') - const configSrcConfigServer = getValue(discriminator, '/configurationSourceConfigServer') - const configSrcMongos = getValue(discriminator, '/configurationSourceMongos') - if (configSrcShard === `same-as-${configType}-config-secret`) { - transferConfigSecret({ commit, model, getValue }, configType, 'shard') + function setConfigurationMongos({ model, getValue }) { + const value = getValue(model, '/resources/secret_mongos_config/stringData/mongod.conf') + return value } - if (configSrcConfigServer === `same-as-${configType}-config-secret`) { - transferConfigSecret({ commit, model, getValue }, configType, 'configserver') + + function setConfigurationFiles({ model, getValue }) { + const value = getValue(model, '/resources/secret_config/data/mongod.conf') + return atob(value) } - if (configSrcMongos === `same-as-${configType}-config-secret`) { - transferConfigSecret({ commit, model, getValue }, configType, 'mongos') + + function setConfigurationFilesShard({ model, getValue }) { + const value = getValue(model, '/resources/secret_shard_config/data/mongod.conf') + return atob(value) } -} -function setConfiguration({ model, getValue }) { - return getValue(model, '/resources/secret_config/stringData/mongod.conf') -} + function setConfigurationFilesConfigServer({ model, getValue }) { + const value = getValue(model, '/resources/secret_configserver_config/data/mongod.conf') + return atob(value) + } -function setConfigurationShard({ model, getValue }) { - const value = getValue(model, '/resources/secret_shard_config/stringData/mongod.conf') - return value -} + function setConfigurationFilesMongos({ model, getValue }) { + const value = getValue(model, '/resources/secret_mongos_config/data/mongod.conf') + return atob(value) + } -function setConfigurationConfigServer({ model, getValue }) { - const value = getValue(model, '/resources/secret_configserver_config/stringData/mongod.conf') - return value -} + function onSetCustomConfigChange({ discriminator, getValue, commit }) { + const value = getValue(discriminator, '/setCustomConfig') -function setConfigurationMongos({ model, getValue }) { - const value = getValue(model, '/resources/secret_mongos_config/stringData/mongod.conf') - return value -} + if (value === 'no') { + commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/configSecret') + commit( + 'wizard/model$delete', + '/resources/kubedbComMongoDB/spec/shardTopology/shard/configSecret', + ) + commit( + 'wizard/model$delete', + '/resources/kubedbComMongoDB/spec/shardTopology/configServer/configSecret', + ) + commit( + 'wizard/model$delete', + '/resources/kubedbComMongoDB/spec/shardTopology/mongos/configSecret', + ) + commit('wizard/model$delete', '/resources/secret_config') + commit('wizard/model$delete', '/resources/secret_shard_config') + commit('wizard/model$delete', '/resources/secret_configserver_config') + commit('wizard/model$delete', '/resources/secret_mongos_config') + } + } -function setConfigurationFiles({ model, getValue }) { - const value = getValue(model, '/resources/secret_config/data/mongod.conf') - return atob(value) -} + function getCreateNameSpaceUrl({ storeGet }) { + const user = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function setConfigurationFilesShard({ model, getValue }) { - const value = getValue(model, '/resources/secret_shard_config/data/mongod.conf') - return atob(value) -} + const domain = storeGet('/domain') || '' + if (domain.includes('bb.test')) { + return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } + } -function setConfigurationFilesConfigServer({ model, getValue }) { - const value = getValue(model, '/resources/secret_configserver_config/data/mongod.conf') - return atob(value) -} + function isVariantAvailable({ storeGet }) { + const variant = storeGet('/route/query/variant') + return variant ? true : false + } -function setConfigurationFilesMongos({ model, getValue }) { - const value = getValue(model, '/resources/secret_mongos_config/data/mongod.conf') - return atob(value) -} + function showScheduleBackup() { + const operationQuery = storeGet('/route/params/actions') || '' + const isBackupOperation = operationQuery === 'edit-self-backupconfiguration' ? true : false + return !isBackupOperation + } -function onSetCustomConfigChange({ discriminator, getValue, commit }) { - const value = getValue(discriminator, '/setCustomConfig') + //////////////////// Autoscaler ///////////////// - if (value === 'no') { - commit('wizard/model$delete', '/resources/kubedbComMongoDB/spec/configSecret') - commit( - 'wizard/model$delete', - '/resources/kubedbComMongoDB/spec/shardTopology/shard/configSecret', - ) - commit( - 'wizard/model$delete', - '/resources/kubedbComMongoDB/spec/shardTopology/configServer/configSecret', - ) - commit( - 'wizard/model$delete', - '/resources/kubedbComMongoDB/spec/shardTopology/mongos/configSecret', - ) - commit('wizard/model$delete', '/resources/secret_config') - commit('wizard/model$delete', '/resources/secret_shard_config') - commit('wizard/model$delete', '/resources/secret_configserver_config') - commit('wizard/model$delete', '/resources/secret_mongos_config') + let autoscaleType = '' + let dbDetails = {} + function isKubedb() { + return !!storeGet('/route/params/actions') } -} -function getCreateNameSpaceUrl({ storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function showOpsRequestOptions() { + if (isKubedb() === true) return true + // watchDependency('model#/spec/databaseRef/name') + return ( + !!getValue(model, '/spec/databaseRef/name') && !!getValue(discriminator, '/autoscalingType') + ) + } + let instance = {} + let showStoragememory = false + async function getDbDetails() { + const annotations = getValue( + model, + '/resources/autoscalingKubedbComMongoDBAutoscaler/metadata/annotations', + ) + instance = annotations?.['kubernetes.io/instance-type'] + 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) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/mongodbs/${name}`, + ) + dbDetails = resp.data || {} + showStoragememory = dbDetails?.spec?.storageEngine === 'inMemory' + setDiscriminatorValue('/dbDetails', true) + } catch (e) { + console.log(e) + } + } - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + commit('wizard/model$update', { + path: `/metadata/release/name`, + value: name, + force: true, + }) + commit('wizard/model$update', { + path: `/metadata/release/namespace`, + value: namespace, + force: true, + }) + commit('wizard/model$update', { + path: `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/databaseRef/name`, + value: name, + force: true, + }) + commit('wizard/model$update', { + path: `/resources/autoscalingKubedbComMongoDBAutoscaler/metadata/labels`, + value: dbDetails.metadata.labels, + force: true, + }) } -} -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} + function showStorageMemoryOption() { + return showStoragememory + } -function showScheduleBackup({ storeGet }) { - const operationQuery = storeGet('/route/params/actions') || '' - const isBackupOperation = operationQuery === 'edit-self-backupconfiguration' ? true : false - return !isBackupOperation -} + function mongoTypeEqualsTo(mongoType, type) { + // watchDependency('discriminator#/dbDetails') + autoscaleType = type + const dbDetailsSuccess = getValue(discriminator, '/dbDetails') -//////////////////// Autoscaler ///////////////// + if (!dbDetailsSuccess) return false -let autoscaleType = '' -let dbDetails = {} -function isKubedb({ storeGet }) { - return !!storeGet('/route/params/actions') -} + const { spec } = dbDetails || {} + const { shardTopology, replicaSet } = spec || {} + let verd = '' + if (shardTopology) verd = 'sharded' + else { + if (replicaSet) verd = 'replicaSet' + else verd = 'standalone' + } + clearSpecModel(verd) + return mongoType === verd + } -function showOpsRequestOptions({ model, getValue, watchDependency, storeGet, discriminator }) { - if (isKubedb({ storeGet }) === true) return true - watchDependency('model#/spec/databaseRef/name') - return ( - !!getValue(model, '/spec/databaseRef/name') && !!getValue(discriminator, '/autoscalingType') - ) -} + function clearSpecModel(dbtype) { + if (dbtype === 'standalone') { + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/${autoscaleType}/replicaSet`, + ) + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/${autoscaleType}/shard`, + ) + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/${autoscaleType}/mongos`, + ) + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/${autoscaleType}/configServer`, + ) + } else if (dbtype === 'replicaSet') { + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/${autoscaleType}/standalone`, + ) + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/${autoscaleType}/shard`, + ) + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/${autoscaleType}/mongos`, + ) + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/${autoscaleType}/configServer`, + ) + } else if (dbtype === 'sharded') { + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/${autoscaleType}/standalone`, + ) + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/${autoscaleType}/replicaSet`, + ) + } + } + 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/kubedbComMongoDB/spec/monitor/prometheus/exporter/env/${index}/valueFrom/configMapKeyRef/name`, + ) -async function getDbDetails({ axios, storeGet, getValue, model, setDiscriminatorValue, commit }) { - const owner = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/configMapKeyRef/name') - const namespace = - storeGet('/route/query/namespace') || getValue(model, '/metadata/namespace') || '' - const name = storeGet('/route/params/name') || getValue(model, '/spec/databaseRef/name') || '' + if (!configMapName) return [] - if (namespace && name) { try { const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/mongodbs/${name}`, + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/configmaps/${configMapName}`, ) - dbDetails = resp.data || {} - setDiscriminatorValue('/dbDetails', true) + 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 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 [] + } - commit('wizard/model$update', { - path: `/metadata/release/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/metadata/release/namespace`, - value: namespace, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/databaseRef/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComMongoDBAutoscaler/metadata/labels`, - value: dbDetails.metadata.labels, - force: true, - }) -} - -async function mongoTypeEqualsTo( - { watchDependency, getValue, commit, discriminator }, - mongoType, - type, -) { - watchDependency('discriminator#/dbDetails') - autoscaleType = type - const dbDetailsSuccess = getValue(discriminator, '/dbDetails') - - if (!dbDetailsSuccess) return false - - const { spec } = dbDetails || {} - const { shardTopology, replicaSet } = spec || {} - let verd = '' - if (shardTopology) verd = 'sharded' - else { - if (replicaSet) verd = 'replicaSet' - else verd = 'standalone' - } - clearSpecModel({ commit }, verd) - return mongoType === verd -} - -function clearSpecModel({ commit }, dbtype) { - if (dbtype === 'standalone') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/${autoscaleType}/replicaSet`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/${autoscaleType}/shard`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/${autoscaleType}/mongos`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/${autoscaleType}/configServer`, - ) - } else if (dbtype === 'replicaSet') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/${autoscaleType}/shard`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/${autoscaleType}/mongos`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/${autoscaleType}/configServer`, - ) - } else if (dbtype === 'sharded') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/${autoscaleType}/replicaSet`, - ) + function isNodeTopologySelected() { + // watchDependency( + // 'model#/resources/autoscalingKubedbComMongoDBAutoscaler/spec/compute/nodeTopology/name', + // ) + const nodeTopologyName = + getValue( + model, + '/resources/autoscalingKubedbComMongoDBAutoscaler/spec/compute/nodeTopology/name', + ) || '' + return !!nodeTopologyName.length } -} -async function fetchNodeTopology({ axios, storeGet }) { - 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 + function setControlledResources(type) { + const list = ['cpu', 'memory'] + const path = `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/${type}/controlledResources` + commit('wizard/model$update', { + path: path, + value: list, + force: true, }) - return mappedList - } catch (e) { - console.log(e) + return list } - return [] -} - -function isNodeTopologySelected({ watchDependency, model, getValue }) { - watchDependency( - 'model#/resources/autoscalingKubedbComMongoDBAutoscaler/spec/compute/nodeTopology/name', - ) - const nodeTopologyName = - getValue( - model, - '/resources/autoscalingKubedbComMongoDBAutoscaler/spec/compute/nodeTopology/name', - ) || '' - return !!nodeTopologyName.length -} - -function setControlledResources({ commit }, type) { - const list = ['cpu', 'memory'] - const path = `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/${type}/controlledResources` - commit('wizard/model$update', { - path: path, - value: list, - force: true, - }) - return list -} -function setTrigger({ model, getValue }, path) { - let value = getValue(model, `/resources/${path}`) - if (value) return value - return 'On' -} + function setTrigger(path) { + let value = getValue(model, `/resources/${path}`) + return value === 'On' + } -function setApplyToIfReady() { - return 'IfReady' -} + function onTriggerChange(type) { + const trigger = getValue(discriminator, `/${type}/trigger`) + const commitPath = `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/${type}/trigger` -function setMetadata({ storeGet, mode, commit }) { - const dbname = storeGet('/route/params/name') || '' - const namespace = storeGet('/route/query/namespace') || '' - if (mode === 'standalone-step') { - commit('wizard/model$update', { - path: '/metadata/release/name', - value: dbname, - force: true, - }) commit('wizard/model$update', { - path: '/metadata/release/namespace', - value: namespace, + path: commitPath, + value: trigger ? 'On' : 'Off', force: true, }) } -} -function handleUnit({ commit, model, getValue }, 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)) { + function setApplyToIfReady() { + return 'IfReady' + } + + function setMetadata() { + const dbname = storeGet('/route/params/name') || '' + const namespace = storeGet('/route/query/namespace') || '' + const isKube = !!storeGet('/route/params/actions') + if (isKube) { commit('wizard/model$update', { - path: `/resources/${path}`, - value: updatedValue, + path: '/metadata/release/name', + value: dbname, force: true, }) - } - } else { - if (!isNaN(value)) { - value += 'Gi' commit('wizard/model$update', { - path: `/resources/${path}`, - value: value, + path: '/metadata/release/namespace', + value: namespace, force: true, }) } } -} -function objectCopy(obj) { - const temp = JSON.stringify(obj) - return JSON.parse(temp) -} + 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 isBindingAlreadyOn({ model, getValue }) { - const value = getValue(model, '/resources') - const keys = Object.keys(value) - isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComMongoDBBinding') - return isExposeBinding -} + function objectCopy(obj) { + const temp = JSON.stringify(obj) + return JSON.parse(temp) + } -async function addOrRemoveBinding({ commit, model, getValue, discriminator }) { - const value = getValue(discriminator, `/binding`) - const dbName = getValue(model, '/metadata/release/name') - const dbNamespace = getValue(model, '/metadata/release/namespace') - const labels = getValue(model, '/resources/kubedbComMongoDB/metadata/labels') - const bindingValues = { - apiVersion: 'catalog.appscode.com/v1alpha1', - kind: 'MongoDBBinding', - metadata: { - labels, - name: dbName, - namespace: dbNamespace, - }, - spec: { - sourceRef: { + function isBindingAlreadyOn() { + const value = getValue(model, '/resources') + const keys = Object.keys(value) + const isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComMongoDBBinding') + 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/kubedbComMongoDB/metadata/labels') + const bindingValues = { + apiVersion: 'catalog.appscode.com/v1alpha1', + kind: 'MongoDBBinding', + metadata: { + labels, name: dbName, namespace: dbNamespace, }, - }, - } + spec: { + sourceRef: { + name: dbName, + namespace: dbNamespace, + }, + }, + } - if (value) { - await commit('wizard/model$update', { - path: '/resources/catalogAppscodeComMongoDBBinding', - value: bindingValues, - force: true, - }) - } else { - await commit('wizard/model$delete', '/resources/catalogAppscodeComMongoDBBinding') + if (value) { + commit('wizard/model$update', { + path: '/resources/catalogAppscodeComMongoDBBinding', + value: bindingValues, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/catalogAppscodeComMongoDBBinding') + } } -} -function getOpsRequestUrl({ storeGet, model, getValue, mode }, 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 + `/create-opsrequest-${reqType.toLowerCase()}?namespace=${namespace}` - - if (mode === 'standalone-step') return pathConstructedForKubedb - else - return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/mongodbopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` -} + 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}` -async function fetchTopologyMachines({ axios, getValue, storeGet, model, setDiscriminatorValue }) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComMongoDBAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] + const isKube = !!storeGet('/route/params/actions') - 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) + if (isKube) return pathConstructedForKubedb + else + return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/mongodbopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` + } + + async function fetchTopologyMachines() { + const annotations = getValue( + model, + '/resources/autoscalingKubedbComMongoDBAutoscaler/metadata/annotations', + ) + const 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 [] + setDiscriminatorValue('/topologyMachines', []) + } + } + } - const nodeGroups = resp.data?.spec?.nodeGroups || [] - setDiscriminatorValue('/topologyMachines', nodeGroups) - return nodeGroups + function setAllowedMachine(type, minmax) { + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) } catch (e) { console.log(e) - return [] + parsedInstance = {} } - } -} -function setAllowedMachine({ model, getValue }, type, minmax) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComMongoDBAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - let parsedInstance = {} - try { - if (instance) parsedInstance = JSON.parse(instance) - } catch (e) { - console.log(e) - parsedInstance = {} + const machine = parsedInstance[type] || '' + const mx = machine?.includes(',') ? machine.split(',')[1] : '' + const mn = machine?.includes(',') ? machine.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: '', + } } - const machine = parsedInstance[type] || '' - const mx = machine?.includes(',') ? machine.split(',')[1] : '' - const mn = machine?.includes(',') ? machine.split(',')[0] : '' + function getMachines(type, minmax) { + // watchDependency('discriminator#/topologyMachines') + const depends = minmax === 'min' ? 'max' : 'min' + const dependantPath = `/allowedMachine-${type}-${depends}` - if (minmax === 'min') return mn - else return mx -} + // watchDependency(`discriminator#${dependantPath}`) + const dependantMachineObj = getValue(discriminator, dependantPath) + const dependantMachine = dependantMachineObj?.machine || '' -async function getMachines({ getValue, watchDependency, discriminator }, type, minmax) { - watchDependency('discriminator#/topologyMachines') - const depends = minmax === 'min' ? 'max' : 'min' - const dependantPath = `/allowedMachine-${type}-${depends}` + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] - watchDependency(`discriminator#${dependantPath}`) - const dependantMachine = getValue(discriminator, dependantPath) + const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) - const nodeGroups = getValue(discriminator, '/topologyMachines') || [] + // 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 dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) + const filteredMachine = machines?.filter((item, ind) => + minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, + ) - const machines = nodeGroups?.map((item) => { - const subText = `CPU: ${item.allocatable.cpu}, Memory: ${item.allocatable.memory}` - const text = item.topologyValue - return { text, subText, value: item.topologyValue } - }) + return dependantIndex === -1 ? machines : filteredMachine + } - const filteredMachine = machines?.filter((item, ind) => - minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, - ) + function hasAnnotations() { + const annotations = getValue( + model, + '/resources/autoscalingKubedbComMongoDBAutoscaler/metadata/annotations', + ) + const instance = annotations['kubernetes.io/instance-type'] - return dependantIndex === -1 ? machines : filteredMachine -} + return !!instance + } -function hasAnnotations({ model, getValue }, type) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComMongoDBAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] + function hasNoAnnotations() { + return !hasAnnotations() + } - return !!instance -} + function onMachineChange(type) { + const annoPath = '/resources/autoscalingKubedbComMongoDBAutoscaler/metadata/annotations' + const annotations = getValue(model, annoPath) || {} + const instance = annotations['kubernetes.io/instance-type'] + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = {} + } -function hasNoAnnotations({ model, getValue }) { - return !hasAnnotations({ model, getValue }) -} + // Now discriminator values are objects with { machine, cpu, memory } + const minMachineObj = getValue(discriminator, `/allowedMachine-${type}-min`) + const maxMachineObj = getValue(discriminator, `/allowedMachine-${type}-max`) + const minMachine = minMachineObj?.machine || '' + const maxMachine = maxMachineObj?.machine || '' + const minMaxMachine = `${minMachine},${maxMachine}` + + parsedInstance[type] = minMaxMachine + const instanceString = JSON.stringify(parsedInstance) + annotations['kubernetes.io/instance-type'] = instanceString + + // 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/autoscalingKubedbComMongoDBAutoscaler/spec/compute/${type}` + + if (minMachine && maxMachine && instance !== instanceString) { + 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 onMachineChange({ model, getValue, discriminator, commit }, type) { - const annoPath = '/resources/autoscalingKubedbComMongoDBAutoscaler/metadata/annotations' - const annotations = getValue(model, annoPath) - const instance = annotations['kubernetes.io/instance-type'] - let parsedInstance = {} - try { - if (instance) parsedInstance = JSON.parse(instance) - } catch (e) { - console.log(e) - parsedInstance = {} - } - - const minMachine = getValue(discriminator, `/allowedMachine-${type}-min`) - const maxMachine = getValue(discriminator, `/allowedMachine-${type}-max`) - const minMaxMachine = `${minMachine},${maxMachine}` - - parsedInstance[type] = minMaxMachine - const instanceString = JSON.stringify(parsedInstance) - annotations['kubernetes.io/instance-type'] = instanceString - - const machines = getValue(discriminator, `/topologyMachines`) || [] - const minMachineObj = machines.find((item) => item.topologyValue === minMachine) - const maxMachineObj = machines.find((item) => item.topologyValue === maxMachine) - const minMachineAllocatable = minMachineObj?.allocatable - const maxMachineAllocatable = maxMachineObj?.allocatable - const allowedPath = `/resources/autoscalingKubedbComMongoDBAutoscaler/spec/compute/${type}` - - if (minMachine && maxMachine && instance !== instanceString) { - 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 setValueFrom() { + if (isConfigMapTypeValueFrom()) { + return 'configMap' + } else if (isSecretTypeValueFrom()) { + return 'secret' + } else { + return 'input' + } + } + + function setValueFromDbDetails(path) { + const value = getValue(model, path) + return value + } + + function isHidden(path) { + const value = getValue(model, path) + return !!value + } + + 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/kubedbComMongoDB/spec/monitor/prometheus/exporter/env', + value: filteredEnv, + force: true, + }) } -} -return { - getOpsRequestUrl, - handleUnit, - setMetadata, - isKubedb, - getDbDetails, - mongoTypeEqualsTo, - clearSpecModel, - fetchNodeTopology, - isNodeTopologySelected, - setControlledResources, - setTrigger, - setApplyToIfReady, - showOpsRequestOptions, - setInitSchedule, - fetchNames, - isRancherManaged, - fetchNamespaces, - onInputChangeSchedule, - getDefaultSchedule, - getBlueprints, - ifUsagePolicy, - isBlueprintOption, - getDefault, - onInputChange, - showBackupOptions, - showScheduleBackup, - isVariantAvailable, - fetchJsons, - disableLableChecker, - isEqualToModelPathValue, - getResources, - isEqualToDiscriminatorPath, - setValueFromModel, - isNotShardModeSelected, - isShardModeSelected, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - returnTrue, - returnStringYes, - getMongoDbVersions, - showAuthPasswordField, - showAuthSecretField, - showNewSecretCreateField, - isNotStandaloneMode, - showCommonStorageClassAndSizeField, - setDatabaseMode, - getStorageClassNames, - setStorageClass, - deleteDatabaseModePath, - isEqualToDatabaseMode, - setApiGroup, - getIssuerRefsName, - hasIssuerRefName, - hasNoIssuerRefName, - setClusterAuthMode, - setSSLMode, - showTlsConfigureSection, - onTlsConfigureChange, - getAliasOptions, - showMonitoringSection, - onEnableMonitoringChange, - showCustomizeExporterSection, - onCustomizeExporterChange, - disableInitializationSection, - valueExists, - initPrePopulateDatabase, - onPrePopulateDatabaseChange, - initDataSource, - onDataSourceChange, - initVolumeType, - onVolumeTypeChange, - showInitializationForm, - showScriptOrStashForm, - showConfigMapOrSecretName, - initializeNamespace, - showRepositorySelectOrCreate, - onInitRepositoryChoiseChange, - initCustomizeRestoreJobRuntimeSettings, - initCustomizeRestoreJobRuntimeSettingsForBackup, - onCustomizeRestoreJobRuntimeSettingsChange, - onCustomizeRestoreJobRuntimeSettingsChangeForBackup, - showRuntimeForm, - getImagePullSecrets, - getBackupConfigsAndAnnotations, - deleteKubeDbComMongDbAnnotation, - addKubeDbComMongDbAnnotation, - initScheduleBackup, - initScheduleBackupForEdit, - onScheduleBackupChange, - showBackupForm, - initalizeTargetReferenceName, - setInitialRestoreSessionRepo, - initRepositoryChoise, - initRepositoryChoiseForEdit, - onRepositoryChoiseChange, - onRepositoryNameChange, - getMongoAnnotations, - initFromAnnotationValue, - onBackupBlueprintNameChange, - onBackupBlueprintScheduleChange, - initFromAnnotationKeyValue, - onTaskParametersChange, - isValueExistInModel, - onNamespaceChange, - onLabelChange, - onNameChange, - returnFalse, - onAgentChange, - getCreateAuthSecret, - showExistingSecretSection, - showPasswordSection, - setAuthSecretPassword, - onAuthSecretPasswordChange, - encodePassword, - decodePassword, - onCreateAuthSecretChange, - getSecrets, - isEqualToServiceMonitorType, - onConfigurationSourceChange, - onConfigurationChange, - setConfigurationSource, - setSecretConfigNamespace, - setConfigurationSourceShard, - setConfigurationSourceConfigServer, - setConfigurationSourceMongos, - isSchemaOf, - disableConfigSourceOption, - onConfigurationSourceMongosChange, - onConfigurationSourceShardChange, - onConfigurationSourceConfigServerChange, - transferConfigSecret, - onConfigSecretModelChange, - setConfiguration, - setConfigurationShard, - setConfigurationConfigServer, - setConfigurationMongos, - setConfigurationFiles, - setConfigurationFilesShard, - setConfigurationFilesConfigServer, - setConfigurationFilesMongos, - onSetCustomConfigChange, - getCreateNameSpaceUrl, - updateConfigServerStorageClass, - - initBackupData, - isBackupDataLoadedTrue, - setBackupType, - getTypes, - getNamespaceArray, - isBackupType, - getContext, - onContextChange, - getConfigList, - onConfigChange, - showPause, - showSchedule, - showConfigList, - setBlueprintSwitch, - onBlueprintChange, - setArchiverSwitch, - onArchiverChange, - onBackupTypeChange, - isBindingAlreadyOn, - addOrRemoveBinding, - getMachines, - setAllowedMachine, - hasAnnotations, - hasNoAnnotations, - fetchTopologyMachines, - onMachineChange, + function initEnvArray() { + const env = getValue(model, '/resources/kubedbComMongoDB/spec/monitor/prometheus/exporter/env') + + return env || [] + } + return { + isEqualToTemp, + initEnvArray, + initMonitoring, + onEnvArrayChange, + getOpsRequestUrl, + handleUnit, + setMetadata, + isKubedb, + getDbDetails, + mongoTypeEqualsTo, + clearSpecModel, + fetchNodeTopology, + isNodeTopologySelected, + setControlledResources, + setTrigger, + onTriggerChange, + setApplyToIfReady, + showOpsRequestOptions, + setInitSchedule, + fetchNames, + isRancherManaged, + fetchNamespaces, + onInputChangeSchedule, + getDefaultSchedule, + getBlueprints, + ifUsagePolicy, + isBlueprintOption, + getDefault, + onInputChange, + showBackupOptions, + showScheduleBackup, + isVariantAvailable, + fetchJsons, + disableLableChecker, + isEqualToModelPathValue, + getResources, + isEqualToDiscriminatorPath, + setValueFromModel, + isNotShardModeSelected, + isShardModeSelected, + getNamespacedResourceList, + getResourceList, + resourceNames, + unNamespacedResourceNames, + returnTrue, + returnStringYes, + getMongoDbVersions, + showAuthPasswordField, + showAuthSecretField, + showNewSecretCreateField, + isNotStandaloneMode, + showCommonStorageClassAndSizeField, + setDatabaseMode, + getStorageClassNames, + setStorageClass, + deleteDatabaseModePath, + isEqualToDatabaseMode, + setApiGroup, + getIssuerRefsName, + hasIssuerRefName, + hasNoIssuerRefName, + setClusterAuthMode, + setSSLMode, + showTlsConfigureSection, + onTlsConfigureChange, + getAliasOptions, + showMonitoringSection, + onEnableMonitoringChange, + showCustomizeExporterSection, + onCustomizeExporterChange, + disableInitializationSection, + valueExists, + initPrePopulateDatabase, + onPrePopulateDatabaseChange, + initDataSource, + onDataSourceChange, + initVolumeType, + onVolumeTypeChange, + showInitializationForm, + showScriptOrStashForm, + showConfigMapOrSecretName, + initializeNamespace, + showRepositorySelectOrCreate, + onInitRepositoryChoiseChange, + initCustomizeRestoreJobRuntimeSettings, + initCustomizeRestoreJobRuntimeSettingsForBackup, + onCustomizeRestoreJobRuntimeSettingsChange, + onCustomizeRestoreJobRuntimeSettingsChangeForBackup, + showRuntimeForm, + getImagePullSecrets, + getBackupConfigsAndAnnotations, + deleteKubeDbComMongDbAnnotation, + addKubeDbComMongDbAnnotation, + initScheduleBackup, + initScheduleBackupForEdit, + onScheduleBackupChange, + showBackupForm, + initalizeTargetReferenceName, + setInitialRestoreSessionRepo, + initRepositoryChoise, + initRepositoryChoiseForEdit, + onRepositoryChoiseChange, + onRepositoryNameChange, + getMongoAnnotations, + initFromAnnotationValue, + onBackupBlueprintNameChange, + onBackupBlueprintScheduleChange, + initFromAnnotationKeyValue, + onTaskParametersChange, + isValueExistInModel, + onNamespaceChange, + onLabelChange, + onNameChange, + returnFalse, + onAgentChange, + getCreateAuthSecret, + showExistingSecretSection, + showPasswordSection, + setAuthSecretPassword, + onAuthSecretPasswordChange, + encodePassword, + decodePassword, + onCreateAuthSecretChange, + getSecrets, + isEqualToServiceMonitorType, + onConfigurationSourceChange, + onConfigurationChange, + setConfigurationSource, + setSecretConfigNamespace, + setConfigurationSourceShard, + setConfigurationSourceConfigServer, + setConfigurationSourceMongos, + isSchemaOf, + disableConfigSourceOption, + onConfigurationSourceMongosChange, + onConfigurationSourceShardChange, + onConfigurationSourceConfigServerChange, + transferConfigSecret, + onConfigSecretModelChange, + setConfiguration, + setConfigurationShard, + setConfigurationConfigServer, + setConfigurationMongos, + setConfigurationFiles, + setConfigurationFilesShard, + setConfigurationFilesConfigServer, + setConfigurationFilesMongos, + onSetCustomConfigChange, + getCreateNameSpaceUrl, + updateConfigServerStorageClass, + initBackupData, + isBackupDataLoadedTrue, + setBackupType, + getTypes, + getNamespaceArray, + isBackupType, + getContext, + onContextChange, + getConfigList, + onConfigChange, + showPause, + showSchedule, + showConfigList, + setBlueprintSwitch, + onBlueprintChange, + setArchiverSwitch, + onArchiverChange, + onBackupTypeChange, + isBindingAlreadyOn, + addOrRemoveBinding, + getMachines, + setAllowedMachine, + hasAnnotations, + hasNoAnnotations, + fetchTopologyMachines, + onMachineChange, + onValueFromChange, + getConfigMapKeys, + setValueFrom, + isInputTypeValueFrom, + getSecretKeys, + setValueFromDbDetails, + isHidden, + setPausedValue, + showStorageMemoryOption, + } } diff --git a/charts/kubedbcom-mssqlserver-editor-options/ui/create-ui.yaml b/charts/kubedbcom-mssqlserver-editor-options/ui/create-ui.yaml index 0ffc233716..79a5ce84f0 100644 --- a/charts/kubedbcom-mssqlserver-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-mssqlserver-editor-options/ui/create-ui.yaml @@ -1,403 +1,413 @@ -steps: -- form: - discriminator: - bundleApiLoaded: - default: false - type: boolean - customPid: - type: string - pid: - type: string - elements: - - computed: initBundle - if: returnFalse - type: label-element - - disableUnselect: true - fetch: getAdminOptions|databases/MSSQLServer/versions - if: isToggleOn|databases/MSSQLServer/versions - label: - text: labels.database.version - schema: - $ref: schema#/properties/spec/properties/admin/properties/databases/properties/MSSQLServer/properties/versions/properties/default - type: select - - computed: getDefault|databases/MSSQLServer/mode - fetch: getAdminOptions|databases/MSSQLServer/mode - hasDescription: true - if: isToggleOn|databases/MSSQLServer/mode - label: - text: labels.database.mode - onChange: onModeChange - schema: - $ref: schema#/properties/spec/properties/mode - type: radio - - element: - label: - text: labels.databases - type: input - if: isEqualToModelPathValue|Topology|/spec/mode - label: - text: labels.availabilityGroup - schema: - $ref: schema#/properties/spec/properties/topology/properties/availabilityGroup/properties/databases - type: list-input-form - - if: isEqualToModelPathValue|Topology|/spec/mode - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/replicas +step: +- type: single-step-form + loader: initBundle + elements: + - type: label-element + label: '' + subtitle: Select the MSSQLServer version you want to deploy on Kubernetes. The chosen version determines the SQL Server engine features, compatibility, and runtime behavior of your database cluster. + - disableUnselect: true + loader: getAdminOptions|databases/MSSQLServer/versions + if: + type: function + name: isToggleOn|databases/MSSQLServer/versions + label: Database version + schema: schema/properties/spec/properties/admin/properties/databases/properties/MSSQLServer/properties/versions/properties/default + type: select + - init: + type: func + value: getDefault|databases/MSSQLServer/mode + loader: getAdminOptions|databases/MSSQLServer/mode + if: + type: function + name: isToggleOn|databases/MSSQLServer/mode + label: Database mode + isHorizontal: true + watcher: + func: onModeChange + paths: + - schema/properties/spec/properties/mode + schema: schema/properties/spec/properties/mode + type: radio + - type: array-item-form + element: + label: Databases type: input - - elements: - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.cpu - onChange: setRequests|cpu - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.memory - onChange: setRequests|memory - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - label: - text: labels.machine_profile - show_label: true - type: single-step-form - - fetch: getAdminOptions|storageClasses - label: - text: labels.storage.class - schema: - $ref: schema#/properties/spec/properties/admin/properties/storageClasses/properties/default + if: + type: function + name: isEqualToModelPathValue|Topology|/spec/mode + label: Availability Group + schema: schema/properties/spec/properties/topology/properties/availabilityGroup/properties/databases + - if: + type: function + name: isEqualToModelPathValue|Topology|/spec/mode + label: Replicaset number + schema: schema/properties/spec/properties/replicas + type: input + - elements: + - type: label-element + label: '' + subtitle: Select a machine profile to allocate CPU and memory resources for your database cluster. Choose 'custom' to manually specify resource requirements or select a predefined profile. + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: CPU + loader: setLimits|cpu + watcher: + func: setRequests|cpu + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: Memory + loader: setLimits|memory + watcher: + func: setRequests|memory + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + label: Machine Profile + showLabels: true + type: block-layout + - elements: + - type: horizontal-layout + showLabels: true + elements: + - loader: getAdminOptions|storageClasses + label: Storage Class + schema: schema/properties/spec/properties/admin/properties/storageClasses/properties/default + type: select + - if: + type: function + name: showStorageSizeField + label: Storage Size + schema: schema/properties/spec/properties/persistence/properties/size + type: input + type: block-layout + - elements: + - loader: getAdminOptions|clusterIssuers + label: Cluster Issuers + validation: + type: required + schema: schema/properties/spec/properties/admin/properties/clusterIssuers/properties/default type: select - - if: showStorageSizeField - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/persistence/properties/size - type: input + type: block-layout + - label: Accept EULA? + schema: schema/properties/spec/properties/acceptEULA + type: switch + - init: + type: func + value: getDefaulPid + label: PID + watcher: + func: onPidChange + paths: + - temp/pid + options: + - Developer + - Express + - Standard + - Evaluation + - Enterprise + - EnterpriseCore + - Custom + validation: + type: required + schema: temp/pid + type: select + - if: + type: function + name: isPidCustom + label: Custom PID + watcher: + func: onCustomPidChange + paths: + - temp/customPid + validation: + type: required + schema: temp/customPid + type: input + - description: Configure Credentials, Deployment Mode etc. + elements: - elements: - - fetch: getAdminOptions|clusterIssuers - label: - text: labels.clusterIssuers - required: true - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterIssuers/properties/default - type: select - type: single-step-form - - label: - text: Accept EULA? - schema: - $ref: schema#/properties/spec/properties/acceptEULA - type: switch - - computed: getDefaulPid - label: - text: PID - onChange: onPidChange + - type: label-element + label: '' + subtitle: Add custom labels and annotations to your database resources for organization, monitoring, and integration with other Kubernetes tools and services. + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/annotations + label: Labels & Annotations + showLabels: true + hideBlock: true + type: block-layout + - init: + type: func + value: getDefault|deletionPolicy + customClass: mt-20 + if: + type: function + name: isToggleOn|deletionPolicy + label: Deletion Policy + watcher: + func: setStorageClass + paths: + - schema/properties/spec/properties/deletionPolicy options: - - Developer - - Express - - Standard - - Evaluation - - Enterprise - - EnterpriseCore - - Custom - required: true - schema: - $ref: discriminator#/properties/pid + - description: options.deletionPolicy.delete.description + text: Delete + value: Delete + - description: options.deletionPolicy.halt.description + text: Halt + value: Halt + - description: options.deletionPolicy.wipeOut.description + text: WipeOut + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: DoNotTerminate + value: DoNotTerminate + schema: schema/properties/spec/properties/deletionPolicy + type: select + - if: + type: function + name: getDefaultValue|spec/admin/authCredential/customize + label: Provide Authentication Credentials? + watcher: + func: onAuthChange + paths: + - temp/createAuthSecret + schema: temp/createAuthSecret + type: switch + - if: + type: function + name: showReferSecretSwitch + label: Refer existing Secret? + watcher: + func: onReferSecretChange + paths: + - temp/referSecret + schema: temp/referSecret + type: switch + - loader: getReferSecrets + if: + type: function + name: showSecretDropdown + label: Secret + schema: schema/properties/spec/properties/authSecret/properties/name type: select - - if: isPidCustom - label: - text: Custom PID - onChange: onCustomPidChange - required: true - schema: - $ref: discriminator#/properties/customPid + - if: + type: function + name: showReferSecret + label: password + schema: schema/properties/spec/properties/authSecret/properties/password type: input - - accordion: true - description: - text: Configure Credentials, Deployment Mode etc. - discriminator: - configDatabase: - default: false - type: boolean - createAuthSecret: - default: false - type: boolean - recovery: - default: false - type: boolean - referSecret: - default: false - type: boolean - elements: - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties + - if: + type: function + name: getDefaultValue|spec/admin/customConfiguration + label: Configure Database? + watcher: + func: clearConfiguration + paths: + - temp/configDatabase + schema: temp/configDatabase + type: switch + - if: + type: function + name: isConfigDatabaseOn + label: Configuration + # hasCopy: true + schema: schema/properties/spec/properties/configuration + type: textarea + - init: + type: func + value: getDefault|pointInTimeRecovery + if: + type: function + name: isToggleOn|pointInTimeRecovery + label: Point in-time Recovery? + schema: temp/recovery + type: switch + - elements: + - type: label-element + label: '' + subtitle: Configure point-in-time recovery to restore your database to a specific moment. Specify the source database namespace, name, and the exact timestamp for recovery. + - type: horizontal-layout + showLabels: true + elements: + - label: Namespace + watcher: + func: setPointInTimeRecovery + paths: + - temp/refNamespace + forceRequired: true + validation: + type: required + schema: temp/refNamespace type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties + - label: Name + watcher: + func: setPointInTimeRecovery + paths: + - temp/refDBName + validation: + type: required + schema: temp/refDBName type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - computed: getDefault|deletionPolicy - customClass: mt-20 - if: isToggleOn|deletionPolicy - 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/spec/properties/deletionPolicy - type: select - - if: getDefaultValue|spec/admin/authCredential/customize - label: - text: Provide Authentication Credentials? - onChange: onAuthChange - schema: - $ref: discriminator#/createAuthSecret - type: switch - - if: showReferSecretSwitch - label: - text: Refer existing Secret? - onChange: onReferSecretChange - schema: - $ref: discriminator#/referSecret - type: switch - - fetch: getReferSecrets - if: showSecretDropdown - label: - text: Secret - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/name - type: select - - if: showReferSecret - label: - text: labels.password - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/password - type: input - - computed: isConfigAvailable - if: getDefaultValue|spec/admin/customConfiguration - label: - text: Configure Database? - onChange: clearConfiguration - schema: - $ref: discriminator#/configDatabase - type: switch - - if: isConfigDatabaseOn - label: - text: Configuration - schema: - $ref: schema#/properties/spec/properties/configuration - type: editor - - computed: getDefault|pointInTimeRecovery - if: isToggleOn|pointInTimeRecovery - label: - text: Point in-time Recovery? - schema: - $ref: discriminator#/recovery + - customClass: mt-10 + label: Recovery Timestamp + schema: schema/properties/spec/properties/init/properties/archiver/properties/recoveryTimestamp + type: date-time + watcher: + func: onTimestampChange + paths: + - schema/properties/spec/properties/init/properties/archiver/properties/recoveryTimestamp + if: + type: function + name: showRecovery + label: Point in-time Recovery + showLabels: true + type: block-layout + - if: + type: function + name: isToggleOn|deployment + label: Deployment name + options: + - description: labels.deployment.shared + text: Shared + value: Shared + - description: labels.deployment.dedicated + text: Dedicated + value: Dedicated + schema: schema/properties/spec/properties/admin/properties/deployment/properties/default + type: radio + - if: + type: function + name: isToggleOn|clusterTier + isHorizontal: true + label: Cluster Tier + options: + - text: General Purpose + value: GeneralPurpose + - text: Memory Optimized + value: MemoryOptimized + - text: CPU Optimized + value: CPUOptimized + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/default + type: radio + - disableUnselect: true + loader: getAdminOptions|clusterTier/placement + if: + type: function + name: isToggleOn|clusterTier/placement + label: Placement + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + type: select + - disableUnselect: true + loader: getNodeTopology + if: + type: function + name: isToggleOn|clusterTier/nodeTopology + label: Node Topology + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + type: select + label: Advanced Configuration + showLabels: true + type: block-layout + - description: Enable Backup, Monitoring, TLS etc. + elements: + - elements: + - init: + type: func + value: setMonitoring + if: + type: function + name: isToggleOn|monitoring + label: Enable Monitoring? + watcher: + func: updateAlertValue + paths: + - temp/monitoring + schema: temp/monitoring type: switch - - discriminator: - refDBName: - type: string - refNamespace: - type: string - elements: - - label: - text: Namespace - onChange: setPointInTimeRecovery - required: true - schema: - $ref: discriminator#/refNamespace - type: input - - label: - text: Name - onChange: setPointInTimeRecovery - required: true - schema: - $ref: discriminator#/refDBName - type: input - - customClass: mt-10 - label: - text: Recovery Timestamp - schema: - $ref: schema#/properties/spec/properties/init/properties/archiver/properties/recoveryTimestamp - type: input - if: showRecovery - label: - text: Point in-time Recovery - schema: - $ref: schema#/properties/spec/properties/init/properties/archiver - show_label: true - type: single-step-form - - hasDescription: true - if: isToggleOn|deployment - label: - text: labels.deployment.name - options: - - description: labels.deployment.shared - text: Shared - value: Shared - - description: labels.deployment.dedicated - text: Dedicated - value: Dedicated - schema: - $ref: schema#/properties/spec/properties/admin/properties/deployment/properties/default - type: radio - - if: isToggleOn|clusterTier - isHorizontal: true - label: - text: labels.clusterTier - options: - - text: General Purpose - value: GeneralPurpose - - text: Memory Optimized - value: MemoryOptimized - - text: CPU Optimized - value: CPUOptimized - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/default - type: radio - - disableUnselect: true - fetch: getAdminOptions|clusterTier/placement - if: isToggleOn|clusterTier/placement - label: - text: labels.placement - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default - type: select - - disableUnselect: true - fetch: getNodeTopology - if: isToggleOn|clusterTier/nodeTopology - label: - text: labels.nodeTopology - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default - type: select - hideForm: true - label: - text: Advanced Configuration - show_label: true - type: single-step-form - - accordion: true - description: - text: Enable Backup, Monitoring, TLS etc. - discriminator: - backup: - default: false - type: boolean - elements: - - discriminator: - monitoring: - default: false - type: boolean - elements: - - computed: setMonitoring - if: isToggleOn|monitoring - label: - text: labels.enable_monitoring - onChange: updateAlertValue - schema: - $ref: discriminator#/monitoring - type: switch - type: single-step-form - - computed: setBackup - if: isToggleOn|backup - label: - text: Enable Backup? - onChange: onBackupSwitch - schema: - $ref: discriminator#/backup + type: block-layout + - init: + type: func + value: setBackup + if: + type: function + name: isToggleOn|backup + label: Enable Backup? + watcher: + func: onBackupSwitch + paths: + - temp/backup + schema: temp/backup + type: switch + - elements: + - disable: showArchiverAlert + label: Enable Archiver? + watcher: + func: onArchiverChange + paths: + - schema/properties/spec/properties/admin/properties/archiver/properties/enable/properties/default + schema: schema/properties/spec/properties/admin/properties/archiver/properties/enable/properties/default type: switch - - elements: - - disabled: showArchiverAlert - label: - text: Enable Archiver? - onChange: onArchiverChange - schema: - $ref: schema#/properties/spec/properties/admin/properties/archiver/properties/enable/properties/default - type: switch - - alertInfo: - show: true - type: neutral - if: showArchiverAlert - label: - text: The selected StorageClass does not support Archiver - type: label-element - if: showArchiver - type: single-step-form - - if: isToggleOn|tls - label: - text: Enable TLS? - schema: - $ref: schema#/properties/spec/properties/admin/properties/tls/properties/default + - if: + type: function + name: showArchiverAlert + label: The selected StorageClass does not support Archiver + type: warning + if: + type: function + name: showArchiver + type: block-layout + - if: + type: function + name: isToggleOn|tls + label: Enable TLS? + schema: schema/properties/spec/properties/admin/properties/tls/properties/default + type: switch + - elements: + - label: Expose via Gateway? + schema: schema/properties/spec/properties/admin/properties/expose/properties/default type: switch - - elements: - - label: - text: Expose via Gateway? - schema: - $ref: schema#/properties/spec/properties/admin/properties/expose/properties/default - type: switch - if: isToggleOn|expose - type: single-step-form - if: showAdditionalSettings - label: - text: Additional Options - show_label: true - type: single-step-form - type: single-step-form + if: + type: function + name: isToggleOn|expose + type: block-layout + if: + type: function + name: showAdditionalSettings + label: Additional Options + showLabels: true + type: block-layout id: options - title: steps.0.label + # title: steps.0.label type: multi-step-form diff --git a/charts/kubedbcom-mssqlserver-editor-options/ui/functions.js b/charts/kubedbcom-mssqlserver-editor-options/ui/functions.js index 3eb7a4f152..fff5610424 100644 --- a/charts/kubedbcom-mssqlserver-editor-options/ui/functions.js +++ b/charts/kubedbcom-mssqlserver-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -315,1096 +317,1206 @@ const modeDetails = { }, } -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) -function showStorageSizeField({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - const validType = ['Standalone', 'Topology'] - return validType.includes(modelPathValue) -} + setDiscriminatorValue('bundleApiLoaded', false) + setDiscriminatorValue('customPid', '') + setDiscriminatorValue('pid', '') + setDiscriminatorValue('configDatabase', false) + setDiscriminatorValue('createAuthSecret', false) + setDiscriminatorValue('recovery', false) + setDiscriminatorValue('referSecret', false) + setDiscriminatorValue('refDBName', '') + setDiscriminatorValue('refNamespace', '') + setDiscriminatorValue('backup', false) + setDiscriminatorValue('monitoring', false) + + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } -function onModeChange({ model, getValue, commit }) { - const dbMode = getValue(model, '/spec/mode') - commit('wizard/model$update', { - path: '/spec/replicas', - value: dbMode === 'Topology' ? 3 : 1, - force: true, - }) -} + function showStorageSizeField() { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + const validType = ['Standalone', 'Topology'] + return validType.includes(modelPathValue) + } + + function onModeChange() { + const dbMode = getValue(model, '/spec/mode') + commit('wizard/model$update', { + path: '/spec/replicas', + value: dbMode === 'Topology' ? 3 : 1, + force: true, + }) + } -function getMachineListForOptions({ model, getValue }) { - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') let array = [] + function getMachineListForOptions() { + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') - if (available.length) { - array = available.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - else { - let subText = '', - text = '' - const machineData = machinesFromPreset.find((val) => val.id === machine) - if (machineData) { - subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` - text = machineData.name ? machineData.name : machineData.id - } - return { text, subText, value: machine } - } - }) - } else { - array = machineList - .map((machine) => { + if (available.length) { + array = available.map((machine) => { if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + else { + let subText = '', + text = '' + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + text = machineData.name ? machineData.name : machineData.id + } + return { text, subText, value: machine } + } }) - .filter((val) => !!val) + } else { + array = machineList + .map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { text, subText, value: machine } + }) + .filter((val) => !!val) + } + return array } - return array -} -function setLimits({ model, getValue, commit, watchDependency }, resource, type) { - const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' - watchDependency(`model#${path}`) - const selectedMachine = getValue(model, path) || 'custom' - const reqCommitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - const comparePath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - - const resourceValue = getValue(model, comparePath) - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - - let cpu = '', - memory = '' - if (available.length && selectedMachine !== 'custom') { - const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) - if (machineData) { - cpu = machineData.limits.cpu - memory = machineData.limits.memory + function setLimits(resource, type) { + const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' + // watchDependency(`model#${path}`) + const selectedMachine = getValue(model, path) || 'custom' + const reqCommitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + const comparePath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + + const resourceValue = getValue(model, comparePath) + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + let cpu = '', + memory = '' + if (available.length && selectedMachine !== 'custom') { + const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) + if (machineData) { + cpu = machineData.limits.cpu + memory = machineData.limits.memory + } + } else { + if (selectedMachine === 'custom') { + cpu = resourceValue + memory = resourceValue + } else { + cpu = machines[selectedMachine].resources.limits.cpu + memory = machines[selectedMachine].resources.limits.memory + } } - } else { - if (selectedMachine === 'custom') { - cpu = resourceValue - memory = resourceValue + + if (resource === 'memory') { + commit('wizard/model$update', { + path: reqCommitPath, + value: memory, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: memory, + force: true, + }) + return memory } else { - cpu = machines[selectedMachine].resources.limits.cpu - memory = machines[selectedMachine].resources.limits.memory + commit('wizard/model$update', { + path: reqCommitPath, + value: cpu, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: cpu, + force: true, + }) + return cpu } } - if (resource === 'memory') { + function setRequests(resource, type) { + const modelPath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + + const fullpath = `/spec/podResources/machine` + const modelPathValue = getValue(model, fullpath) + commit('wizard/model$update', { - path: reqCommitPath, - value: memory, + path: commitPath, + value: val, force: true, }) - commit('wizard/model$update', { - path: comparePath, - value: memory, - force: true, + + if (modelPathValue === 'custom') { + return + } + let commitCpuMemory, ModelPathValue + if (resource && type) { + const fullPath = `/spec/${type}/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/${type}/podResources/resources/requests/${resource}` + } else { + const fullPath = `/spec/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/podResources/resources/requests/${resource}` + } + let cpuMemoryValue + array.forEach((item) => { + if (item.value === ModelPathValue) { + // Parse subText like "CPU: 2, Memory: 2Gi" + const subText = item.subText || '' + if (resource === 'cpu') { + // Extract CPU value + const cpuMatch = subText.match(/CPU:\s*([^,]+)/) + cpuMemoryValue = cpuMatch ? cpuMatch[1].trim() : '' + } else if (resource === 'memory') { + // Extract Memory value + const memoryMatch = subText.match(/Memory:\s*(.+)/) + cpuMemoryValue = memoryMatch ? memoryMatch[1].trim() : '' + } + } }) - return memory - } else { commit('wizard/model$update', { - path: reqCommitPath, - value: cpu, + path: commitCpuMemory, + value: cpuMemoryValue, force: true, }) + return cpuMemoryValue + } + + function setRequests(resource) { + const modelPath = `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + commitPath = `/spec/podResources/resources/limits/${resource}` commit('wizard/model$update', { - path: comparePath, - value: cpu, + path: commitPath, + value: val, force: true, }) - return cpu } -} - -function setRequests({ getValue, model, commit }, resource) { - const modelPath = `/spec/podResources/resources/requests/${resource}` - const val = getValue(model, modelPath) - commitPath = `/spec/podResources/resources/limits/${resource}` - commit('wizard/model$update', { - path: commitPath, - value: val, - force: true, - }) -} -function isMachineCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue === 'custom' -} + function isMachineCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue === 'custom' + } -function isMachineNotCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue !== 'custom' && !!modelPathValue -} + function isMachineNotCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue !== 'custom' && !!modelPathValue + } -function setMachineToCustom({ getValue, model }) { - const machine = getValue(model, '/spec/admin/machineProfiles/default') - return machine || 'custom' -} + function setMachineToCustom() { + const machine = getValue(model, '/spec/admin/machineProfiles/default') + return machine || 'custom' + } -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function getCreateNameSpaceUrl() { + 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + const domain = storeGet('/domain') || '' + if (domain.includes('bb.test')) { + return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } } -} -const ifCapiProviderIsNotEmpty = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/provider') - const val = getValue(model, '/form/capi/provider') - if (val) return true -} + const ifCapiProviderIsNotEmpty = () => { + // watchDependency('model#/form/capi/provider') + const val = getValue(model, '/form/capi/provider') + if (val) return true + } -const showMultiselectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') + const showMultiselectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') - if (val === 'capz' && ifDedicated({ model, getValue })) return true -} + if (val === 'capz' && ifDedicated()) return true + } -const showSelectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') - if (val !== 'capz' && ifDedicated({ model, getValue })) return true -} + const showSelectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') + if (val !== 'capz' && ifDedicated()) return true + } -const ifDedicated = ({ model, getValue }) => { - const val = getValue(model, 'form/capi/dedicated') - if (val) return true -} + const ifDedicated = () => { + const val = getValue(model, 'form/capi/dedicated') + if (val) return true + } -const dedicatedOnChange = ({ model, getValue, commit }) => { - const val = getValue(model, 'form/capi/dedicated') - if (!val) { - commit('wizard/model$delete', 'form/capi/zones') - commit('wizard/model$delete', 'form/capi/sku') + const dedicatedOnChange = () => { + const val = getValue(model, 'form/capi/dedicated') + if (!val) { + commit('wizard/model$delete', 'form/capi/zones') + commit('wizard/model$delete', 'form/capi/sku') + } } -} -const ifZones = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/zones') - watchDependency('model#/form/capi/dedicated') - const zones = getValue(model, 'form/capi/zones') || [] - const isDedicated = getValue(model, 'form/capi/dedicated') - if (zones.length && isDedicated) return true -} + const ifZones = () => { + // watchDependency('model#/form/capi/zones') + // watchDependency('model#/form/capi/dedicated') + const zones = getValue(model, 'form/capi/zones') || [] + const isDedicated = getValue(model, 'form/capi/dedicated') + if (zones.length && isDedicated) return true + } -const zonesOnChange = ({ model, getValue, commit }) => { - const zones = getValue(model, 'form/capi/zones') || [] - if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') -} + const zonesOnChange = () => { + const zones = getValue(model, 'form/capi/zones') || [] + if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') + } -async function getZones({ storeGet, axios, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const isDedicated = getValue(model, 'form/capi/dedicated') - if (isDedicated) { - try { - const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) - const val = resp.data.map((item) => { - return { value: item, text: item } - }) - return val - } catch (e) { - console.log(e) - return [] + async function getZones() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const isDedicated = getValue(model, 'form/capi/dedicated') + if (isDedicated) { + try { + const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) + const val = resp.data.map((item) => { + return { value: item, text: item } + }) + return val + } catch (e) { + console.log(e) + return [] + } } } -} -async function getSKU({ storeGet, axios, model, getValue, watchDependency }) { - watchDependency('model#/form/capi/zones') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const zones = getValue(model, 'form/capi/zones') || [] - if (zones.length) { - try { - let url = `clustersv2/${owner}/${cluster}/vms?` - if (typeof zones === 'string') { - url += `zones=${encodeURIComponent(zones)}` - } else { - zones.forEach((item) => { - url += `zones=${encodeURIComponent(item)}&` + async function getSKU() { + // watchDependency('model#/form/capi/zones') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const zones = getValue(model, 'form/capi/zones') || [] + if (zones.length) { + try { + let url = `clustersv2/${owner}/${cluster}/vms?` + if (typeof zones === 'string') { + url += `zones=${encodeURIComponent(zones)}` + } else { + zones.forEach((item) => { + url += `zones=${encodeURIComponent(item)}&` + }) + url = url.slice(0, -1) + } + const resp = await axios.get(url) + const val = resp.data.map((item) => { + return { + value: item.name, + text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, + } }) - url = url.slice(0, -1) + return val + } catch (e) { + console.log(e) + return [] } - const resp = await axios.get(url) - const val = resp.data.map((item) => { - return { - value: item.name, - text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, - } - }) - return val - } catch (e) { - console.log(e) - return [] } } -} - -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} -function setStorageClass({ model, getValue, commit, discriminator, watchDependency }) { - const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' - let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' - const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] - const suffix = '-retain' - - const simpleClassList = storageClassList.filter((item) => { - return !item.endsWith(suffix) - }) - const retainClassList = storageClassList.filter((item) => { - return item.endsWith(suffix) - }) - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] - } else { - storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] - } - - const isChangeable = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'storageClasses', - ) - if (isChangeable && storageClass) { - commit('wizard/model$update', { - path: '/spec/admin/storageClasses/default', - value: storageClass, - force: true, - }) + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false } -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function setStorageClass() { + const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' + let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' + const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] + const suffix = '-retain' -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], - }, - }, - ) - const projects = resp?.data?.status?.projects - if (projects) { - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - namespaces = projectsNamespace + const simpleClassList = storageClassList.filter((item) => { + return !item.endsWith(suffix) + }) + const retainClassList = storageClassList.filter((item) => { + return item.endsWith(suffix) + }) + if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { + storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] } else { - namespaces = resp?.data?.status?.namespaces || [] + storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] } - return namespaces - } catch (e) { - console.log(e) - return [] - } -} - -function showRecovery({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/recovery') - const isRecoveryOn = getValue(discriminator, '/recovery') || '' - return isRecoveryOn -} -function onAuthChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/authSecret/password', - value: '', - force: true, - }) -} - -function clearConfiguration({ discriminator, getValue, commit }) { - const configOn = getValue(discriminator, '/configDatabase') - - if (!configOn) { - commit('wizard/model$delete', '/spec/configuration') - } -} -function isConfigDatabaseOn({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configDatabase') - return getValue(discriminator, '/configDatabase') -} - -function showIssuer({ model, getValue, watchDependency, discriminator }) { - watchDependency('model#/spec/admin/tls/default') - const isTlsEnabled = getValue(model, '/spec/admin/tls/default') - const isIssuerToggleEnabled = isToggleOn( - { getValue, model, watchDependency, discriminator }, - 'clusterIssuers', - ) - return isTlsEnabled && isIssuerToggleEnabled -} - -function setMonitoring({ getValue, model }) { - const agent = getValue(model, '/spec/admin/monitoring/agent') || '' - return !!agent -} - -function updateAlertValue({ commit, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const alert = isMonitorEnabled ? 'warning' : 'none' - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: alert, - force: true, - }) - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} - -function showAlerts({ watchDependency, model, getValue, discriminator }) { - watchDependency('discriminator#/monitoring') - const isMonitorEnabled = getValue(discriminator, '/monitoring') - return ( - isMonitorEnabled && isToggleOn({ getValue, model, discriminator, watchDependency }, 'alert') - ) -} - -function setBackup({ model, getValue }) { - const backup = getValue(model, '/spec/backup/tool') - const val = getValue(model, '/spec/admin/backup/enable/default') - return backup === 'KubeStash' && features.includes('backup') && val -} - -function onBackupSwitch({ discriminator, getValue, commit }) { - const isBackupOn = getValue(discriminator, '/backup') - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: isBackupOn ? 'KubeStash' : '', - force: true, - }) -} - -let placement = [] -let versions = [] -let storageClass = [] -let clusterIssuers = [] -let nodetopologiesShared = [] -let nodetopologiesDedicated = [] -let features = [] -let namespaces = [] -async function initBundle({ commit, model, getValue, axios, storeGet, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - - let db = getValue(model, '/metadata/resource/kind') - db = db.toLowerCase() - let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` - const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - - try { - const resp = await axios.get(url) - features = resp.data.features || [] - placement = resp.data.placementpolicies || [] - versions = resp.data.versions || [] - storageClass = resp.data.storageclasses || [] - clusterIssuers = resp.data.clusterissuers || [] - nodetopologiesDedicated = resp.data.dedicated || [] - nodetopologiesShared = resp.data.shared || [] - - const response = await axios.get(annotationUrl) - const annotations = response.data?.metadata?.annotations || {} - const uidRange = annotations['openshift.io/sa.scc.uid-range'] - if (uidRange) { - const val = uidRange.split('/')[0] + const isChangeable = isToggleOn('storageClasses') + if (isChangeable && storageClass) { commit('wizard/model$update', { - path: '/spec/openshift/securityContext/runAsUser', - value: val, + path: '/spec/admin/storageClasses/default', + value: storageClass, force: true, }) } - } catch (e) { - console.log(e) } - commit('wizard/model$update', { - path: '/spec/deletionPolicy', - value: getDefault({ getValue, model }, 'deletionPolicy'), - force: true, - }) + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } - if (!getValue(model, `/spec/admin/databases/MSSQLServer/mode/toggle`)) { - let defMode = getDefault({ getValue, model }, 'databases/MSSQLServer/mode') || '' - if (defMode === '') { - const arr = getValue(model, '/spec/databases/MSSQLServer/mode/available') || [] - if (arr.length) defMode = arr[0] + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, + }, + ) + const projects = resp?.data?.status?.projects + if (projects) { + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + namespaces = projectsNamespace + } else { + namespaces = resp?.data?.status?.namespaces || [] + } + return namespaces + } catch (e) { + console.log(e) + return [] } - commit('wizard/model$update', { - path: '/spec/mode', - value: defMode, - force: true, - }) } - if (!features.includes('tls')) { - commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: false, - force: true, - }) + function showRecovery() { + // watchDependency('discriminator#/recovery') + const isRecoveryOn = getValue(discriminator, '/recovery') || '' + return isRecoveryOn } - if (!features.includes('binding')) { + + function onAuthChange() { commit('wizard/model$update', { - path: '/spec/admin/expose/default', - value: false, + path: '/spec/authSecret/name', + value: '', force: true, }) - } - if (!features.includes('monitoring')) { commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', + path: '/spec/authSecret/password', value: '', force: true, }) + } + + function clearConfiguration() { + const configOn = getValue(discriminator, '/configDatabase') + + if (!configOn) { + commit('wizard/model$delete', '/spec/configuration') + } + } + + function isConfigDatabaseOn() { + // watchDependency('discriminator#/configDatabase') + return getValue(discriminator, '/configDatabase') + } + + function showIssuer() { + // watchDependency('model#/spec/admin/tls/default') + const isTlsEnabled = getValue(model, '/spec/admin/tls/default') + const isIssuerToggleEnabled = isToggleOn('clusterIssuers') + return isTlsEnabled && isIssuerToggleEnabled + } + + function setMonitoring() { + const agent = getValue(model, '/spec/admin/monitoring/agent') || '' + return !!agent + } + + function updateAlertValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const alert = isMonitorEnabled ? 'warning' : 'none' + // update alert value depend on monitoring profile commit('wizard/model$update', { path: '/form/alert/enabled', - value: 'none', + value: alert, force: true, }) - } - if (!features.includes('backup')) { + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, + path: '/spec/admin/monitoring/agent', + value: agent, force: true, }) + } + + function showAlerts() { + // watchDependency('discriminator#/monitoring') + const isMonitorEnabled = getValue(discriminator, '/monitoring') + return isMonitorEnabled && isToggleOn('alert') + } + + function setBackup() { + const backup = getValue(model, '/spec/backup/tool') + const val = getValue(model, '/spec/admin/backup/enable/default') + return backup === 'KubeStash' && features.includes('backup') && val + } + + function onBackupSwitch() { + const isBackupOn = getValue(discriminator, '/backup') commit('wizard/model$update', { path: '/spec/backup/tool', - value: '', + value: isBackupOn ? 'KubeStash' : '', force: true, }) } - namespaces = getNamespaces({ axios, storeGet }) - setDiscriminatorValue('/bundleApiLoaded', true) -} -function fetchNamespaces({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return namespaces -} + let placement = [] + let versions = [] + let storageClass = [] + let clusterIssuers = [] + let nodetopologiesShared = [] + let nodetopologiesDedicated = [] + let features = [] + let namespaces = [] + + async function initBundle() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + + let db = getValue(model, '/metadata/resource/kind') + db = db.toLowerCase() + let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` + const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` -async function getRecoveryNames({ getValue, model, watchDependency, storeGet, axios }, type) { - watchDependency(`model#/spec/init/archiver/${type}/namespace`) - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/spec/init/archiver/${type}/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${namespace}/repositories` - if (type === 'encryptionSecret') - url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - const options = [] - if (namespace) { try { const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) + features = resp.data.features || [] + placement = resp.data.placementpolicies || [] + versions = resp.data.versions || [] + storageClass = resp.data.storageclasses || [] + clusterIssuers = resp.data.clusterissuers || [] + nodetopologiesDedicated = resp.data.dedicated || [] + nodetopologiesShared = resp.data.shared || [] + + const response = await axios.get(annotationUrl) + const annotations = response.data?.metadata?.annotations || {} + const uidRange = annotations['openshift.io/sa.scc.uid-range'] + if (uidRange) { + const val = uidRange.split('/')[0] + commit('wizard/model$update', { + path: '/spec/openshift/securityContext/runAsUser', + value: val, + force: true, + }) + } } catch (e) { console.log(e) } - } - return options -} - -function fetchOptions({ model, getValue, commit }, type) { - let kind = getValue(model, '/metadata/resource/kind') - - let returnArray = [] - if (type === 'clusterTier/placement') { - returnArray = placement - } else if (type === `databases/${kind}/versions`) { - returnArray = versions - } else if (type === 'storageClasses') { - returnArray = storageClass - } else if (type === 'clusterIssuers') { - returnArray = clusterIssuers - } - if (returnArray.length === 1) { - const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: path, - value: returnArray[0], + path: '/spec/deletionPolicy', + value: getDefault('deletionPolicy'), force: true, }) + + if (!getValue(model, `/spec/admin/databases/MSSQLServer/mode/toggle`)) { + let defMode = getDefault('databases/MSSQLServer/mode') || '' + if (defMode === '') { + const arr = getValue(model, '/spec/databases/MSSQLServer/mode/available') || [] + if (arr.length) defMode = arr[0] + } + commit('wizard/model$update', { + path: '/spec/mode', + value: defMode, + force: true, + }) + } + + if (!features.includes('tls')) { + commit('wizard/model$update', { + path: '/spec/admin/tls/default', + value: false, + force: true, + }) + } + if (!features.includes('binding')) { + commit('wizard/model$update', { + path: '/spec/admin/expose/default', + value: false, + force: true, + }) + } + if (!features.includes('monitoring')) { + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: 'none', + force: true, + }) + } + if (!features.includes('backup')) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: '', + force: true, + }) + } + namespaces = getNamespaces() + setDiscriminatorValue('/bundleApiLoaded', true) } - return returnArray -} + function fetchNamespaces() { + // watchDependency('discriminator#/bundleApiLoaded') + return namespaces + } + + async function getRecoveryNames(type) { + // watchDependency(`model#/spec/init/archiver/${type}/namespace`) + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/spec/init/archiver/${type}/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${namespace}/repositories` + if (type === 'encryptionSecret') + url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` + const options = [] + if (namespace) { + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + } + return options + } -let archiverMap = [] -let archiverCalled = false + function fetchOptions(type) { + let kind = getValue(model, '/metadata/resource/kind') + + let returnArray = [] + if (type === 'clusterTier/placement') { + returnArray = placement + } else if (type === `databases/${kind}/versions`) { + returnArray = versions + } else if (type === 'storageClasses') { + returnArray = storageClass + } else if (type === 'clusterIssuers') { + returnArray = clusterIssuers + } -function getAdminOptions({ getValue, model, watchDependency, axios, storeGet, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') + if (returnArray.length === 1) { + const path = `/spec/admin/${type}/default` + commit('wizard/model$update', { + path: path, + value: returnArray[0], + force: true, + }) + } - if (type === 'storageClasses' && !archiverCalled) { - getArchiverName({ axios, storeGet }) + return returnArray } - const options = getValue(model, `/spec/admin/${type}/available`) || [] + let archiverMap = [] + let archiverCalled = false + + function getAdminOptions(type) { + // watchDependency('discriminator#/bundleApiLoaded') + + if (type === 'storageClasses' && !archiverCalled) { + getArchiverName() + } + + const options = getValue(model, `/spec/admin/${type}/available`) || [] - if (options.length === 0) { - return fetchOptions({ model, getValue, commit }, type) + if (options.length === 0) { + return fetchOptions(type) + } + if (type.endsWith('/mode')) { + return ( + options?.map((item) => ({ + description: modeDetails[item]?.description || '', + text: modeDetails[item]?.text || '', + value: item, + })) || [] + ) + } + return options } - if (type.endsWith('/mode')) { - return ( - options?.map((item) => ({ - description: modeDetails[item]?.description || '', - text: modeDetails[item]?.text || '', - value: item, - })) || [] - ) + + function showArchiver() { + return checkIfFeatureOn('archiver') } - return options -} -function showArchiver({ getValue, model }) { - return checkIfFeatureOn({ getValue, model }, 'archiver') -} + async function getArchiverName() { + try { + archiverCalled = true + const params = storeGet('/route/params') + const { user, cluster, group, resource } = params + const url = `/clusters/${user}/${cluster}/proxy/storage.k8s.io/v1/storageclasses` + const resp = await axios.get(url) -async function getArchiverName({ axios, storeGet }) { - try { - archiverCalled = true - const params = storeGet('/route/params') - const { user, cluster, group, resource } = params - const url = `/clusters/${user}/${cluster}/proxy/storage.k8s.io/v1/storageclasses` - const resp = await axios.get(url) - - resp.data?.items?.forEach((item) => { - const annotations = item.metadata?.annotations - const classname = item.metadata?.name - const annotationKeyToFind = `${resource}.${group}/archiver` - archiverMap.push({ storageClass: classname, annotation: annotations[annotationKeyToFind] }) - return resp.data - }) - } catch (e) { - console.log(e) + resp.data?.items?.forEach((item) => { + const annotations = item.metadata?.annotations + const classname = item.metadata?.name + const annotationKeyToFind = `${resource}.${group}/archiver` + archiverMap.push({ storageClass: classname, annotation: annotations[annotationKeyToFind] }) + return resp.data + }) + } catch (e) { + console.log(e) + } } -} -function onArchiverChange({ model, getValue, commit }) { - const isArchiverOn = getValue(model, '/spec/admin/archiver/enable/default') + function onArchiverChange() { + const isArchiverOn = getValue(model, '/spec/admin/archiver/enable/default') - const stClass = getValue(model, '/spec/admin/storageClasses/default') - const found = archiverMap.find((item) => item.storageClass === stClass) - const via = getValue(model, '/spec/admin/archiver/via') + const stClass = getValue(model, '/spec/admin/storageClasses/default') + const found = archiverMap.find((item) => item.storageClass === stClass) + const via = getValue(model, '/spec/admin/archiver/via') - if (!isArchiverOn) { - commit('wizard/model$update', { - path: '/spec/archiverName', - value: '', - force: true, - }) - } else { - if (via === 'VolumeSnapshotter') { + if (!isArchiverOn) { commit('wizard/model$update', { path: '/spec/archiverName', - value: found.annotation, + value: '', force: true, }) } else { - const kind = getValue(model, '/metadata/resource/kind') - commit('wizard/model$update', { - path: '/spec/archiverName', - value: kind.toLowerCase(), - force: true, - }) + if (via === 'VolumeSnapshotter') { + commit('wizard/model$update', { + path: '/spec/archiverName', + value: found.annotation, + force: true, + }) + } else { + const kind = getValue(model, '/metadata/resource/kind') + commit('wizard/model$update', { + path: '/spec/archiverName', + value: kind.toLowerCase(), + force: true, + }) + } } } -} -function showArchiverAlert({ watchDependency, model, getValue, commit }) { - watchDependency('model#/spec/admin/storageClasses/default') + function showArchiverAlert() { + // watchDependency('model#/spec/admin/storageClasses/default') - const mode = getValue(model, '/spec/mode') - if (mode === 'Standalone') return false + const mode = getValue(model, '/spec/mode') + if (mode === 'Standalone') return false - const via = getValue(model, '/spec/admin/archiver/via') + const via = getValue(model, '/spec/admin/archiver/via') - if (via === 'VolumeSnapshotter') { - // toggle archiver to false when storageClass annotation not found - const stClass = getValue(model, '/spec/admin/storageClasses/default') - const found = archiverMap.find((item) => item.storageClass === stClass) - const show = !found?.annotation - if (show) { - commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, - force: true, - }) - return true - } else onArchiverChange({ model, getValue, commit }) - } else onArchiverChange({ model, getValue, commit }) - return false -} - -function checkIfFeatureOn({ getValue, model }, type) { - let val = getValue(model, `/spec/admin/${type}/toggle`) - if (type === 'backup' || type === 'archiver') { - val = getValue(model, `/spec/admin/${type}/enable/toggle`) + if (via === 'VolumeSnapshotter') { + // toggle archiver to false when storageClass annotation not found + const stClass = getValue(model, '/spec/admin/storageClasses/default') + const found = archiverMap.find((item) => item.storageClass === stClass) + const show = !found?.annotation + if (show) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + return true + } else onArchiverChange() + } else onArchiverChange() + return false } - const backupVal = getValue(model, '/spec/backup/tool') - if (type === 'backup') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } else if (type === 'tls') { - return features.includes('tls') && val - } else if (type === 'expose') { - return features.includes('binding') && val - } else if (type === 'monitoring') { - return features.includes('monitoring') && val - } else if (type === 'archiver') { - return features.includes('backup') && val + let backupToolInitialValue = '' + function checkIfFeatureOn(type) { + let val = getValue(model, `/spec/admin/${type}/toggle`) + if (type === 'backup' || type === 'archiver') { + val = getValue(model, `/spec/admin/${type}/enable/toggle`) + } + const backupVal = getValue(model, '/spec/backup/tool') + if (type === 'backup') { + if (backupToolInitialValue === '') { + backupToolInitialValue = + features.includes('backup') && backupVal === 'KubeStash' && val ? 'on' : 'off' + return features.includes('backup') && backupVal === 'KubeStash' && val + } else { + if (backupToolInitialValue === 'on') { + return true + } else { + return false + } + } + } else if (type === 'tls') { + return features.includes('tls') && val + } else if (type === 'expose') { + return features.includes('binding') && val + } else if (type === 'monitoring') { + return features.includes('monitoring') && val + } else if (type === 'archiver') { + return features.includes('backup') && val + } } -} -function isToggleOn({ getValue, model, discriminator, watchDependency, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') - watchDependency('model#/spec/admin/deployment/default') - const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') - let deploymentType = getValue(model, `/spec/admin/deployment/default`) - if (type === 'tls' || type === 'backup' || type === 'expose' || type === 'monitoring') { - return checkIfFeatureOn({ getValue, model }, type) - } else if ( - type === 'clusterTier' || - type === 'clusterTier/placement' || - type === 'clusterTier/nodeTopology' - ) { - if (deploymentType === 'Dedicated' && bundleApiLoaded) return true - else return false - } else if (type === 'deployment') { - const deploymentType = getValue(model, '/spec/admin/deployment/default') - if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { - commit('wizard/model$update', { - path: '/spec/admin/deployment/default', - value: 'Shared', - force: true, - }) - } - return ( - getValue(model, `/spec/admin/${type}/toggle`) && - nodetopologiesDedicated.length && - bundleApiLoaded - ) - } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded -} + function isToggleOn(type) { + // watchDependency('discriminator#/bundleApiLoaded') + // watchDependency('model#/spec/admin/deployment/default') + const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') + let deploymentType = getValue(model, `/spec/admin/deployment/default`) + if (type === 'tls' || type === 'backup' || type === 'expose' || type === 'monitoring') { + return checkIfFeatureOn(type) + } else if ( + type === 'clusterTier' || + type === 'clusterTier/placement' || + type === 'clusterTier/nodeTopology' + ) { + if (deploymentType === 'Dedicated' && bundleApiLoaded) return true + else return false + } else if (type === 'deployment') { + const deploymentType = getValue(model, '/spec/admin/deployment/default') + if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + commit('wizard/model$update', { + path: '/spec/admin/deployment/default', + value: 'Shared', + force: true, + }) + } + return ( + getValue(model, `/spec/admin/${type}/toggle`) && + nodetopologiesDedicated.length && + bundleApiLoaded + ) + } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded + } -async function getNodeTopology({ model, getValue, axios, storeGet, watchDependency }) { - watchDependency('model#/spec/admin/deployment/default') - watchDependency('model#/spec/admin/clusterTier/default') - const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' - const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' - let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + async function getNodeTopology() { + // watchDependency('model#/spec/admin/deployment/default') + // watchDependency('model#/spec/admin/clusterTier/default') + const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' + const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' + let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] - const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' - if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared - else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared + else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated - const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) - return filteredList -} + const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) + return filteredList + } -function filterNodeTopology(list, tier, provider) { - // first filter the list from value that exists from the filtered list got from API - const filteredlist = list + function filterNodeTopology(list, tier, provider) { + // first filter the list from value that exists from the filtered list got from API + const filteredlist = list - // filter the list based on clusterTier - if (provider === 'EKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('c') - else if (tier === 'MemoryOptimized') return item.startsWith('r') - else return !item.startsWith('c') && !item.startsWith('r') - }) - } else if (provider === 'AKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - else - return ( - !(item.startsWith('f') || item.startsWith('fx')) && - !( + // filter the list based on clusterTier + if (provider === 'EKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('c') + else if (tier === 'MemoryOptimized') return item.startsWith('r') + else return !item.startsWith('c') && !item.startsWith('r') + }) + } else if (provider === 'AKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('e') || item.startsWith('eb') || item.startsWith('ec') || item.startsWith('m') || item.startsWith('d') ) - ) - }) - } else if (provider === 'GKE') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') - return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - else - return ( - !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && - !( + else + return ( + !(item.startsWith('f') || item.startsWith('fx')) && + !( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + ) + }) + } else if (provider === 'GKE') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') + return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('x4') || item.startsWith('m1') || item.startsWith('m2') || item.startsWith('m3') ) - ) - }) - } else return filteredlist -} + else + return ( + !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && + !( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + ) + }) + } else return filteredlist + } -function returnFalse() { - return false -} + function returnFalse() { + return false + } -function showAdditionalSettings({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return features.length -} + function showAdditionalSettings() { + // watchDependency('discriminator#/bundleApiLoaded') + return features.length + } -function getDefault({ getValue, model }, type) { - const val = getValue(model, `/spec/admin/${type}/default`) || '' - return val -} + function getDefault(type) { + const val = getValue(model, `/spec/admin/${type}/default`) || '' + return val + } -function getDefaulPid({ getValue, model }) { - return (pid = getValue(model, '/spec/pid') || '') -} + function getDefaulPid() { + return (pid = getValue(model, '/spec/pid') || '') + } -function onPidChange({ getValue, discriminator, commit }) { - const pid = getValue(discriminator, '/pid') - commit('wizard/model$update', { - path: '/spec/pid', - value: pid !== 'Custom' ? pid : '', - force: true, - }) -} + function onPidChange() { + const pid = getValue(discriminator, '/pid') + commit('wizard/model$update', { + path: '/spec/pid', + value: pid !== 'Custom' ? pid : '', + force: true, + }) + } -function isPidCustom({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/pid') - const pid = getValue(discriminator, '/pid') - return pid === 'Custom' -} + function isPidCustom() { + // watchDependency('discriminator#/pid') + const pid = getValue(discriminator, '/pid') + return pid === 'Custom' + } -function onCustomPidChange({ getValue, discriminator, commit }) { - const customPid = getValue(discriminator, '/customPid') - commit('wizard/model$update', { - path: '/spec/pid', - value: customPid, - force: true, - }) -} + function onCustomPidChange() { + const customPid = getValue(discriminator, '/customPid') + commit('wizard/model$update', { + path: '/spec/pid', + value: customPid, + force: true, + }) + } -function convertToLocal(input) { - const date = new Date(input) + function convertToLocal(input) { + const date = new Date(input) - if (isNaN(date.getTime())) { - return null + if (isNaN(date.getTime())) { + return null + } + + return date.toString() } - return date.toString() -} + function convertToUTC(localTime) { + const date = new Date(localTime) + if (isNaN(date.getTime())) return -function getComponentLogStats(snapshot) { - if (!snapshot || !snapshot.status || !snapshot.status.components) { - return null + const utcString = date.toISOString() + return utcString } - const components = snapshot.status.components - const appKind = snapshot.spec?.appRef?.kind + function onTimestampChange() { + const localTime = getValue(model, '/spec/init/archiver/recoveryTimestamp') + if (!localTime) return - if (appKind === 'MongoDB') { - for (const [key, value] of Object.entries(components)) { - if (key.endsWith('0') && value.logStats) { - return value.logStats - } + const utcString = convertToUTC(localTime) + + // Only update if the value is valid & not already in UTC format + if (utcString && localTime !== utcString) { + commit('wizard/model$update', { + path: '/spec/init/archiver/recoveryTimestamp', + value: utcString, + force: true, + }) } } - if (components['wal'] && components['wal'].logStats) { - return components['wal'].logStats - } + function getComponentLogStats(snapshot) { + if (!snapshot || !snapshot.status || !snapshot.status.components) { + return null + } - return null -} + const components = snapshot.status.components + const appKind = snapshot.spec?.appRef?.kind -async function setPointInTimeRecovery({ commit, axios, storeGet, discriminator, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const refNamespace = getValue(discriminator, '/refNamespace') - const refDBName = getValue(discriminator, '/refDBName') + if (appKind === 'MongoDB') { + for (const [key, value] of Object.entries(components)) { + if (key.endsWith('0') && value.logStats) { + return value.logStats + } + } + } - try { - const repositoriesUrl = `clusters/${owner}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${refNamespace}/repositories/${refDBName}-full` - const snapshotsUrl = `clusters/${owner}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${refNamespace}/snapshots/${refDBName}-incremental-snapshot` - const repositoriesResp = await axios.get(repositoriesUrl) - const snapshotsResp = await axios.get(snapshotsUrl) + if (components['wal'] && components['wal'].logStats) { + return components['wal'].logStats + } - commit('wizard/model$update', { - path: `/spec/init/archiver/encryptionSecret/name`, - value: repositoriesResp.data?.spec.encryptionSecret.name, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/encryptionSecret/namespace`, - value: repositoriesResp.data?.spec.encryptionSecret.namespace, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/fullDBRepository/name`, - value: `${refDBName}-full`, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/fullDBRepository/namespace`, - value: `${refNamespace}`, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/manifestRepository/name`, - value: `${refDBName}-manifest`, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/manifestRepository/namespace`, - value: `${refNamespace}`, - force: true, - }) + return null + } - const resp = getComponentLogStats(snapshotsResp.data) + async function setPointInTimeRecovery() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const refNamespace = getValue(discriminator, '/refNamespace') + const refDBName = getValue(discriminator, '/refDBName') - commit('wizard/model$update', { - path: `/spec/init/archiver/recoveryTimestamp`, - value: convertToLocal(resp?.end), - force: true, - }) - commit('wizard/model$update', { - path: `/minDate`, - value: convertToLocal(resp?.start), - force: true, - }) - commit('wizard/model$update', { - path: `/maxDate`, - value: convertToLocal(resp?.end), - force: true, - }) - } catch (e) { - commit('wizard/model$update', { - path: `/spec/init/archiver/recoveryTimestamp`, - value: '', - force: true, - }) - commit('wizard/model$update', { - path: `/minDate`, - value: '', - force: true, - }) - commit('wizard/model$update', { - path: `/maxDate`, - value: '', - force: true, - }) - console.log(e) - } -} + try { + const repositoriesUrl = `clusters/${owner}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${refNamespace}/repositories/${refDBName}-full` + const snapshotsUrl = `clusters/${owner}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${refNamespace}/snapshots/${refDBName}-incremental-snapshot` + const repositoriesResp = await axios.get(repositoriesUrl) + const snapshotsResp = await axios.get(snapshotsUrl) -function isConfigAvailable({ getValue, model }) { - const val = getValue(model, '/spec/configuration') - return val !== '' -} + commit('wizard/model$update', { + path: `/spec/init/archiver/encryptionSecret/name`, + value: repositoriesResp.data?.spec.encryptionSecret.name, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/encryptionSecret/namespace`, + value: repositoriesResp.data?.spec.encryptionSecret.namespace, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/fullDBRepository/name`, + value: `${refDBName}-full`, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/fullDBRepository/namespace`, + value: `${refNamespace}`, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/manifestRepository/name`, + value: `${refDBName}-manifest`, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/manifestRepository/namespace`, + value: `${refNamespace}`, + force: true, + }) + + const resp = getComponentLogStats(snapshotsResp.data) -async function getReferSecrets({ getValue, model, storeGet, axios, discriminator }) { - const referSecret = getValue(discriminator, '/referSecret') - if (!referSecret) { - return [] + commit('wizard/model$update', { + path: `/spec/init/archiver/recoveryTimestamp`, + value: convertToUTC(resp?.end), + force: true, + }) + commit('wizard/model$update', { + path: `/minDate`, + value: convertToUTC(resp?.start), + force: true, + }) + commit('wizard/model$update', { + path: `/maxDate`, + value: convertToUTC(resp?.end), + force: true, + }) + } catch (e) { + pointIntimeError = + e.response?.data?.message || 'Invalid name / namespace for recovery timestamp' + commit('wizard/model$update', { + path: `/spec/init/archiver/recoveryTimestamp`, + value: '', + force: true, + }) + commit('wizard/model$update', { + path: `/minDate`, + value: '', + force: true, + }) + commit('wizard/model$update', { + path: `/maxDate`, + value: '', + force: true, + }) + commit('wizard/model$delete', '/spec/init/archiver/encryptionSecret') + commit('wizard/model$delete', '/spec/init/archiver/fullDBRepository') + commit('wizard/model$delete', '/spec/init/archiver/manifestRepository') + console.log(e) + } } - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/metadata/release/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` + let pointIntimeError = '' + function pointInTimeErrorCheck() { + if (pointIntimeError.length) return pointIntimeError + return + } - const options = [] - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) - } catch (e) { - console.log(e) + async function getReferSecrets() { + const referSecret = getValue(discriminator, '/referSecret') + if (!referSecret) { + return [] + } + + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/metadata/release/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` + + const options = [] + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + return options } - return options -} -function showAuthPasswordField({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showAuthPasswordField() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !modelPathValue && showReferSecret() + } -function showSecretDropdown({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showSecretDropdown() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !!modelPathValue && showReferSecret() + } -function showReferSecret({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/createAuthSecret') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue -} + function showReferSecret() { + const modelPathValue = getValue(discriminator, '/createAuthSecret') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue + } -function getDefaultValue({ getValue, model }, path) { - const val = getValue(model, `/${path}`) || '' - return val -} + function getDefaultValue(path) { + const val = getValue(model, `/${path}`) || '' + return val + } -function showReferSecretSwitch({ model, getValue, watchDependency, discriminator }) { - const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showReferSecretSwitch() { + const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue && showReferSecret() + } -function onReferSecretChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) -} + function onReferSecretChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + } -return { - showReferSecretSwitch, - onReferSecretChange, - getDefaultValue, - isRancherManaged, - showSecretDropdown, - showReferSecret, - getReferSecrets, - isConfigAvailable, - setPointInTimeRecovery, - getRecoveryNames, - fetchNamespaces, - showRecovery, - showAdditionalSettings, - initBundle, - returnFalse, - isVariantAvailable, - showAuthPasswordField, - isEqualToModelPathValue, - showStorageSizeField, - onModeChange, - getMachineListForOptions, - setLimits, - setRequests, - setMachineToCustom, - getCreateNameSpaceUrl, - ifCapiProviderIsNotEmpty, - ifDedicated, - dedicatedOnChange, - ifZones, - zonesOnChange, - getZones, - getSKU, - showMultiselectZone, - showSelectZone, - setStorageClass, - getNamespaces, - isToggleOn, - getAdminOptions, - getNodeTopology, - isMachineNotCustom, - isMachineCustom, - onAuthChange, - clearConfiguration, - isConfigDatabaseOn, - showIssuer, - setMonitoring, - showAlerts, - onBackupSwitch, - updateAlertValue, - setBackup, - getDefault, - getDefaulPid, - onPidChange, - isPidCustom, - onCustomPidChange, - onArchiverChange, - showArchiverAlert, - showArchiver, + return { + showReferSecretSwitch, + onReferSecretChange, + getDefaultValue, + isRancherManaged, + showSecretDropdown, + showReferSecret, + getReferSecrets, + setPointInTimeRecovery, + pointInTimeErrorCheck, + getRecoveryNames, + fetchNamespaces, + showRecovery, + showAdditionalSettings, + initBundle, + returnFalse, + isVariantAvailable, + showAuthPasswordField, + isEqualToModelPathValue, + showStorageSizeField, + onModeChange, + getMachineListForOptions, + setLimits, + setRequests, + setMachineToCustom, + getCreateNameSpaceUrl, + ifCapiProviderIsNotEmpty, + ifDedicated, + dedicatedOnChange, + ifZones, + zonesOnChange, + getZones, + getSKU, + showMultiselectZone, + showSelectZone, + setStorageClass, + getNamespaces, + isToggleOn, + getAdminOptions, + getNodeTopology, + isMachineNotCustom, + isMachineCustom, + onAuthChange, + clearConfiguration, + isConfigDatabaseOn, + showIssuer, + setMonitoring, + showAlerts, + onBackupSwitch, + updateAlertValue, + setBackup, + getDefault, + getDefaulPid, + onPidChange, + isPidCustom, + onCustomPidChange, + onArchiverChange, + showArchiverAlert, + showArchiver, + filterNodeTopology, + onTimestampChange, + } } diff --git a/charts/kubedbcom-mssqlserver-editor/ui/edit-ui.yaml b/charts/kubedbcom-mssqlserver-editor/ui/edit-ui.yaml index 90f42cc0e7..5340a0b127 100644 --- a/charts/kubedbcom-mssqlserver-editor/ui/edit-ui.yaml +++ b/charts/kubedbcom-mssqlserver-editor/ui/edit-ui.yaml @@ -1,758 +1,721 @@ -steps: -- form: - elements: - - disabled: true - label: - text: labels.database.name - onChange: onNameChange - schema: - $ref: schema#/properties/metadata/properties/release/properties/name - type: input - type: single-step-form - id: basic - title: steps.0.label -- form: - discriminator: - repoInitialSelectionStatus: - type: string - scheduleBackup: - default: "yes" - type: string +type: multi-step-form +step: + - type: single-step-form + id: backupconfiguration + # label: Backup + schema: schema/ elements: - - computed: initScheduleBackupForEdit - if: showScheduleBackup - label: - text: labels.backup.title - onChange: onScheduleBackupChange + - type: radio + label: Schedule a Backup? + schema: temp/properties/scheduleBackup + isHorizontal: true options: - - text: options.yesOrNo.yes.text - value: "yes" - - text: options.yesOrNo.no.text - value: "no" - schema: - $ref: discriminator#/properties/scheduleBackup - type: radio - - discriminator: - backupType: - type: string - isBackupDataLoaded: - default: false - type: boolean + - text: 'Yes' + value: 'yes' + - text: 'No' + value: 'no' + if: + type: function + name: showScheduleBackup + init: + type: func + value: initScheduleBackupForEdit + watcher: + func: onScheduleBackupChange + paths: + - temp/properties/scheduleBackup + - type: block-layout + label: Backup Form + showLabels: false + loader: initBackupData + if: + type: function + name: showBackupForm elements: - - computed: initBackupData - if: returnFalse - type: input - - computed: setBackupType - fetch: getTypes - hasDescription: true - if: isBackupDataLoadedTrue - label: - text: Select Backup Type - onChange: onBackupTypeChange - schema: - $ref: discriminator#/backupType - type: radio - - discriminator: - backupConfigContext: - type: string - config: - type: string - paused: - default: false - type: boolean - schedule: - type: string - elements: - - fetch: getContext - label: - text: Select Context - onChange: onContextChange - required: true - schema: - $ref: discriminator#/backupConfigContext - type: select - - fetch: getConfigList - if: showConfigList - label: - text: Select BackupConfig - onChange: onConfigChange - required: true - schema: - $ref: discriminator#/config - type: select - - computed: getDefaultSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions - if: showSchedule - label: - text: Schedule - onChange: onInputChangeSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions|schedule - required: true - schema: - $ref: discriminator#/schedule - type: input - - if: showPause - label: - text: Paused - schema: - $ref: schema#/properties/resources/properties/coreKubestashComBackupConfiguration/properties/spec/properties/paused - type: switch - if: isBackupType|BackupConfig - type: single-step-form - - discriminator: - blueprintEnabled: - default: false - type: boolean - elements: - - computed: setBlueprintSwitch - label: - text: Enable Backup Blueprint - onChange: onBlueprintChange - schema: - $ref: discriminator#/blueprintEnabled - type: switch - if: isBackupType|BackupBlueprint - type: single-step-form - - discriminator: - archiverEnabled: - default: false - type: boolean + - type: radio + label: Select Backup Type + schema: temp/properties/backupType + isHorizontal: true + options: + - text: BackupConfig + value: BackupConfig + description: 'Create, Delete or Modify BackupConfig' + - text: BackupBlueprint + value: BackupBlueprint + description: Enable/Disable BackupBlueprint + if: + type: function + name: isBackupDataLoadedTrue + init: + type: func + value: setBackupType + loader: getTypes + watcher: + func: onBackupTypeChange + paths: + - temp/properties/backupType + - type: block-layout + label: Config + if: + type: function + name: isBackupType|BackupConfig + elements: + - type: select + label: Select Context + schema: temp/properties/backupConfigContext + validation: + type: required + loader: getContext + watcher: + func: onContextChange + paths: + - temp/properties/backupConfigContext + - type: select + label: Select BackupConfig + schema: temp/properties/config + validation: + type: required + if: + type: function + name: showConfigList + loader: getConfigList + watcher: + func: onConfigChange + paths: + - temp/properties/config + - type: input + label: Schedule + schema: temp/properties/schedule + validation: + type: required + if: + type: function + name: showSchedule + loader: + name: getDefaultSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions + watchPaths: + - temp/properties/config + watcher: + func: onInputChangeSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions|schedule + paths: + - temp/properties/schedule + - type: switch + label: Paused + fullwidth: true + schema: schema/properties/resources/properties/coreKubestashComBackupConfiguration/properties/spec/properties/paused + if: + type: function + name: showPause + watcher: + func: setPausedValue + paths: + - temp/properties/config + init: + type: func + value: setPausedValue + - type: block-layout + label: Blueprint + if: + type: function + name: isBackupType|BackupBlueprint + elements: + - type: switch + label: Enable Backup Blueprint + fullwidth: true + schema: temp/properties/blueprintEnabled + init: + type: func + value: setBlueprintSwitch + watcher: + func: onBlueprintChange + paths: + - temp/properties/blueprintEnabled + - type: block-layout + label: Archiver + if: + type: function + name: isBackupType|Archiver + elements: + - type: switch + label: Enable Archiver + fullwidth: true + schema: temp/properties/archiverEnabled + init: + type: func + value: setArchiverSwitch + watcher: + func: onArchiverChange + paths: + - temp/properties/archiverEnabled + + - type: single-step-form + id: compute-autoscaler + loader: getDbDetails + elements: + - type: block-layout + if: + type: function + name: isConsole elements: - - computed: setArchiverSwitch - label: - text: Enable Archiver - onChange: onArchiverChange - schema: - $ref: discriminator#/archiverEnabled - type: switch - if: isBackupType|Archiver - 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: - dbDetails: - default: false - type: boolean + - type: input + label: Name + schema: schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/metadata/properties/name + - type: select + label: Select Namespace + loader: getNamespaces + if: + type: function + name: isRancherManaged + schema: schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/metadata/properties/namespace + - type: select + label: Select Db + loader: getDbs + validation: + type: required + refresh: true + schema: schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/databaseRef/properties/name + watcher: + func: initMetadata + paths: + - schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/databaseRef/properties/name + - type: single-step-form + id: monitoring + loader: initMonitoring elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: Select Db - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: Select Type - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - discriminator: - topologyMachines: - default: [] - type: array + - type: label-element + label: To update Exporter Resource section click on Create OpsRequest + - type: anchor + label: Create OpsRequest + schema: temp/properties/opsRequestUrl + init: + type: func + value: getOpsRequestUrl|scale-vertically + - type: switch + label: Enable Monitoring + fullwidth: true + schema: temp/properties/enableMonitoring + init: + type: func + value: isValueExistInModel|/resources/kubedbComMSSQLServer/spec/monitor + watcher: + func: onEnableMonitoringChange + paths: + - temp/properties/enableMonitoring + - type: block-layout + if: + type: function + name: showMonitoringSection elements: - - fetch: fetchTopologyMachines - if: returnFalse - schema: - $ref: discriminator#/topologyMachines - type: input - - elements: - - computed: setTrigger|autoscalingKubedbComMSSQLServerAutoscaler/spec/compute/mssqlserver/trigger - label: - text: Trigger + - type: radio + label: Select a Monitoring Method + schema: schema/properties/resources/properties/kubedbComMSSQLServer/properties/spec/properties/monitor/properties/agent + isHorizontal: true options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/mssqlserver/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/mssqlserver/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/mssqlserver/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-max: - type: string - allowedMachine-min: - type: string + - text: Prometheus Operator + value: prometheus.io/operator + description: Inject metric exporter sidecar and creates a ServiceMonitor + - text: Custom ServiceMonitor + value: prometheus.io + description: Injects the metric exporter sidecar and let you customize ServiceMonitor + - text: Custom Scrapper + value: prometheus.io/builtin + description: Inject metric exporter sidecar and add Prometheus annotations to the stats Service + init: + type: static + value: prometheus.io/operator + watcher: + func: onAgentChange + paths: + - schema/properties/resources/properties/kubedbComMSSQLServer/properties/spec/properties/monitor/properties/agent + - type: block-layout + label: ServiceMonitor Configuration + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComMSSQLServer/spec/monitor/agent elements: - - computed: setAllowedMachine|min - disableUnselect: true - fetch: getMachines|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|mssqlserver - schema: - $ref: discriminator#/properties/allowedMachine-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/mssqlserver/properties/minAllowed/properties/cpu + - label: Scrapping Interval + schema: schema/properties/resources/properties/kubedbComMSSQLServer/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/mssqlserver/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/mssqlserver/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|max - disableUnselect: true - fetch: getMachines|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|mssqlserver - schema: - $ref: discriminator#/properties/allowedMachine-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/mssqlserver/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/mssqlserver/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/mssqlserver/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|mssqlserver - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/mssqlserver/properties/controlledResources - type: multiselect - label: - text: MSSQLServer - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/mssqlserver - show_label: true - type: single-step-form - - elements: - - fetch: fetchNodeTopology - label: - text: Select Node Topology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name - type: select - - if: isNodeTopologySelected - label: - text: ScaleUp Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage - type: input - - if: isNodeTopologySelected - label: - text: ScaleDown Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage - type: input - if: hasNoAnnotations - label: - text: NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/nodeTopology - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: compute-autoscaler - title: steps.6.label -- form: - discriminator: - dbDetails: - default: false - type: boolean - elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - computed: getDbDetails - if: returnFalse - type: input - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: Select Db - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: Select Type - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComMSSQLServerAutoscaler/spec/storage/mssqlserver/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/storage/properties/mssqlserver/properties/trigger - type: select - - label: - text: Expansion Mode - options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/storage/properties/mssqlserver/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/storage/properties/mssqlserver/properties/usageThreshold - type: input - - addFormLabel: ScalingRules - element: + - type: block-layout + label: Service Monitor + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComMSSQLServer/spec/monitor/agent + elements: + - type: array-object-form + label: Endpoints + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/endpoints elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/storage/properties/mssqlserver/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/storage/properties/mssqlserver/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComMSSQLServerAutoscaler/spec/storage/mssqlserver/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/storage/properties/mssqlserver/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComMSSQLServerAutoscaler/spec/storage/mssqlserver/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/storage/properties/mssqlserver/properties/upperBound - type: input - label: - text: MSSQLServer - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/mssqlserver - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: storage-autoscaler - title: steps.7.label -- form: - discriminator: - enableMonitoring: - default: true - type: boolean + - type: switch + fullwidth: true + label: Honor labels + schema: honorLabels + - type: input + label: Interval + schema: interval + validation: + type: required + - type: input + label: Path + schema: path + validation: + type: required + - type: input + label: Port + schema: port + validation: + type: required + - type: select + multiple: true + label: Match Namespaces + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/namespaceSelector/properties/matchNames + loader: getResources|core|v1|namespaces + if: + type: function + name: returnFalse + - type: block-layout + showLabels: false + # schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector + if: + type: function + name: returnFalse + elements: + - type: object-item + label: Labels + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector/properties/matchLabels + - type: object-item + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/metadata/properties/labels + label : Labels + buttonClass: is-light is-outlined + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComMSSQLServer/spec/monitor/agent + # individualItemDisabilityCheck: disableLableChecker + - type: label-element + label: Exporter Configuration + schema: '' + - type: switch + label: Customize Exporter Sidecar + fullwidth: true + schema: temp/properties/customizeExporter + init: + type: static + value: true + watcher: + func: onCustomizeExporterChange + paths: + - temp/properties/customizeExporter + - type: block-layout + label: Customer Exporter Section + showLabels: false + loader: setMetadata + if: + type: function + name: showCustomizeExporterSection + elements: + - type: machine-compare + label: Resources + schema: schema/properties/resources/properties/kubedbComMSSQLServer/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/resources + if: + type: function + name: returnFalse + - type: label-element + label: Security Context + schema: '' + - type: input + schema: schema/properties/resources/properties/kubedbComMSSQLServer/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsUser + label: Run as User + - type: input + schema: schema/properties/resources/properties/kubedbComMSSQLServer/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup + label: Run as Group + - type: input + schema: schema/properties/resources/properties/kubedbComMSSQLServer/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/port + label: Port + - type: array-item-form + label: Args + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/kubedbComMSSQLServer/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args + init: + type: static + value: ['--compatible-mode'] + element: + type: input + label: Args + # isSubsection: true + - type: block-layout + label: Metadata + showLabels: false + elements: + - type: array-object-form + init: + type: func + value: initEnvArray + label: Environment Variables + buttonClass: is-light is-outlined + watcher: + func: onEnvArrayChange + paths: + - temp/properties/env + schema: temp/properties/env + elements: + - type: input + label: Name + schema: name + validation: + type: required + - type: radio + label: Value From + schema: temp/properties/valueFromType + validation: + type: required + init: + type: func + value: setValueFrom + options: + - text: Input + value: input + - text: Secret + value: secret + - text: ConfigMap + value: configMap + watcher: + func: onValueFromChange + paths: + - temp/properties/valueFromType + - type: input + label: Value + schema: value + validation: + type: required + if: + name: isEqualToTemp|input + type: function + - type: select + if: + type: function + name: isEqualToTemp|configMap + label: ConfigMap Name + schema: valueFrom/properties/configMapKeyRef/properties/name + loader: + name: resourceNames|core|v1|configmaps + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: ConfigMap Key + schema: valueFrom/properties/configMapKeyRef/properties/key + if: + type: function + name: isEqualToTemp|configMap + loader: + name: getConfigMapKeys + watchPaths: + - schema/resources/kubedbComMSSQLServer/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/configMapKeyRef/name + - schema/metadata/release/namespace + - type: select + label: Secret Name + schema: valueFrom/properties/secretKeyRef/properties/name + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecrets + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: Secret Key + schema: valueFrom/properties/secretKeyRef/properties/key + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecretKeys + watchPaths: + - schema/resources/kubedbComMSSQLServer/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/secretKeyRef/name + - schema/metadata/release/namespace + + + - type: single-step-form + id: compute-autoscaler + loader: getDbDetails elements: - - label: - text: labels.to_update_exporter_resources - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - function: getOpsRequestUrl|VerticalScaling - - computed: isValueExistInModel|/resources/kubedbComMSSQLServer/spec/monitor - label: - text: labels.enable_monitoring - onChange: onEnableMonitoringChange - schema: - $ref: discriminator#/enableMonitoring - type: switch - - discriminator: - customizeExporter: - default: true - type: boolean + - type: block-layout + showLabels: false + loader: fetchTopologyMachines 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/kubedbComMSSQLServer/properties/spec/properties/monitor/properties/agent - type: radio - - elements: - - label: - text: labels.scrapping_interval - schema: - $ref: schema#/properties/resources/properties/kubedbComMSSQLServer/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval - type: input - if: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComMSSQLServer/spec/monitor/agent - label: - text: labels.service_monitor_configuration - show_label: true - type: single-step-form - - elements: - - elements: - - addFormLabel: labels.endpoint - element: + # mssqlserver mode + - type: switch + label: Trigger + fullwidth: true + if: + type: function + name: mssqlserverTypeEqualsTo|mssqlserver|compute + init: + type: func + value: setTrigger|autoscalingKubedbComMSSQLServerAutoscaler/spec/compute/mssqlserver/trigger + schema: temp/properties/compute/properties/mssqlserver/properties/trigger + watcher: + func: onTriggerChange|compute/mssqlserver + paths: + - temp/properties/compute/properties/mssqlserver/properties/trigger + - type: label-element + label: Pod lifetime threshold + subtitle: Specifies the duration a pod can exist before using considered for scaling decisions, ensuring resource optimization and workload stability + if: + type: function + name: mssqlserverTypeEqualsTo|mssqlserver|compute + - type: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/mssqlserver/properties/podLifeTimeThreshold + customClass: width-300 + if: + type: function + name: mssqlserverTypeEqualsTo|mssqlserver|compute + - type: block-layout + label: MSSQLServer + if: + type: function + name: mssqlserverTypeEqualsTo|mssqlserver|compute + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/mssqlserver + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/mssqlserver/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false 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/kubedbComMSSQLServer/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/kubedbComMSSQLServer/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: - - if: returnFalse - label: - text: labels.resources - schema: - $ref: schema#/properties/resources/properties/kubedbComMSSQLServer/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/kubedbComMSSQLServer/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/kubedbComMSSQLServer/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup - type: input - - label: - text: labels.port - schema: - $ref: schema#/properties/resources/properties/kubedbComMSSQLServer/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/kubedbComMSSQLServer/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args/items - type: input - label: - text: labels.args - schema: - $ref: schema#/properties/resources/properties/kubedbComMSSQLServer/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args - type: list-input-form - - alias: reusable_env - chart: - name: uibytebuildersdev-component-env - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComMSSQLServer/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 -type: multi-step-form + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-mssqlserver-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|mssqlserver|min + loader: + name: getMachines|mssqlserver|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-mssqlserver-max + watcher: + func: onMachineChange|mssqlserver + paths: + - temp/properties/allowedMachine-mssqlserver-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/mssqlserver/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/mssqlserver/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-mssqlserver-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|mssqlserver|max + loader: + name: getMachines|mssqlserver|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-mssqlserver-min + watcher: + func: onMachineChange|mssqlserver + paths: + - temp/properties/allowedMachine-mssqlserver-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/mssqlserver/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/mssqlserver/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|compute/mssqlserver + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/mssqlserver/properties/controlledResources + - type: block-layout + label: NodeTopology + if: + type: function + name: hasNoAnnotations + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/nodeTopology + elements: + - type: select + label: Select NodeTopology + loader: fetchNodeTopology + schema: schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name + - type: threshold-input + label: Scale Up DiffPercentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage + - type: threshold-input + label: Scale Down DiffPercentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + # schema: schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/opsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: storage-autoscaler + loader: getDbDetails + elements: + - type: block-layout + showLabels: false + elements: + # mssqlserver mode + - type: switch + label: Trigger + fullwidth: true + if: + type: function + name: mssqlserverTypeEqualsTo|mssqlserver|storage + init: + type: func + value: setTrigger|autoscalingKubedbComMSSQLServerAutoscaler/spec/storage/mssqlserver/trigger + schema: temp/properties/storage/properties/mssqlserver/properties/trigger + watcher: + func: onTriggerChange|storage/mssqlserver + paths: + - temp/properties/storage/properties/mssqlserver/properties/trigger + - type: label-element + 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. + if: + type: function + name: mssqlserverTypeEqualsTo|mssqlserver|storage + - type: select + label: Mode + description: Select how the storage expansion should be handled. + if: + type: function + name: mssqlserverTypeEqualsTo|mssqlserver|storage + options: + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/storage/properties/mssqlserver/properties/expansionMode + - type: block-layout + label: MSSQLServer + if: + type: function + name: mssqlserverTypeEqualsTo|mssqlserver|storage + showLabels: true + elements: + - type: threshold-input + label: UsageThreshold (%) + subtitle: Set the threshold percentage of storage usage to trigger scaling. + schema: schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/storage/properties/mssqlserver/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/storage/properties/mssqlserver/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComMSSQLServer/spec/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComMSSQLServerAutoscaler/spec/storage/mssqlserver/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/storage/properties/mssqlserver/properties/scalingRules + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/storage/properties/mssqlserver/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComMSSQLServerAutoscaler/spec/storage/mssqlserver/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/storage/properties/mssqlserver/properties/upperBound + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComMSSQLServerAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: binding + elements: + - type: switch + label: Expose Database + schema: temp/properties/binding + fullwidth: true + init: + type: func + value: isBindingAlreadyOn + watcher: + func: addOrRemoveBinding + paths: + - temp/properties/binding diff --git a/charts/kubedbcom-mssqlserver-editor/ui/functions.js b/charts/kubedbcom-mssqlserver-editor/ui/functions.js index 63652ca563..267ba31475 100644 --- a/charts/kubedbcom-mssqlserver-editor/ui/functions.js +++ b/charts/kubedbcom-mssqlserver-editor/ui/functions.js @@ -1,3296 +1,1623 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + // ************************* common functions ******************************************** // eslint-disable-next-line no-empty-pattern -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}`, +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-mssqlserver-min', '') + setDiscriminatorValue('/allowedMachine-mssqlserver-max', '') + + function initScheduleBackupForEdit() { + const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( + getValue, + model, ) - // declare evaluate the functionString to get the functions Object - const evalFunc = new Function(functionString.data || '') - functions = evalFunc() - } catch (e) { - console.log(e) + + initRepositoryChoiseForEdit() + + if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' + else return 'no' } - return { - ui: ui.data || {}, - language: language.data || {}, - functions, + function initScheduleBackup() { + const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( + getValue, + model, + ) + + if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' + else return 'no' } -} -function disableLableChecker({ itemCtx }) { - const { key } = itemCtx - if (key.startsWith('app.kubernetes.io') || key.includes('helm')) return true - else return false -} + function onScheduleBackupChange() { + const scheduleBackup = getValue(discriminator, '/scheduleBackup') -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} + if (scheduleBackup === 'no') { + // delete stashAppscodeComBackupConfiguration + commit('wizard/model$delete', '/resources/stashAppscodeComBackupConfiguration') + commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') + // delete annotation from kubedbComMSSQLServer annotation + deleteKubeDbComMSSQLServerDbAnnotation(getValue, model, commit) + } else { + const { isBluePrint } = getBackupConfigsAndAnnotations(getValue, model) -async function getResources({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + // create stashAppscodeComBackupConfiguration and initialize it if not exists - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + const dbName = getValue(model, '/metadata/release/name') - const resources = (resp && resp.data && resp.data.items) || [] + 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, + }) + } + } + } - 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 valueExists(value, getValue, path) { + const val = getValue(value, path) + if (val) return true + else return false } -} -function isEqualToDiscriminatorPath( - { discriminator, getValue, watchDependency }, - value, - discriminatorPath, -) { - watchDependency('discriminator#' + discriminatorPath) - const discriminatorValue = getValue(discriminator, discriminatorPath) - return discriminatorValue === value -} + function deleteKubeDbComMSSQLServerDbAnnotation(getValue, model, commit) { + const annotations = + getValue(model, '/resources/kubedbComMSSQLServer/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/kubedbComMSSQLServer/metadata/annotations', + value: filteredAnnotations, + }) + } -function setValueFromModel({ getValue, model }, path) { - return getValue(model, path) -} + function getBackupConfigsAndAnnotations(getValue, model) { + const stashAppscodeComBackupConfiguration = getValue( + model, + '/resources/stashAppscodeComBackupConfiguration', + ) -function isNotShardModeSelected({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComMSSQLServer/spec') - const hasShardTopology = getValue(model, '/resources/kubedbComMSSQLServer/spec/shardTopology') - return !hasShardTopology -} + const coreKubestashComBackupConfiguration = getValue( + model, + '/resources/coreKubestashComBackupConfiguration', + ) + const kubeStashTarget = coreKubestashComBackupConfiguration?.spec?.target -function isShardModeSelected({ model, getValue, watchDependency, commit }) { - const resp = !isNotShardModeSelected({ model, getValue, watchDependency }) - if (resp) { - commit('wizard/model$delete', '/resources/kubedbComMSSQLServer/spec/configSecret') - commit('wizard/model$delete', '/resources/secret_config') - } - return resp -} + const mongoDB = getValue(model, '/resources/kubedbComMSSQLServer') + const mongoDbKind = mongoDB?.apiVersion?.split('/')?.at(0) -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + let isKubeStash = false + if ( + mongoDB?.kind === kubeStashTarget?.kind && + mongoDB?.metadata?.name === kubeStashTarget?.name && + mongoDB?.metadata?.namespace === kubeStashTarget?.namespace && + mongoDbKind === kubeStashTarget?.apiGroup + ) { + isKubeStash = true + } - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + const kubedbComMSSQLServerAnnotations = + getValue(model, '/resources/kubedbComMSSQLServer/metadata/annotations') || {} - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }) + const isBluePrint = Object.keys(kubedbComMSSQLServerAnnotations).some( + (k) => + k === 'stash.appscode.com/backup-blueprint' || + k === 'stash.appscode.com/schedule' || + k.startsWith('params.stash.appscode.com/'), + ) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + return { + stashAppscodeComBackupConfiguration, + isBluePrint, + isKubeStash, + } } - return ans -} + // backup form + function showBackupForm() { + const scheduleBackup = getValue(discriminator, '/scheduleBackup') + // watchDependency('discriminator#/scheduleBackup') + if (scheduleBackup === 'yes') return true + else return false + } -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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/kubedbComMSSQLServer') + initialDbMetadata = objectCopy(dbResource.metadata) + initialArchiver = dbResource.spec?.archiver ? objectCopy(dbResource.spec?.archiver) : undefined - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` + // 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 ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }) + let url = `/clusters/${user}/${cluster}/helm/packageview/values?name=${chartName}&sourceApiGroup=${sourceApiGroup}&sourceKind=${sourceKind}&sourceNamespace=${sourceNamespace}&sourceName=${sourceName}&version=${chartVersion}&format=json` - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) - } + if (spoke) + url = `/clusters/${user}/${spoke}/helm/packageview/values?name=${chartName}&sourceApiGroup=${sourceApiGroup}&sourceKind=${sourceKind}&sourceNamespace=${sourceNamespace}&sourceName=${sourceName}&version=${chartVersion}&format=json` - return ans -} + const resp = await axios.get(url) -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - 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) - }) - } + valuesFromWizard = objectCopy(resp.data?.resources?.coreKubestashComBackupConfiguration) || {} + } catch (e) { + console.log(e) + } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + // 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) + } } - }) -} -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) - - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) - } + // 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, + ) - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + // 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, + ) -function returnTrue() { - return true -} + // set backup switch here + isBackupOn = !!config -function returnStringYes() { - return 'yes' -} + // set initial data from stash-presets + const stashPreset = storeGet('/backup/stashPresets') + if (stashPreset) { + const { retentionPolicy, encryptionSecret, schedule, storageRef } = stashPreset -// ************************* Basic Info ********************************************** -async function getMongoDbVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + const tempBackends = valuesFromWizard.spec?.backends + tempBackends[0]['storageRef'] = storageRef + tempBackends[0]['retentionPolicy'] = retentionPolicy + valuesFromWizard.spec['backends'] = tempBackends - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, - }, - }, - } + 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}` - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) + tempSessions[0]['repositories'] = tempRepositories + tempSessions[0]['scheduler']['schedule'] = schedule + valuesFromWizard.spec['sessions'] = tempSessions + } - const resources = (resp && resp.data && resp.data.items) || [] + 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, + } - // keep only non deprecated versions - const filteredMongoDbVersions = resources.filter((item) => item.spec && !item.spec.deprecated) + setDiscriminatorValue('isBackupDataLoaded', true) + } - filteredMongoDbVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredMongoDbVersions - } catch (e) { - console.log(e) - return [] + function isBackupDataLoadedTrue() { + // watchDependency('discriminator#/isBackupDataLoaded') + return !!getValue(discriminator, '/isBackupDataLoaded') } -} -// ************************* Auth Secret Field ****************************************** -function showAuthPasswordField({ model, getValue, watchDependency }) { - watchDependency('model#/resources') - const modelPathValue = getValue(model, '/resources') - return !!( - modelPathValue && - modelPathValue.secret && - modelPathValue.secret.metadata && - modelPathValue.secret.metadata.name && - !showAuthSecretField({ model, getValue, watchDependency }) - ) -} + function setBackupType() { + return 'BackupConfig' + } -function showAuthSecretField({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComMSSQLServer/spec') - const modelPathValue = getValue(model, '/resources/kubedbComMSSQLServer/spec') - return !!(modelPathValue && modelPathValue.authSecret && modelPathValue.authSecret.name) -} + 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 showNewSecretCreateField({ model, getValue, watchDependency, commit }) { - const resp = - !showAuthSecretField({ model, getValue, watchDependency }) && - !showAuthPasswordField({ model, getValue, watchDependency }) - const secret = getValue(model, '/resources/secret_auth') - if (resp && !secret) { + function onBackupTypeChange() { + const type = getValue(discriminator, '/backupType') commit('wizard/model$update', { - path: '/resources/secret_auth', - value: { - data: { - password: '', - }, - }, + 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/kubedbComMSSQLServer', + value: objectCopy(dbResource), force: true, }) } - return resp -} - -// ********************* Database Mode *********************** -function isNotStandaloneMode({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - return mode !== 'Standalone' -} -function showCommonStorageClassAndSizeField({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - const validType = ['Standalone', 'Replicaset'] - return validType.includes(mode) -} -function setDatabaseMode({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/resources/kubedbComMSSQLServer/spec') + function isBackupType(type) { + // watchDependency('discriminator#/backupType') + const selectedType = getValue(discriminator, '/backupType') - watchDependency('model#/resources/kubedbComMSSQLServer/spec') - if (modelPathValue.shardTopology) { - return 'Sharded' - } else if (modelPathValue.replicaSet) { - return 'Replicaset' - } else { - return 'Standalone' + return selectedType === type } -} - -let storageClassList = [] -async function getStorageClassNames( - { axios, storeGet, commit, model, getValue, watchDependency, discriminator }, - mode, -) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const databaseModeShard = getValue(discriminator, '/activeDatabaseMode') === 'Sharded' - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/storage.k8s.io/v1/storageclasses`, - { - params: { - filter: { items: { metadata: { name: null, annotations: 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 - }) - storageClassList = resources - const path = - mode === 'shard' - ? '/resources/kubedbComMSSQLServer/spec/shardTopology/shard/storage/storageClassName' - : '/resources/kubedbComMSSQLServer/spec/storage/storageClassName' - const initialStorageClass = getValue(model, path) - if (!initialStorageClass) setStorageClass({ getValue, commit, model, discriminator }) - return resources -} -function setStorageClass({ getValue, commit, model, discriminator }) { - const deletionPolicy = getValue(model, 'resources/kubedbComMSSQLServer/spec/deletionPolicy') || '' - const suffix = '-retain' - let storageClass = '' + function setBlueprintSwitch() { + const annotations = initialDbMetadata?.annotations - const simpleClassList = storageClassList.filter((item) => { - return !item.metadata?.name?.endsWith(suffix) - }) + return !!( + annotations['blueprint.kubestash.com/name'] && + annotations['blueprint.kubestash.com/namespace'] + ) + } - const retainClassList = storageClassList.filter((item) => { - return item.metadata?.name?.endsWith(suffix) - }) + function onBlueprintChange() { + const blueprintSwitch = getValue(discriminator, '/blueprintEnabled') + if (blueprintSwitch) addLabelAnnotation('annotations') + else deleteLabelAnnotation('annotations') + } - const defaultSimpleList = simpleClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] - ) - }) + function setArchiverSwitch() { + const archiver = dbResource?.spec?.archiver + return !!archiver + } - const defaultRetainList = retainClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] - ) - }) - - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - if (simpleClassList.length > 1) { - const found = defaultSimpleList.length ? defaultSimpleList[0] : simpleClassList[0] - storageClass = found.value - } else if (simpleClassList.length === 1) { - storageClass = simpleClassList[0]?.value + function onArchiverChange() { + const archiverSwitch = getValue(discriminator, '/archiverEnabled') + const path = 'resources/kubedbComMSSQLServer/spec/archiver' + if (archiverSwitch) { + commit('wizard/model$update', { + path: path, + value: initialArchiver ? initialArchiver : archiverObjectToCommit, + }) } else { - const found = defaultRetainList.length - ? defaultRetainList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found + commit('wizard/model$delete', path) } - } else { - if (retainClassList.length > 1) { - const found = defaultRetainList.length ? defaultRetainList[0] : retainClassList[0] - storageClass = found.value - } else if (retainClassList.length === 1) { - storageClass = retainClassList[0]?.value + } + + 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 { - const found = defaultSimpleList.length - ? defaultSimpleList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found + obj['kubedb.com/archiver'] = 'true' } + + commit('wizard/model$update', { + path: `/resources/kubedbComMSSQLServer/metadata/${type}`, + value: obj, + force: true, + }) } - const mode = getValue(discriminator, '/activeDatabaseMode') + 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'] - if (mode === 'Sharded') { commit('wizard/model$update', { - path: '/resources/kubedbComMSSQLServer/spec/shardTopology/shard/storage/storageClassName', - value: storageClass, + path: `/resources/kubedbComMSSQLServer/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: '/resources/kubedbComMSSQLServer/spec/shardTopology/configServer/storage/storageClassName', - value: storageClass, + path: '/context', + value: context, force: true, }) - commit('wizard/model$delete', '/resources/kubedbComMSSQLServer/spec/storage') - } else { + 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/kubedbComMSSQLServer/spec/storage/storageClassName', - value: storageClass, + path: '/resources/coreKubestashComBackupConfiguration', + value: configDetails, force: true, }) } -} -function updateConfigServerStorageClass({ getValue, model, commit }) { - const storageClass = - getValue( - model, - '/resources/kubedbComMSSQLServer/spec/shardTopology/shard/storage/storageClassName', - ) || '' - commit('wizard/model$update', { - path: '/resources/kubedbComMSSQLServer/spec/shardTopology/configServer/storage/storageClassName', - value: storageClass, - 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 deleteDatabaseModePath({ discriminator, getValue, commit, model }) { - const mode = getValue(discriminator, '/activeDatabaseMode') - const modelSpec = getValue(model, '/resources/kubedbComMSSQLServer/spec') - if (mode === 'Sharded') { - commit('wizard/model$delete', '/resources/kubedbComMSSQLServer/spec/replicaSet') - commit('wizard/model$delete', '/resources/kubedbComMSSQLServer/spec/replicas') - commit('wizard/model$delete', '/resources/kubedbComMSSQLServer/spec/storage') - commit('wizard/model$delete', '/resources/kubedbComMSSQLServer/spec/podTemplate') - commit('wizard/model$delete', '/resources/kubedbComMSSQLServer/spec/configSecret') + function initRepositoryChoiseForEdit() { + const stashAppscodeComRepository_repo = getValue( + model, + '/resources/stashAppscodeComRepository_repo', + ) + const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' + setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) - commit('wizard/model$delete', '/resources/secret_config') + return repoInitialSelectionStatus + } - if (!modelSpec.shardTopology) { + 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: '/resources/kubedbComMSSQLServer/spec/shardTopology', - value: { - configServer: { - replicas: 3, - storage: { - resources: { - requests: { - storage: '', - }, - }, - }, - }, - mongos: { - replicas: 2, - }, - shard: { - replicas: 3, - shards: 3, - storage: { - resources: { - requests: { - storage: '', - }, - }, - }, - }, + path: modelPath, + value: session, + }) + } + } + + 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/kubedbComMSSQLServer/metadata/labels') + const bindingValues = { + apiVersion: 'catalog.appscode.com/v1alpha1', + kind: 'MSSQLServerBinding', + metadata: { + labels, + name: dbName, + namespace: dbNamespace, + }, + spec: { + sourceRef: { + name: dbName, + namespace: dbNamespace, }, + }, + } + + if (value) { + commit('wizard/model$update', { + path: '/resources/catalogAppscodeComMSSQLServerBinding', + value: bindingValues, force: true, }) + } else { + commit('wizard/model$delete', '/resources/catalogAppscodeComMSSQLServerBinding') } - } else if (mode === 'Replicaset') { - commit('wizard/model$delete', '/resources/kubedbComMSSQLServer/spec/shardTopology') + } + + function isBindingAlreadyOn() { + const value = getValue(model, '/resources') + const keys = Object.keys(value) + const isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComMSSQLServerBinding') + return isExposeBinding + } + + function objectCopy(obj) { + const temp = JSON.stringify(obj) + return JSON.parse(temp) + } + + /************ Compute Autoscaling ************/ - commit('wizard/model$delete', '/resources/secret_shard_config') - commit('wizard/model$delete', '/resources/secret_configserver_config') - commit('wizard/model$delete', '/resources/secret_mongos_config') + let autoscaleType = '' + let dbDetails = {} + let instance = '' - if (!modelSpec.replicaSet) { + function isConsole() { + const isKube = isKubedb() + + if (isKube) { + const dbName = storeGet('/route/params/name') || '' commit('wizard/model$update', { - path: '/resources/kubedbComMSSQLServer/spec/replicaSet', - value: { name: '' }, + path: '/resources/autoscalingKubedbComMSSQLServerAutoscaler/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/kubedbComMSSQLServer/spec/replicas', - value: 3, + path: '/resources/autoscalingKubedbComMSSQLServerAutoscaler/metadata/name', + value: modifiedName, force: true, }) + const namespace = storeGet('/route/query/namespace') || '' + if (namespace) { + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComMSSQLServerAutoscaler/metadata/namespace', + value: namespace, + force: true, + }) + } } - } else if (mode === 'Standalone') { - commit('wizard/model$delete', '/resources/kubedbComMSSQLServer/spec/shardTopology') - - commit('wizard/model$delete', '/resources/kubedbComMSSQLServer/spec/replicaSet') - commit('wizard/model$delete', '/resources/kubedbComMSSQLServer/spec/replicas') - commit('wizard/model$delete', '/resources/secret_shard_config') - commit('wizard/model$delete', '/resources/secret_configserver_config') - commit('wizard/model$delete', '/resources/secret_mongos_config') + return !isKube } -} - -function isEqualToDatabaseMode({ getValue, watchDependency, discriminator }, value) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - return mode === value -} - -// ************************** TLS ******************************88 -function setApiGroup() { - return 'cert-manager.io' -} + function isKubedb() { + return !!storeGet('/route/params/actions') + } -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - watchDependency('model#/resources/kubedbComMSSQLServer/spec/tls/issuerRef/apiGroup') - watchDependency('model#/resources/kubedbComMSSQLServer/spec/tls/issuerRef/kind') - watchDependency('model#/metadata/release/namespace') - const apiGroup = getValue(model, '/resources/kubedbComMSSQLServer/spec/tls/issuerRef/apiGroup') - const kind = getValue(model, '/resources/kubedbComMSSQLServer/spec/tls/issuerRef/kind') - const namespace = getValue(model, '/metadata/release/namespace') + async function getDbDetails() { + const annotations = getValue( + model, + '/resources/autoscalingKubedbComMSSQLServerAutoscaler/metadata/annotations', + ) + instance = annotations?.['kubernetes.io/instance-type'] + + const owner = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + const namespace = + storeGet('/route/query/namespace') || + getValue(model, '/resources/autoscalingKubedbComMSSQLServerAutoscaler/metadata/namespace') || + '' + const name = + storeGet('/route/params/name') || + getValue( + model, + '/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/databaseRef/name', + ) || + '' + + if (namespace && name) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/mssqlservers/${name}`, + ) + dbDetails = resp.data || {} + setDiscriminatorValue('/dbDetails', true) + } catch (e) { + console.log(e) + } + } - let url - if (kind === 'Issuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/namespaces/${namespace}/issuers` - } else if (kind === 'ClusterIssuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/clusterissuers` + commit('wizard/model$update', { + path: `/metadata/release/name`, + value: name, + force: true, + }) + commit('wizard/model$update', { + path: `/metadata/release/namespace`, + value: namespace, + force: true, + }) + commit('wizard/model$update', { + path: `/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/databaseRef/name`, + value: name, + force: true, + }) + commit('wizard/model$update', { + path: `/resources/autoscalingKubedbComMSSQLServerAutoscaler/metadata/labels`, + value: dbDetails.metadata.labels, + force: true, + }) } - if (!url) return [] + async function getNamespaces() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - try { - const resp = await axios.get(url) + 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) || [] - resources.map((item) => { + return resources.map((item) => { const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + return { + text: name, + value: name, + } }) - return resources - } catch (e) { - console.log(e) - return [] } -} -async function hasIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await getIssuerRefsName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !!(resp && resp.length) -} - -async function hasNoIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await hasIssuerRefName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !resp -} - -function setClusterAuthMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComMSSQLServer/spec/clusterAuthMode') - return val || 'x509' -} - -function setSSLMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComMSSQLServer/spec/sslMode') - return val || 'requireSSL' -} - -function showTlsConfigureSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configureTLS') - const configureStatus = getValue(discriminator, '/configureTLS') - return configureStatus -} - -function onTlsConfigureChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/configureTLS') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComMSSQLServer/spec/tls', - value: { issuerRef: {}, certificates: [] }, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComMSSQLServer/spec/tls') - commit('wizard/model$delete', '/resources/kubedbComMSSQLServer/spec/clusterAuthMode') - commit('wizard/model$delete', '/resources/kubedbComMSSQLServer/spec/sslMode') - } -} - -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} - -/****** Monitoring *********/ - -function showMonitoringSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/enableMonitoring') - const configureStatus = getValue(discriminator, '/enableMonitoring') - return configureStatus -} - -function onEnableMonitoringChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/enableMonitoring') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComMSSQLServer/spec/monitor', - value: {}, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComMSSQLServer/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, getValue }) { - watchDependency('discriminator#/customizeExporter') - const configureStatus = getValue(discriminator, '/customizeExporter') - return configureStatus -} - -function onCustomizeExporterChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/customizeExporter') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComMSSQLServer/spec/monitor/prometheus/exporter', - value: {}, - force: true, - }) - } else { - commit( - 'wizard/model$delete', - '/resources/kubedbComMSSQLServer/spec/monitor/prometheus/exporter', + async function getDbs() { + // watchDependency('model#/resources/autoscalingKubedbComMSSQLServerAutoscaler/metadata/namespace') + const namespace = getValue( + model, + '/resources/autoscalingKubedbComMSSQLServerAutoscaler/metadata/namespace', ) - } -} + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -// ********************************* Initialization & Backup ************************************* -const stashAppscodeComRestoreSession_init = { - spec: { - repository: { - name: '', - }, - rules: [ + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises`, { - snapshots: ['latest'], - }, - ], - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} -const initScript = { - scriptPath: '', - secret: { - secretName: '', - }, -} -const stashAppscodeComRepository_init_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const stashAppscodeComRepository_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const restoreSessionInitRunTimeSettings = { - container: { - resources: { - requests: { - cpu: '', - memory: '', - }, - limits: { - cpu: '', - memory: '', - }, - }, - nice: { - adjustment: null, - }, - ionice: { - class: null, - classData: null, - }, - securityContext: { - privileged: false, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - env: [], - envFrom: [], - }, - pod: { - serviceAccountName: '', - imagePullSecrets: [], - securityContext: { - fsGroup: null, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - }, -} - -const stashAppscodeComBackupConfiguration = { - spec: { - repository: { - name: '', - }, - retentionPolicy: { - keepLast: 5, - name: 'keep-last-5', - prune: true, - }, - schedule: '*/5 * * * *', - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} - -function disableInitializationSection({ model, getValue, watchDependency }) { - const initialized = getValue(model, '/resources/kubedbComMSSQLServer/spec/init/initialized') - watchDependency('model#/resources/kubedbComMSSQLServer/spec/init/initialized') - return !!initialized -} - -function valueExists(value, getValue, path) { - const val = getValue(value, path) - if (val) return true - else return false -} - -function initPrePopulateDatabase({ getValue, model }) { - const waitForInitialRestore = getValue( - model, - '/resources/kubedbComMSSQLServer/spec/init/waitForInitialRestore', - ) - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - const script = getValue(model, '/resources/kubedbComMSSQLServer/spec/init/script') - - return waitForInitialRestore || !!stashAppscodeComRestoreSession_init || !!script ? 'yes' : 'no' -} - -function onPrePopulateDatabaseChange({ commit, getValue, discriminator, model }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - if (prePopulateDatabase === 'no') { - // delete related properties - commit('wizard/model$update', { - path: '/resources/kubedbComMSSQLServer/spec/init/waitForInitialRestore', - value: false, - }) - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - commit('wizard/model$delete', '/resources/kubedbComMSSQLServer/spec/init/script') - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else { - const dbName = getValue(model, '/metadata/release/name') - // set stashAppscodeComRestoreSession_init if it doesn't exist - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - force: true, - }) - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - } - } -} - -function initDataSource({ getValue, model }) { - const script = getValue(model, '/resources/kubedbComMSSQLServer/spec/init/script') - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - - if (script) return 'script' - else if (stashAppscodeComRestoreSession_init) return 'stashBackup' - else return undefined -} - -function onDataSourceChange({ commit, getValue, discriminator, model }) { - const dataSource = getValue(discriminator, '/dataSource') - - commit('wizard/model$update', { - path: '/resources/kubedbComMSSQLServer/spec/init/waitForInitialRestore', - value: dataSource === 'stashBackup', - force: true, - }) - - if (dataSource === 'script') { - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - - // create a new script if there is no script property - if (!valueExists(model, getValue, '/resources/kubedbComMSSQLServer/spec/init/script')) - commit('wizard/model$update', { - path: '/resources/kubedbComMSSQLServer/spec/init/script', - value: initScript, - }) - } else if (dataSource === 'stashBackup') { - commit('wizard/model$delete', '/resources/kubedbComMSSQLServer/spec/init/script') - - // create a new stashAppscodeComRestoreSession_init if there is no stashAppscodeComRestoreSession_init property - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - const dbName = getValue(model, '/metadata/release/name') - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - }) - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - } - } -} - -// // for script -function initVolumeType({ getValue, model }) { - const configMap = getValue( - model, - '/resources/kubedbComMSSQLServer/spec/init/script/configMap/name', - ) - const secret = getValue( - model, - '/resources/kubedbComMSSQLServer/spec/init/script/secret/secretName', - ) - - if (configMap) return 'configMap' - else if (secret) return 'secret' - else return undefined -} - -function onVolumeTypeChange({ commit, getValue, discriminator, model }) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - if (sourceVolumeType === 'configMap') { - // add configMap object and delete secret object - commit('wizard/model$delete', '/resources/kubedbComMSSQLServer/spec/init/script/secret') - - if ( - !valueExists(model, getValue, '/resources/kubedbComMSSQLServer/spec/init/script/configMap') - ) { - commit('wizard/model$update', { - path: '/resources/kubedbComMSSQLServer/spec/init/script/configMap', - value: { - name: '', - }, - }) - } - } else if (sourceVolumeType === 'secret') { - // delete configMap object and add secret object - commit('wizard/model$delete', '/resources/kubedbComMSSQLServer/spec/init/script/configMap') - - if (!valueExists(model, getValue, '/resources/kubedbComMSSQLServer/spec/init/script/secret')) { - commit('wizard/model$update', { - path: '/resources/kubedbComMSSQLServer/spec/init/script/secret', - value: { - secretName: '', - }, - }) - } - } -} - -function showInitializationForm({ getValue, discriminator, watchDependency }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - watchDependency('discriminator#/prePopulateDatabase') - return prePopulateDatabase === 'yes' -} - -function showScriptOrStashForm({ getValue, discriminator, watchDependency }, value) { - const dataSource = getValue(discriminator, '/dataSource') - watchDependency('discriminator#/dataSource') - return dataSource === value -} - -function showConfigMapOrSecretName({ getValue, discriminator, watchDependency }, value) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - watchDependency('discriminator#/sourceVolumeType') - return sourceVolumeType === value -} - -// for stash backup -function initializeNamespace({ getValue, model }) { - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} - -function showRepositorySelectOrCreate({ getValue, discriminator, watchDependency }, value) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - return repositoryChoise === value -} - -function onInitRepositoryChoiseChange({ getValue, discriminator, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - if (repositoryChoise === 'select') { - // delete stashAppscodeComRepository_init_repo from model - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else if (repositoryChoise === 'create') { - // add stashAppscodeComRepository_init_repo to model - commit('wizard/model$update', { - path: 'resources/stashAppscodeComRepository_init_repo', - value: stashAppscodeComRepository_init_repo, - }) - - const repositoryName = `${getValue(model, '/metadata/release/name')}-init-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: repositoryName, - }) - } -} - -function initCustomizeRestoreJobRuntimeSettings({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function initCustomizeRestoreJobRuntimeSettingsForBackup({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function onCustomizeRestoreJobRuntimeSettingsChange({ commit, getValue, discriminator, model }) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - value: restoreSessionInitRunTimeSettings, - }) - } - } -} - -function onCustomizeRestoreJobRuntimeSettingsChangeForBackup({ - commit, - getValue, - discriminator, - model, -}) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - value: {}, - force: true, - }) - } - } -} - -function showRuntimeForm({ discriminator, getValue, watchDependency }, value) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - watchDependency('discriminator#/customizeRestoreJobRuntimeSettings') - return customizeRestoreJobRuntimeSettings === value -} - -async function getImagePullSecrets({ getValue, model, watchDependency, axios, storeGet }) { - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - - let resources = await getNamespacedResourceList(axios, storeGet, { - namespace, - group: 'core', - version: 'v1', - resource: 'secrets', - }) - - resources = resources.filter((item) => { - const validType = ['kubernetes.io/dockerconfigjson'] - return validType.includes(item.type) - }) - - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: { name: name }, - } - }) -} - -function showBackupOptions({ discriminator, getValue, watchDependency }, backup) { - const backupEnabled = getValue(discriminator, '/backupEnabled') - if (backupEnabled) { - if (backup === 'alert') return true - else return false - } else { - if (backup === 'alert') return false - else return true - } -} - -function isBlueprintOption({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/blueprintOptions') - const blueprintOptions = getValue(discriminator, '/blueprintOptions') - return blueprintOptions === value -} - -function ifUsagePolicy({ discriminator, getValue, watchDependency, model }, value) { - watchDependency( - 'model#/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', - ) - const usagePolicy = getValue( - model, - '/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', - ) - return usagePolicy === value -} - -async function getBlueprints({ getValue, model, setDiscriminatorValue, axios, storeGet }, backup) { - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const url = `clusters/${username}/${clusterName}/proxy/core.kubestash.com/v1alpha1/backupblueprints` - - try { - const resp = await axios.get(url) - let data = resp.data.items - return data - } catch (e) { - console.log(e) - } -} - -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} - -async function fetchNamespaces({ axios, storeGet }) { - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const group = storeGet('/route/params/group') - const version = storeGet('/route/params/version') - const resource = storeGet('/route/params/resource') - - const url = `clusters/${username}/${clusterName}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews` - - try { - const resp = await axios.post(url, { - _recurringCall: false, - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], - }, - }) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] - } - } catch (e) { - console.log(e) - } - return [] -} - -async function fetchNames( - { getValue, axios, storeGet, watchDependency, discriminator }, - version, - type, - discriminatorName, -) { - watchDependency(`discriminator#/${discriminatorName}`) - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const namespace = getValue(discriminator, `${discriminatorName}`) - const url = - type !== 'secrets' - ? `clusters/${username}/${clusterName}/proxy/storage.kubestash.com/${version}/namespaces/${namespace}/${type}` - : `clusters/${username}/${clusterName}/proxy/core/${version}/namespaces/${namespace}/${type}` - try { - if (namespace) { - const resp = await axios.get(url) - let data = resp.data.items - if (type === 'secrets') data = data.filter((ele) => !!ele.data['RESTIC_PASSWORD']) - data = data.map((ele) => ele.metadata.name) - return data - } - } catch (e) { - console.log(e) - } - return [] -} - -// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// FOR Backup Configuration - -// schedule backup - -function getBackupConfigsAndAnnotations(getValue, model) { - const stashAppscodeComBackupConfiguration = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration', - ) - - const coreKubestashComBackupConfiguration = getValue( - model, - '/resources/coreKubestashComBackupConfiguration', - ) - const kubeStashTarget = coreKubestashComBackupConfiguration?.spec?.target - - const mongoDB = getValue(model, '/resources/kubedbComMSSQLServer') - const mongoDbKind = mongoDB?.apiVersion?.split('/')?.at(0) - - let isKubeStash = false - if ( - mongoDB?.kind === kubeStashTarget?.kind && - mongoDB?.metadata?.name === kubeStashTarget?.name && - mongoDB?.metadata?.namespace === kubeStashTarget?.namespace && - mongoDbKind === kubeStashTarget?.apiGroup - ) { - isKubeStash = true - } - - const kubedbComMSSQLServerAnnotations = - getValue(model, '/resources/kubedbComMSSQLServer/metadata/annotations') || {} - - const isBluePrint = Object.keys(kubedbComMSSQLServerAnnotations).some( - (k) => - k === 'stash.appscode.com/backup-blueprint' || - k === 'stash.appscode.com/schedule' || - k.startsWith('params.stash.appscode.com/'), - ) - - return { - stashAppscodeComBackupConfiguration, - isBluePrint, - isKubeStash, - } -} - -function deleteKubeDbComMongDbAnnotation(getValue, model, commit) { - const annotations = getValue(model, '/resources/kubedbComMSSQLServer/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/kubedbComMSSQLServer/metadata/annotations', - value: filteredAnnotations, - }) -} - -function addKubeDbComMongDbAnnotation(getValue, model, commit, key, value, force) { - const annotations = getValue(model, '/resources/kubedbComMSSQLServer/metadata/annotations') || {} - - if (annotations[key] === undefined) { - annotations[key] = value - } else if (force) { - annotations[key] = value - } - - commit('wizard/model$update', { - path: '/resources/kubedbComMSSQLServer/metadata/annotations', - value: annotations, - force: true, - }) -} - -function initScheduleBackupForEdit({ getValue, model, setDiscriminatorValue }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function initScheduleBackup({ getValue, model }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function onScheduleBackupChange({ commit, getValue, discriminator, model }) { - 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 kubedbComMSSQLServer annotation - deleteKubeDbComMongDbAnnotation(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, - }) - } - } -} - -// backup form -function showBackupForm({ getValue, discriminator, watchDependency }) { - 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({ storeGet, axios, getValue, model, setDiscriminatorValue }) { - // 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/kubedbComMSSQLServer') - 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, getValue, discriminator }) { - watchDependency('discriminator#/isBackupDataLoaded') - return !!getValue(discriminator, '/isBackupDataLoaded') -} - -async function setBackupType() { - return 'BackupConfig' -} - -async 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?.topology && isArchiverAvailable) { - arr.push({ - description: 'Enable/Disable Archiver', - text: 'Archiver', - value: 'Archiver', - }) - } - return arr -} - -function onBackupTypeChange({ commit, getValue, discriminator }) { - 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/kubedbComMSSQLServer', - value: objectCopy(dbResource), - force: true, - }) -} - -function isBackupType({ watchDependency, getValue, discriminator }, 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({ getValue, discriminator, commit, model, storeGet }) { - const blueprintSwitch = getValue(discriminator, '/blueprintEnabled') - if (blueprintSwitch) addLabelAnnotation(commit, storeGet, 'annotations') - else deleteLabelAnnotation(commit, 'annotations') -} - -function setArchiverSwitch() { - const archiver = dbResource?.spec?.archiver - return !!archiver -} - -function onArchiverChange({ getValue, discriminator, commit, model, storeGet }) { - const archiverSwitch = getValue(discriminator, '/archiverEnabled') - const path = 'resources/kubedbComMSSQLServer/spec/archiver' - if (archiverSwitch) { - commit('wizard/model$update', { - path: path, - value: initialArchiver ? initialArchiver : archiverObjectToCommit, - }) - } else { - commit('wizard/model$delete', path) - } -} -function addLabelAnnotation(commit, storeGet, 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/kubedbComMSSQLServer/metadata/${type}`, - value: obj, - force: true, - }) -} - -function deleteLabelAnnotation(commit, 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/kubedbComMSSQLServer/metadata/${type}`, - value: obj, - force: true, - }) -} + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) -function getContext() { - if (isBackupOn) return ['Create', 'Delete', 'Modify'] - return ['Create'] -} + const resources = (resp && resp.data && resp.data.items) || [] -function onContextChange({ getValue, discriminator, commit, model }) { - 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, + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } }) } -} - -function getConfigList({ storeGet }) { - 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({ getValue, discriminator, commit, storeGet, model }) { - 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, getValue, discriminator }) { - watchDependency('discriminator#/backupConfigContext') - watchDependency('discriminator#/config') - const contex = getValue(discriminator, '/backupConfigContext') - const configName = getValue(discriminator, '/config') - return !!configName && contex === 'Modify' -} - -function showConfigList({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/backupConfigContext') - const contex = getValue(discriminator, '/backupConfigContext') - return contex === 'Modify' || contex === 'Delete' -} - -function showSchedule({ watchDependency, getValue, discriminator }) { - 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 getNamespaceArray() { - return namespaceList -} - -// invoker form -function initBackupInvoker() { - return 'backupConfiguration' -} - -function initBlueprint() { - return 'create' -} -function initUsagePolicy() { - return 'Same' -} - -function onBackupInvokerChange({ getValue, discriminator, commit, model, storeGet }) { - const kind = storeGet('/resource/layout/result/resource/kind') - const backupInvoker = getValue(discriminator, '/backupInvoker') - const annotations = getValue(model, '/resources/kubedbComMSSQLServer/metadata/annotations') - - // get name namespace labels to set in db resource when backup is not enabled initially + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } - if (backupInvoker === 'backupConfiguration') { - commit('wizard/model$update', { - path: '/resources/coreKubestashComBackupConfiguration', - value: initialModel, - force: true, - }) + // function onNamespaceChange() { + // const namespace = getValue(model, '/metadata/release/namespace') + // const agent = getValue(model, '/resources/kubedbComMSSQLServer/spec/monitor/agent') + // if (agent === 'prometheus.io') { + // commit('wizard/model$update', { + // path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + // value: [namespace], + // force: true, + // }) + // } + // } - if ( - !dbResource.metadata?.annotations?.['blueprint.kubestash.com/name'] && - !dbResource.metadata?.annotations?.['blueprint.kubestash.com/namespace'] - ) { - delete annotations['blueprint.kubestash.com/name'] - delete annotations['blueprint.kubestash.com/namespace'] + function initMetadata() { + const dbName = + getValue( + model, + '/resources/autoscalingKubedbComMSSQLServerAutoscaler/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/kubedbComMSSQLServer/metadata/annotations', - value: annotations, + path: '/resources/autoscalingKubedbComMSSQLServerAutoscaler/metadata/name', + value: modifiedName, force: true, }) - } - } else if (backupInvoker === 'backupBlueprint') { - if (!isBackupOn) { - commit('wizard/model$delete', '/resources/coreKubestashComBackupConfiguration') - } - annotations['blueprint.kubestash.com/name'] = `${kind.toLowerCase()}-blueprint` - annotations['blueprint.kubestash.com/namespace'] = 'kubedb' - commit('wizard/model$update', { - path: '/resources/kubedbComMSSQLServer/metadata/annotations', - value: annotations, - force: true, - }) - } -} - -function showInvokerForm({ getValue, discriminator, watchDependency }, value) { - const backupInvoker = getValue(discriminator, '/backupInvoker') - watchDependency('discriminator#/backupInvoker') - - return backupInvoker === value -} - -// backup configuration form -function initalizeTargetReferenceName({ getValue, model, watchDependency }) { - const databaseName = getValue(model, '/metadata/release/name') - watchDependency('model#/metadata/release/name') - - return databaseName -} - -// restore session repository -function setInitialRestoreSessionRepo({ getValue, model }) { - const value = getValue(model, 'resources/stashAppscodeComRepository_init_repo') - return value ? 'create' : 'select' -} - -// backup config repository -function initRepositoryChoise({ getValue, model }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - - if (stashAppscodeComRepository_repo) return 'create' - else return 'select' -} - -function initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' - setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) - return repoInitialSelectionStatus -} - -function onRepositoryChoiseChange({ getValue, discriminator, watchDependency, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - if (repositoryChoise === 'select') { - // delete the stashAppscodeComRepository_repo - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') - } else if (repositoryChoise === 'create') { - // create new stashAppscodeComRepository_repo - if (!valueExists(model, getValue, '/resources/stashAppscodeComRepository_repo')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRepository_repo', - value: stashAppscodeComRepository_repo, - }) - const repositoryName = `${getValue(model, '/metadata/release/name')}-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) - } + // delete the other type object from model + if (type === 'compute') + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/storage', + ) + if (type === 'storage') + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/compute', + ) } -} - -function onRepositoryNameChange({ getValue, model, commit }) { - const repositoryName = getValue(model, 'resources/stashAppscodeComRepository_repo/metadata/name') - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) -} - -function onInputChange( - { getValue, discriminator, commit, model }, - modelPath, - field, - subfield, - discriminatorName, -) { - const value = getValue(discriminator, `/${discriminatorName}`) - const backends = getValue(model, modelPath) || [] - if (field !== 'encryptionSecret') backends[0][field][subfield] = value - else backends[0]['repositories'][0][field][subfield] = value - commit('wizard/model$update', { - path: modelPath, - value: backends, - }) -} -function setFileValueFromStash({ getValue, commit, model }, modelPath, field, subfield, value) { - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') backends[0][field][subfield] = value - else backends[0]['repositories'][0][field][subfield] = value - commit('wizard/model$update', { - path: modelPath, - value: backends, - }) -} -function onInputChangeSchedule( - { getValue, discriminator, commit, model }, - modelPath, - discriminatorName, -) { - const value = getValue(discriminator, `/${discriminatorName}`) - const session = getValue(model, modelPath) - session[0].scheduler.schedule = value - commit('wizard/model$update', { - path: modelPath, - value: session, - }) -} + async function fetchTopologyMachines() { + const instance = hasAnnotations() -function setInitSchedule( - { getValue, discriminator, watchDependency, commit, model }, - modelPath, - value, -) { - const session = getValue(model, modelPath) - session[0].scheduler.schedule = value - commit('wizard/model$update', { - path: modelPath, - value: session, - }) -} + 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) -function getDefault({ getValue, model }, modelPath, field, subfield) { - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') return backends[0][field][subfield] - else { - return backends[0]['repositories'][0][field][subfield] + const nodeGroups = resp.data?.spec?.nodeGroups || [] + setDiscriminatorValue('/topologyMachines', nodeGroups) + return nodeGroups + } catch (e) { + console.log(e) + return [] + } + } } -} - -function getDefaultSchedule({ getValue, model, watchDependency }, modelPath) { - watchDependency('discriminator#/config') - const session = getValue(model, modelPath) - return session?.length ? session[0]?.scheduler.schedule : '' -} - -// backup blueprint form -function getMongoAnnotations(getValue, model) { - const annotations = getValue(model, '/resources/kubedbComMSSQLServer/metadata/annotations') - return { ...annotations } || {} -} - -function initFromAnnotationValue({ getValue, model }, key) { - const annotations = getMongoAnnotations(getValue, model) - return annotations[key] -} -function onBackupBlueprintNameChange({ getValue, discriminator, commit, model }) { - const backupBlueprintName = getValue(discriminator, '/backupBlueprintName') - addKubeDbComMongDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/backup-blueprint', - backupBlueprintName, - true, - ) -} + function setAllowedMachine(minmax) { + const mx = instance?.includes(',') ? instance.split(',')[1] : '' + const mn = instance?.includes(',') ? instance.split(',')[0] : '' + const machineName = minmax === 'min' ? mn : mx -function onBackupBlueprintScheduleChange({ getValue, discriminator, commit, model }) { - const backupBlueprintSchedule = getValue(discriminator, '/schedule') - addKubeDbComMongDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/schedule', - backupBlueprintSchedule, - true, - ) -} + // Find the machine details from topologyMachines + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] + const machineData = nodeGroups.find((item) => item.topologyValue === machineName) -function initFromAnnotationKeyValue({ getValue, model }, prefix) { - const annotations = getMongoAnnotations(getValue, model) - const newOb = {} - Object.keys(annotations).forEach((key) => { - if (key.startsWith(prefix)) { - const newKey = key.replace(prefix, '') - newOb[newKey] = annotations[key] + // 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 newOb -} - -function onTaskParametersChange({ getValue, discriminator, model, commit }) { - const taskParameters = getValue(discriminator, '/taskParameters') + // Return empty object if no machine found + return { + machine: machineName || '', + cpu: '', + memory: '', + } + } - const taskParamterKeys = Object.keys(taskParameters).map( - (tp) => `params.stash.appscode.com/${tp}`, - ) - const oldAnnotations = - getValue(model, '/resources/kubedbComMSSQLServer/metadata/annotations') || {} - const newAnnotations = {} + function getMachines(minmax) { + // watchDependency('discriminator#/topologyMachines') + const depends = minmax === 'min' ? 'max' : 'min' + const dependantPath = `/allowedMachine-${depends}` - const filteredAnnotationKeys = Object.keys(oldAnnotations).filter( - (key) => !taskParamterKeys.includes(key) && !key.startsWith('params.stash.appscode.com/'), - ) + // watchDependency(`discriminator#${dependantPath}`) + const dependantMachineObj = getValue(discriminator, dependantPath) + const dependantMachine = dependantMachineObj?.machine || '' - filteredAnnotationKeys.forEach((key) => { - newAnnotations[key] = oldAnnotations[key] - }) + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] - Object.keys(taskParameters).forEach((tpk) => { - newAnnotations[`params.stash.appscode.com/${tpk}`] = taskParameters[tpk] - }) + const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) - commit('wizard/model$update', { - path: '/resources/kubedbComMSSQLServer/metadata/annotations', - value: newAnnotations, - }) -} + // 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, + }, + } + }) -function isValueExistInModel({ model, getValue }, path) { - const modelValue = getValue(model, path) - return !!modelValue -} + const filteredMachine = machines?.filter((item, ind) => + minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, + ) -function onNamespaceChange({ commit, model, getValue }) { - const namespace = getValue(model, '/metadata/release/namespace') - const agent = getValue(model, '/resources/kubedbComMSSQLServer/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', - value: [namespace], - force: true, - }) + return dependantIndex === -1 ? machines : filteredMachine } -} -function onLabelChange({ commit, model, getValue }) { - const labels = getValue(model, '/resources/kubedbComMSSQLServer/spec/metadata/labels') - - const agent = getValue(model, '/resources/kubedbComMSSQLServer/spec/monitor/agent') + function hasAnnotations() { + const annotations = + getValue( + model, + '/resources/autoscalingKubedbComMSSQLServerAutoscaler/metadata/annotations', + ) || {} + const instance = annotations['kubernetes.io/instance-type'] - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) + return !!instance } -} -function onNameChange({ commit, model, getValue }) { - const dbName = getValue(model, '/metadata/release/name') - - const agent = getValue(model, '/resources/kubedbComMSSQLServer/spec/monitor/agent') + function hasNoAnnotations() { + return !hasAnnotations() + } - const labels = getValue(model, '/resources/kubedbComMSSQLServer/spec/metadata/labels') + function onMachineChange(type) { + const annoPath = '/resources/autoscalingKubedbComMSSQLServerAutoscaler/metadata/annotations' + const annotations = getValue(model, annoPath) || {} + const instance = annotations['kubernetes.io/instance-type'] - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) - } + // 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 - const scheduleBackup = getValue(model, '/resources/stashAppscodeComBackupConfiguration') + // 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/autoscalingKubedbComMSSQLServerAutoscaler/spec/compute/${type}` - if (scheduleBackup) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_repo') - if (creatingNewRepo) { + if (minMachine && maxMachine && instance !== minMaxMachine) { commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: `${dbName}-repo`, + path: `${allowedPath}/maxAllowed`, + value: maxMachineAllocatable, + force: true, + }) + commit('wizard/model$update', { + path: `${allowedPath}/minAllowed`, + value: minMachineAllocatable, force: true, }) - } - } - - const prePopulateDatabase = getValue(model, '/resources/stashAppscodeComRestoreSession_init') - - if (prePopulateDatabase) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_init_repo') - if (creatingNewRepo) { commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: `${dbName}-init-repo`, + path: annoPath, + value: { ...annotations }, force: true, }) } } - // to reset configSecret name field - const hasSecretConfig = getValue(model, '/resources/secret_config') - if (hasSecretConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComMSSQLServer/spec/configSecret/name', - value: `${dbName}-config`, - force: true, - }) + 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 [] } - // to reset shard configSecret name field - const hasSecretShardConfig = getValue(model, '/resources/secret_shard_config') - if (hasSecretShardConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComMSSQLServer/spec/shardTopology/shard/configSecret/name', - value: `${dbName}-shard-config`, - force: true, - }) + function isNodeTopologySelected() { + // watchDependency( + // 'model#/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/compute/nodeTopology/name', + // ) + const nodeTopologyName = + getValue( + model, + '/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/compute/nodeTopology/name', + ) || '' + return !!nodeTopologyName.length } - // to reset shard configSecret name field - const hasSecretConfigServerConfig = getValue(model, '/resources/secret_configserver_config') - if (hasSecretConfigServerConfig) { + function setControlledResources(type) { + const list = ['cpu', 'memory'] + const path = `/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/compute/${type}/controlledResources` commit('wizard/model$update', { - path: '/resources/kubedbComMSSQLServer/spec/shardTopology/configServer/configSecret/name', - value: `${dbName}-configserver-config`, + path: path, + value: list, force: true, }) + return list } - // to reset mongos configSecret name field - const hasSecretMongosConfig = getValue(model, '/resources/secret_mongos_config') - if (hasSecretMongosConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComMSSQLServer/spec/shardTopology/mongos/configSecret/name', - value: `${dbName}-mongos-config`, - force: true, - }) + function setTrigger(path) { + let value = getValue(model, `/resources/${path}`) + if (value) return value + return 'On' } -} -function returnFalse() { - return false -} - -function onAgentChange({ commit, model, getValue }) { - const agent = getValue(model, '/resources/kubedbComMSSQLServer/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', - value: [], - force: true, - }) - - onNamespaceChange({ commit, model, getValue }) - onLabelChange({ commit, model, getValue }) - } else { - commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') + function setApplyToIfReady() { + return 'IfReady' } -} - -/************************************* Database Secret Section ********************************************/ - -function getCreateAuthSecret({ model, getValue }) { - const authSecret = getValue(model, '/resources/kubedbComMSSQLServer/spec/authSecret') - - return !authSecret -} - -function showExistingSecretSection({ getValue, watchDependency, discriminator }) { - watchDependency('discriminator#/createAuthSecret') - - const hasAuthSecretName = getValue(discriminator, '/createAuthSecret') - return !hasAuthSecretName -} - -function showPasswordSection({ getValue, watchDependency, discriminator }) { - return !showExistingSecretSection({ - getValue, - watchDependency, - discriminator, - }) -} -function setAuthSecretPassword({ model, getValue }) { - const encodedPassword = getValue(model, '/resources/secret_auth/data/password') - return encodedPassword ? decodePassword({}, encodedPassword) : '' -} - -function onAuthSecretPasswordChange({ getValue, discriminator, commit }) { - const stringPassword = getValue(discriminator, '/password') - - if (stringPassword) { - commit('wizard/model$update', { - path: '/resources/secret_auth/data/password', - value: encodePassword({}, stringPassword), - force: true, - }) - commit('wizard/model$update', { - path: '/resources/secret_auth/data/username', - value: encodePassword({}, 'root'), - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/secret_auth') + function showOpsRequestOptions() { + if (isKubedb({ storeGet }) === true) return true + // watchDependency( + // 'model#/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/databaseRef/name', + // ) + // watchDependency('discriminator#/autoscalingType') + return ( + !!getValue( + model, + '/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/databaseRef/name', + ) && !!getValue(discriminator, '/autoscalingType') + ) } -} - -// eslint-disable-next-line no-empty-pattern -function encodePassword({}, value) { - return btoa(value) -} -// eslint-disable-next-line no-empty-pattern -function decodePassword({}, value) { - return atob(value) -} - -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/resources/kubedbComMSSQLServer/spec/authSecret') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/resources/secret_auth') + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value } -} -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') + 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/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: { filter: { items: { metadata: { name: 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 [] - } -} - -//////////////////////////////////////// Service Monitor ////////////////////////////////////////////////////// - -//////////////////// service monitor /////////////////// + ) -function isEqualToServiceMonitorType({ rootModel, watchDependency }, value) { - watchDependency('rootModel#/spec/type') - return rootModel && rootModel.spec && rootModel.spec.type === value -} + const resources = (resp && resp.data && resp.data.items) || [] -//////////////////// custom config ///////////////// -function onConfigurationSourceChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSource') - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_config') - } else { - const value = getValue(model, '/resources/secret_config') - if (!value) { - commit('wizard/model$update', { - path: '/resources/secret_config', - value: {}, - force: true, + 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 [] } - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComMSSQLServer/spec/configSecret/name', - value: configSecretName, - force: true, - }) - } -} - -function onConfigurationChange({ getValue, commit, discriminator, model }) { - const value = getValue(discriminator, '/configuration') - commit('wizard/model$update', { - path: '/resources/secret_config/stringData/mongod.conf', - value: value, - force: true, - }) - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComMSSQLServer/spec/configSecret/name', - value: configSecretName, - force: true, - }) -} - -function setConfigurationSource({ model, getValue }) { - const modelValue = getValue(model, '/resources/secret_config') - if (modelValue) { - return 'create-new-config' } - return 'use-existing-config' -} -function setSecretConfigNamespace({ getValue, model, watchDependency }) { - watchDependency('model#/metadata/release/namespace') - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} - -//////////////////// custom config for sharded topology ///////////////// - -function setConfigurationSourceShard({ model, getValue, discriminator }) { - const src = getValue(discriminator, '/configurationSourceShard') - if (src) return src - const value = getValue(model, '/resources/secret_shard_config') - return value ? 'create-new-config' : 'use-existing-config' -} - -function setConfigurationSourceConfigServer({ model, getValue, discriminator }) { - const src = getValue(discriminator, '/configurationSourceConfigServer') - if (src) return src - const value = getValue(model, '/resources/secret_configserver_config') - return value ? 'create-new-config' : 'use-existing-config' -} + async function getNamespacedResourceList( + axios, + storeGet, + { namespace, group, version, resource }, + ) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function setConfigurationSourceMongos({ model, getValue, discriminator }) { - const src = getValue(discriminator, '/configurationSourceMongos') - if (src) return src - const value = getValue(model, '/resources/secret_mongos_config') - return value ? 'create-new-config' : 'use-existing-config' -} + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` -function isSchemaOf(schema) { - if (schema === 'discriminator#/configurationSourceShard') { - return 'shard' - } else if (schema === 'discriminator#/configurationSourceConfigServer') { - return 'configserver' - } else { - return 'mongos' - } -} + let ans = [] + try { + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) -function disableConfigSourceOption({ - itemCtx, - discriminator, - getValue, - watchDependency, - elementUi, -}) { - watchDependency('discriminator#/configurationSourceShard') - watchDependency('discriminator#/configurationSourceConfigServer') - watchDependency('discriminator#/configurationSourceMongos') - const configSrcShard = getValue(discriminator, '/configurationSourceShard') - const configSrcConfigServer = getValue(discriminator, '/configurationSourceConfigServer') - const configSrcMongos = getValue(discriminator, '/configurationSourceMongos') - if ( - itemCtx.value !== 'use-existing-config' && - itemCtx.value !== 'create-new-config' && - (configSrcShard === `same-as-${isSchemaOf(elementUi.schema.$ref)}-config-secret` || - configSrcConfigServer === `same-as-${isSchemaOf(elementUi.schema.$ref)}-config-secret` || - configSrcMongos === `same-as-${isSchemaOf(elementUi.schema.$ref)}-config-secret`) - ) { - return true - } - if ( - itemCtx.value === 'same-as-shard-config-secret' && - configSrcShard !== 'use-existing-config' && - configSrcShard !== 'create-new-config' - ) { - return true - } - if ( - itemCtx.value === 'same-as-configserver-config-secret' && - configSrcConfigServer !== 'use-existing-config' && - configSrcConfigServer !== 'create-new-config' - ) { - return true + const items = (resp && resp.data && resp.data.items) || [] + ans = items + } catch (e) { + console.log(e) + } + + return ans } - if ( - itemCtx.value === 'same-as-mongos-config-secret' && - configSrcMongos !== 'use-existing-config' && - configSrcMongos !== 'create-new-config' - ) { - return true + + /****** Monitoring *********/ + + function showMonitoringSection() { + // watchDependency('discriminator#/enableMonitoring') + const configureStatus = getValue(discriminator, '/enableMonitoring') + return configureStatus } - return false -} -function onConfigurationSourceMongosChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSourceMongos') - const configSecretName = `${getValue(model, '/metadata/release/name')}-mongos-config` - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_mongos_config') - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'mongos', - configurationSource, - '/configurationMongos', - ) - } else if (configurationSource === 'create-new-config') { - const value = getValue(model, '/resources/secret_mongos_config') - if (!value) { + function onEnableMonitoringChange() { + const configureStatus = getValue(discriminator, '/enableMonitoring') + if (configureStatus) { commit('wizard/model$update', { - path: '/resources/secret_mongos_config', + path: '/resources/kubedbComMSSQLServer/spec/monitor', value: {}, force: true, }) + } else { + commit('wizard/model$delete', '/resources/kubedbComMSSQLServer/spec/monitor') } + + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: '/resources/kubedbComMSSQLServer/spec/shardTopology/mongos/configSecret/name', - value: configSecretName, + path: '/form/alert/enabled', + value: configureStatus ? 'warning' : 'none', force: true, }) - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'mongos', - configurationSource, - '/configurationMongos', - ) - } else if (configurationSource === 'same-as-shard-config-secret') { - transferConfigSecret({ commit, model, getValue }, 'shard', 'mongos') - } else if (configurationSource === 'same-as-configserver-config-secret') { - transferConfigSecret({ commit, model, getValue }, 'configserver', 'mongos') } -} -function onConfigurationSourceShardChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSourceShard') - const configSecretName = `${getValue(model, '/metadata/release/name')}-shard-config` - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_shard_config') - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'shard', - configurationSource, - '/configurationShard', - ) - } else if (configurationSource === 'create-new-config') { - const value = getValue(model, '/resources/secret_shard_config') - if (!value) { + 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/secret_shard_config', + path: '/resources/kubedbComMSSQLServer/spec/monitor/prometheus/exporter', value: {}, force: true, }) + } else { + commit( + 'wizard/model$delete', + '/resources/kubedbComMSSQLServer/spec/monitor/prometheus/exporter', + ) } - commit('wizard/model$update', { - path: '/resources/kubedbComMSSQLServer/spec/shardTopology/shard/configSecret/name', - value: configSecretName, - force: true, - }) - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'shard', - configurationSource, - '/configurationShard', - ) - } else if (configurationSource === 'same-as-configserver-config-secret') { - transferConfigSecret({ commit, model, getValue }, 'configserver', 'shard') - } else if (configurationSource === 'same-as-mongos-config-secret') { - transferConfigSecret({ commit, model, getValue }, 'mongos', 'shard') } -} -function onConfigurationSourceConfigServerChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSourceConfigServer') - const configSecretName = `${getValue(model, '/metadata/release/name')}-configserver-config` - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_configserver_config') - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'configserver', - configurationSource, - '/configurationConfigServer', - ) - } else if (configurationSource === 'create-new-config') { - const value = getValue(model, '/resources/secret_configserver_config') - if (!value) { + function isValueExistInModel(path) { + const modelValue = getValue(model, path) || null + return !!modelValue + } + + function onLabelChange() { + const labels = getValue(model, '/resources/kubedbComMSSQLServer/spec/metadata/labels') + + const agent = getValue(model, '/resources/kubedbComMSSQLServer/spec/monitor/agent') + + if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: '/resources/secret_configserver_config', - value: {}, + path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', + value: labels, force: true, }) } - commit('wizard/model$update', { - path: '/resources/kubedbComMSSQLServer/spec/shardTopology/configServer/configSecret/name', - value: configSecretName, - force: true, - }) - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'configserver', - configurationSource, - '/configurationConfigServer', - ) - } else if (configurationSource === 'same-as-shard-config-secret') { - const configurationSourceReference = getValue(discriminator, '/configurationSourceShard') - transferConfigSecret( - { commit, model, getValue }, - 'shard', - 'configserver', - configurationSourceReference, - ) - } else if (configurationSource === 'same-as-mongos-config-secret') { - const configurationSourceReference = getValue(discriminator, '/configurationSourceMongos') - transferConfigSecret( - { commit, model, getValue }, - 'mongos', - 'configserver', - configurationSourceReference, - ) } -} -function transferConfigSecret({ commit, model, getValue }, src, des) { - const isShardedMode = getValue(model, '/resources/kubedbComMSSQLServer/spec/shardTopology') - if (isShardedMode) { - commit('wizard/model$update', { - path: `/resources/kubedbComMSSQLServer/spec/shardTopology/${ - des === 'configserver' ? 'configServer' : des - }/configSecret/name`, - value: getValue( - model, - `/resources/kubedbComMSSQLServer/spec/shardTopology/${ - src === 'configserver' ? 'configServer' : src - }/configSecret/name`, - ), - force: true, - }) + function onAgentChange() { + const agent = getValue(model, '/resources/kubedbComMSSQLServer/spec/monitor/agent') + if (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', + value: [], + force: true, + }) - commit('wizard/model$delete', `/resources/secret_${des}_config`) + onNamespaceChange() + onLabelChange() + } else { + commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') + } } -} -function onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - configType, - configSrc, - discriminatorPath, -) { - if (configSrc === 'create-new-config') { - const value = getValue(discriminator, discriminatorPath) - commit('wizard/model$update', { - path: `/resources/secret_${configType}_config/stringData/mongod.conf`, - value: value, - force: true, - }) + function onNamespaceChange() { + const namespace = getValue( + model, + '/resources/autoscalingKubedbComMSSQLServerAutoscaler/metadata/namespace', + ) + if (!namespace) { + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/databaseRef/name', + ) + } } - const configSrcShard = getValue(discriminator, '/configurationSourceShard') - const configSrcConfigServer = getValue(discriminator, '/configurationSourceConfigServer') - const configSrcMongos = getValue(discriminator, '/configurationSourceMongos') - if (configSrcShard === `same-as-${configType}-config-secret`) { - transferConfigSecret({ commit, model, getValue }, configType, 'shard') - } - if (configSrcConfigServer === `same-as-${configType}-config-secret`) { - transferConfigSecret({ commit, model, getValue }, configType, 'configserver') + 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/mssqlserveropsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` + } + + function setValueFrom() { + if (isConfigMapTypeValueFrom()) { + return 'configMap' + } else if (isSecretTypeValueFrom()) { + return 'secret' + } else { + return 'input' + } } - if (configSrcMongos === `same-as-${configType}-config-secret`) { - transferConfigSecret({ commit, model, getValue }, configType, 'mongos') + + 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 setConfiguration({ model, getValue }) { - return getValue(model, '/resources/secret_config/stringData/mongod.conf') -} + // function isEqualToValueFromType(value) { + // //watchDependency('discriminator#/valueFromType') + // const valueFrom = getValue(discriminator, '/valueFromType') + // return valueFrom === value + // } -function setConfigurationShard({ model, getValue }) { - const value = getValue(model, '/resources/secret_shard_config/stringData/mongod.conf') - return value -} + async function resourceNames(group, version, resource) { + const namespace = getValue(model, '/metadata/release/namespace') + // watchDependency('model#/metadata/release/namespace') -function setConfigurationConfigServer({ model, getValue }) { - const value = getValue(model, '/resources/secret_configserver_config/stringData/mongod.conf') - return value -} + let resources = await getNamespacedResourceList(axios, storeGet, { + namespace, + group, + version, + resource, + }) -function setConfigurationMongos({ model, getValue }) { - const value = getValue(model, '/resources/secret_mongos_config/stringData/mongod.conf') - return value -} + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } -function setConfigurationFiles({ model, getValue }) { - const value = getValue(model, '/resources/secret_config/data/mongod.conf') - return atob(value) -} + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -function setConfigurationFilesShard({ model, getValue }) { - const value = getValue(model, '/resources/secret_shard_config/data/mongod.conf') - return atob(value) -} + 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/kubedbComMSSQLServer/spec/monitor/prometheus/exporter/env/${index}/valueFrom/configMapKeyRef/name`, + ) -function setConfigurationFilesConfigServer({ model, getValue }) { - const value = getValue(model, '/resources/secret_configserver_config/data/mongod.conf') - return atob(value) -} + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/configMapKeyRef/name') -function setConfigurationFilesMongos({ model, getValue }) { - const value = getValue(model, '/resources/secret_mongos_config/data/mongod.conf') - return atob(value) -} + if (!configMapName) return [] -function onSetCustomConfigChange({ discriminator, getValue, commit }) { - const value = getValue(discriminator, '/setCustomConfig') + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/configmaps/${configMapName}`, + ) - if (value === 'no') { - commit('wizard/model$delete', '/resources/kubedbComMSSQLServer/spec/configSecret') - commit( - 'wizard/model$delete', - '/resources/kubedbComMSSQLServer/spec/shardTopology/shard/configSecret', - ) - commit( - 'wizard/model$delete', - '/resources/kubedbComMSSQLServer/spec/shardTopology/configServer/configSecret', - ) - commit( - 'wizard/model$delete', - '/resources/kubedbComMSSQLServer/spec/shardTopology/mongos/configSecret', - ) - commit('wizard/model$delete', '/resources/secret_config') - commit('wizard/model$delete', '/resources/secret_shard_config') - commit('wizard/model$delete', '/resources/secret_configserver_config') - commit('wizard/model$delete', '/resources/secret_mongos_config') - } -} + const configMaps = (resp && resp.data && resp.data.data) || {} -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + const configMapKeys = Object.keys(configMaps).map((item) => ({ + text: item, + value: item, + })) - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + return configMapKeys + } catch (e) { + console.log(e) + return [] + } } -} -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} + 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') -function showScheduleBackup({ storeGet }) { - const operationQuery = storeGet('/route/params/actions') || '' - const isBackupOperation = operationQuery === 'edit-self-backupconfiguration' ? true : false - return !isBackupOperation -} + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }, + ) -///////////////////////// Autoscaler /////////////////// -let autoscaleType = '' -let dbDetails = {} + const secrets = (resp && resp.data && resp.data.items) || [] -function isConsole({ storeGet, commit }) { - const isKube = isKubedb({ storeGet }) + const filteredSecrets = secrets.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) - if (isKube) { - const dbName = storeGet('/route/params/name') || '' - commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComMSSQLServerAutoscaler/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/autoscalingKubedbComMSSQLServerAutoscaler/metadata/name', - value: modifiedName, - force: true, - }) - const namespace = storeGet('/route/query/namespace') || '' - if (namespace) { - commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComMSSQLServerAutoscaler/metadata/namespace', - value: namespace, - force: true, + 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 [] } } - return !isKube -} - -function isKubedb({ storeGet }) { - return !!storeGet('/route/params/actions') -} - -function showOpsRequestOptions({ model, getValue, watchDependency, storeGet, discriminator }) { - if (isKubedb({ storeGet }) === true) return true - watchDependency( - 'model#/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/databaseRef/name', - ) - watchDependency('discriminator#/autoscalingType') - return ( - !!getValue( + 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/autoscalingKubedbComMSSQLServerAutoscaler/spec/databaseRef/name', - ) && !!getValue(discriminator, '/autoscalingType') - ) -} - -async function getNamespaces({ axios, storeGet }) { - 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({ axios, storeGet, model, getValue, watchDependency }) { - watchDependency('model#/resources/autoscalingKubedbComMSSQLServerAutoscaler/metadata/namespace') - const namespace = getValue( - model, - '/resources/autoscalingKubedbComMSSQLServerAutoscaler/metadata/namespace', - ) - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + `/resources/kubedbComMSSQLServer/spec/monitor/prometheus/exporter/env/${index}/valueFrom/secretKeyRef/name`, + ) - const resources = (resp && resp.data && resp.data.items) || [] + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/secretKeyRef/name') - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + if (!secretName) return [] -async function getDbDetails({ commit, setDiscriminatorValue, axios, storeGet, getValue, model }) { - const owner = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - const namespace = - storeGet('/route/query/namespace') || - getValue(model, '/resources/autoscalingKubedbComMSSQLServerAutoscaler/metadata/namespace') || - '' - const name = - storeGet('/route/params/name') || - getValue(model, '/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/databaseRef/name') || - '' - - if (namespace && name) { try { const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/mssqlservers/${name}`, + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets/${secretName}`, ) - dbDetails = resp.data || {} - setDiscriminatorValue('/dbDetails', true) + + 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 [] } } - commit('wizard/model$update', { - path: `/metadata/release/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/metadata/release/namespace`, - value: namespace, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/databaseRef/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComMSSQLServerAutoscaler/metadata/labels`, - value: dbDetails.metadata.labels, - force: true, - }) -} - -async function dbTypeEqualsTo({ watchDependency, commit }, type) { - watchDependency('discriminator#/dbDetails') + function returnFalse() { + return false + } - const { spec } = dbDetails || {} - const { topology } = spec || {} - let verd = '' - if (topology) verd = 'topology' - else { - verd = 'combined' + 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, + }) + } + } } - clearSpecModel({ commit }, verd) - return type === verd && spec -} -function clearSpecModel({ commit }, dbtype) { - if (dbtype === 'standalone') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/${autoscaleType}/cluster`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/${autoscaleType}/sentinel`, - ) - } else if (dbtype === 'cluster') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/${autoscaleType}/sentinel`, - ) - } else if (dbtype === 'sentinel') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/${autoscaleType}/cluster`, - ) + function setValueFromDbDetails(path) { + const value = getValue(model, path) + return value } -} -function initMetadata({ getValue, discriminator, model, commit, storeGet }) { - const dbName = - getValue(model, '/resources/autoscalingKubedbComMSSQLServerAutoscaler/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/autoscalingKubedbComMSSQLServerAutoscaler/metadata/name', - value: modifiedName, - force: true, - }) + // MS SQL Server Type Checking for Autoscaling + function mssqlserverTypeEqualsTo(mssqlserverType, type) { + // watchDependency('discriminator#/dbDetails') + autoscaleType = type + const dbDetailsSuccess = getValue(discriminator, '/dbDetails') - // delete the other type object from model - if (type === 'compute') - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/storage', - ) - if (type === 'storage') - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/compute', - ) -} + if (!dbDetailsSuccess) return false -function onNamespaceChange({ model, getValue, commit }) { - const namespace = getValue( - model, - '/resources/autoscalingKubedbComMSSQLServerAutoscaler/metadata/namespace', - ) - if (!namespace) { - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/databaseRef/name', - ) + // For MS SQL Server, we always use 'mssqlserver' as the type + // MS SQL Server doesn't have different topologies like MongoDB (standalone/replicaSet/sharded) + return mssqlserverType === 'mssqlserver' } -} - -function ifScalingTypeEqualsTo( - { storeGet, watchDependency, getValue, discriminator, model }, - type, -) { - watchDependency('discriminator#/autoscalingType') - watchDependency( - 'model#/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/databaseRef/name', - ) - const operation = storeGet('/route/params/actions') || '' - if (operation.length) { - const splitOp = operation.split('-') - if (splitOp.length > 2) autoscaleType = splitOp[2] - } else autoscaleType = getValue(discriminator, '/autoscalingType') || '' - const isDatabaseSelected = !!getValue( - model, - '/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/databaseRef/name', - ) - return autoscaleType === type && isDatabaseSelected -} + function onTriggerChange(type) { + const trigger = getValue(discriminator, `/${type}/trigger`) + const commitPath = `/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/${type}/trigger` -async function fetchNodeTopology({ axios, storeGet }) { - 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 + commit('wizard/model$update', { + path: commitPath, + value: trigger ? 'On' : 'Off', + force: true, }) - return mappedList - } catch (e) { - console.log(e) } - return [] -} - -function isNodeTopologySelected({ watchDependency, model, getValue }) { - watchDependency( - 'model#/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/compute/nodeTopology/name', - ) - const nodeTopologyName = - getValue( - model, - '/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/compute/nodeTopology/name', - ) || '' - return !!nodeTopologyName.length -} - -function setControlledResources({ commit }, type) { - const list = ['cpu', 'memory'] - const path = `/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/compute/${type}/controlledResources` - commit('wizard/model$update', { - path: path, - value: list, - force: true, - }) - return list -} -function setTrigger({ model, getValue }, path) { - let value = getValue(model, `/resources/${path}`) - if (value) return value - return 'On' -} - -function setApplyToIfReady() { - return 'IfReady' -} - -function handleUnit({ commit, model, getValue }, 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)) { + function setMetadata() { + const dbname = storeGet('/route/params/name') || '' + const namespace = storeGet('/route/query/namespace') || '' + const isKube = !!storeGet('/route/params/actions') + if (isKube) { commit('wizard/model$update', { - path: `/resources/${path}`, - value: updatedValue, + path: '/metadata/release/name', + value: dbname, force: true, }) - } - } else { - if (!isNaN(value)) { - value += 'Gi' commit('wizard/model$update', { - path: `/resources/${path}`, - value: value, + path: '/metadata/release/namespace', + value: namespace, force: true, }) } } -} - -function objectCopy(obj) { - const temp = JSON.stringify(obj) - return JSON.parse(temp) -} - -function getOpsRequestUrl({ storeGet, model, getValue, mode }, 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 + `/create-opsrequest-${reqType.toLowerCase()}?namespace=${namespace}` - - if (mode === 'standalone-step') 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` -} - -async function fetchTopologyMachines({ axios, getValue, storeGet, model, setDiscriminatorValue }) { - const instance = hasAnnotations({ model, getValue }) - 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) + 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/kubedbComMSSQLServer/metadata/labels') + const bindingValues = { + apiVersion: 'catalog.appscode.com/v1alpha1', + kind: 'MSSQLServerBinding', + metadata: { + labels, + name: dbName, + namespace: dbNamespace, + }, + spec: { + sourceRef: { + name: dbName, + namespace: dbNamespace, + }, + }, + } - const nodeGroups = resp.data?.spec?.nodeGroups || [] - setDiscriminatorValue('/topologyMachines', nodeGroups) - return nodeGroups - } catch (e) { - console.log(e) - return [] + if (value) { + commit('wizard/model$update', { + path: '/resources/catalogAppscodeComMSSQLServerBinding', + value: bindingValues, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/catalogAppscodeComMSSQLServerBinding') } } -} - -function setAllowedMachine({ model, getValue }, minmax) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComMSSQLServerAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - const mx = instance?.includes(',') ? instance.split(',')[1] : '' - const mn = instance?.includes(',') ? instance.split(',')[0] : '' - - if (minmax === 'min') return mn - else return mx -} - -async function getMachines({ getValue, watchDependency, discriminator }, minmax) { - watchDependency('discriminator#/topologyMachines') - const depends = minmax === 'min' ? 'max' : 'min' - const dependantPath = `/allowedMachine-${depends}` - - watchDependency(`discriminator#${dependantPath}`) - const dependantMachine = getValue(discriminator, dependantPath) - - const nodeGroups = getValue(discriminator, '/topologyMachines') || [] - const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) - - const machines = nodeGroups?.map((item) => { - const subText = `CPU: ${item.allocatable.cpu}, Memory: ${item.allocatable.memory}` - const text = item.topologyValue - return { text, subText, value: item.topologyValue } - }) - - const filteredMachine = machines?.filter((item, ind) => - minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, - ) - - return dependantIndex === -1 ? machines : filteredMachine -} - -function hasAnnotations({ model, getValue }) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComMSSQLServerAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - - return !!instance -} + 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 + }) -function hasNoAnnotations({ model, getValue }) { - return !hasAnnotations({ model, getValue }) -} + if (filteredEnv.length) + commit('wizard/model$update', { + path: '/resources/kubedbComMSSQLServer/spec/monitor/prometheus/exporter/env', + value: filteredEnv, + force: true, + }) + } -function onMachineChange({ model, getValue, discriminator, commit }, type) { - const annoPath = '/resources/autoscalingKubedbComMSSQLServerAutoscaler/metadata/annotations' - const annotations = getValue(model, annoPath) - const instance = annotations['kubernetes.io/instance-type'] + function initEnvArray() { + const env = getValue( + model, + '/resources/kubedbComMSSQLServer/spec/monitor/prometheus/exporter/env', + ) - const minMachine = getValue(discriminator, '/allowedMachine-min') - const maxMachine = getValue(discriminator, '/allowedMachine-max') - const minMaxMachine = `${minMachine},${maxMachine}` - annotations['kubernetes.io/instance-type'] = minMaxMachine + return env || [] + } - const machines = getValue(discriminator, `/topologyMachines`) || [] - const minMachineObj = machines.find((item) => item.topologyValue === minMachine) - const maxMachineObj = machines.find((item) => item.topologyValue === maxMachine) - const minMachineAllocatable = minMachineObj?.allocatable - const maxMachineAllocatable = maxMachineObj?.allocatable - const allowedPath = `/resources/autoscalingKubedbComMSSQLServerAutoscaler/spec/compute/${type}` + function isEqualToTemp(value, index) { + //watchDependency('discriminator#/valueFromType') + const valueFrom = getValue(discriminator, `/env/${index}/temp/valueFromType`) + return valueFrom === value + } - 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 initMonitoring() { + const env = + getValue(model, '/resources/kubedbComMSSQLServer/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 { - getOpsRequestUrl, - handleUnit, - isConsole, - getNamespaces, - getDbs, - isKubedb, - getDbDetails, - dbTypeEqualsTo, - clearSpecModel, - initMetadata, - onNamespaceChange, - ifScalingTypeEqualsTo, - fetchNodeTopology, - isNodeTopologySelected, - setControlledResources, - setTrigger, - setApplyToIfReady, - showOpsRequestOptions, - setInitSchedule, - fetchNames, - fetchNamespaces, - isRancherManaged, - onInputChangeSchedule, - getDefaultSchedule, - getBlueprints, - ifUsagePolicy, - initUsagePolicy, - isBlueprintOption, - initBlueprint, - getDefault, - onInputChange, - showBackupOptions, - showScheduleBackup, - isVariantAvailable, - fetchJsons, - disableLableChecker, - isEqualToModelPathValue, - getResources, - isEqualToDiscriminatorPath, - setValueFromModel, - isNotShardModeSelected, - isShardModeSelected, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - returnTrue, - returnStringYes, - getMongoDbVersions, - showAuthPasswordField, - showAuthSecretField, - showNewSecretCreateField, - isNotStandaloneMode, - showCommonStorageClassAndSizeField, - setDatabaseMode, - getStorageClassNames, - setStorageClass, - deleteDatabaseModePath, - isEqualToDatabaseMode, - setApiGroup, - getIssuerRefsName, - hasIssuerRefName, - hasNoIssuerRefName, - setClusterAuthMode, - setSSLMode, - showTlsConfigureSection, - onTlsConfigureChange, - getAliasOptions, - showMonitoringSection, - onEnableMonitoringChange, - showCustomizeExporterSection, - onCustomizeExporterChange, - disableInitializationSection, - valueExists, - initPrePopulateDatabase, - onPrePopulateDatabaseChange, - initDataSource, - onDataSourceChange, - initVolumeType, - onVolumeTypeChange, - showInitializationForm, - showScriptOrStashForm, - showConfigMapOrSecretName, - initializeNamespace, - showRepositorySelectOrCreate, - onInitRepositoryChoiseChange, - initCustomizeRestoreJobRuntimeSettings, - initCustomizeRestoreJobRuntimeSettingsForBackup, - onCustomizeRestoreJobRuntimeSettingsChange, - onCustomizeRestoreJobRuntimeSettingsChangeForBackup, - showRuntimeForm, - getImagePullSecrets, - getBackupConfigsAndAnnotations, - deleteKubeDbComMongDbAnnotation, - addKubeDbComMongDbAnnotation, - initScheduleBackup, - initScheduleBackupForEdit, - onScheduleBackupChange, - showBackupForm, - initBackupInvoker, - onBackupInvokerChange, - showInvokerForm, - initalizeTargetReferenceName, - setInitialRestoreSessionRepo, - initRepositoryChoise, - initRepositoryChoiseForEdit, - onRepositoryChoiseChange, - onRepositoryNameChange, - getMongoAnnotations, - initFromAnnotationValue, - onBackupBlueprintNameChange, - onBackupBlueprintScheduleChange, - initFromAnnotationKeyValue, - onTaskParametersChange, - isValueExistInModel, - onNamespaceChange, - onLabelChange, - onNameChange, - returnFalse, - onAgentChange, - getCreateAuthSecret, - showExistingSecretSection, - showPasswordSection, - setAuthSecretPassword, - onAuthSecretPasswordChange, - encodePassword, - decodePassword, - onCreateAuthSecretChange, - getSecrets, - isEqualToServiceMonitorType, - onConfigurationSourceChange, - onConfigurationChange, - setConfigurationSource, - setSecretConfigNamespace, - setConfigurationSourceShard, - setConfigurationSourceConfigServer, - setConfigurationSourceMongos, - isSchemaOf, - disableConfigSourceOption, - onConfigurationSourceMongosChange, - onConfigurationSourceShardChange, - onConfigurationSourceConfigServerChange, - transferConfigSecret, - onConfigSecretModelChange, - setConfiguration, - setConfigurationShard, - setConfigurationConfigServer, - setConfigurationMongos, - setConfigurationFiles, - setConfigurationFilesShard, - setConfigurationFilesConfigServer, - setConfigurationFilesMongos, - onSetCustomConfigChange, - getCreateNameSpaceUrl, - updateConfigServerStorageClass, - - initBackupData, - isBackupDataLoadedTrue, - setBackupType, - getTypes, - getNamespaceArray, - isBackupType, - getContext, - onContextChange, - getConfigList, - onConfigChange, - showPause, - showSchedule, - showConfigList, - setBlueprintSwitch, - onBlueprintChange, - setArchiverSwitch, - onArchiverChange, - onBackupTypeChange, - getMachines, - setAllowedMachine, - hasAnnotations, - hasNoAnnotations, - fetchTopologyMachines, - onMachineChange, + 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, + + isConsole, + isKubedb, + getDbDetails, + getNamespaces, + getDbs, + isRancherManaged, + onNamespaceChange, + initMetadata, + fetchTopologyMachines, + setAllowedMachine, + getMachines, + hasAnnotations, + hasNoAnnotations, + onMachineChange, + fetchNodeTopology, + isNodeTopologySelected, + setControlledResources, + setTrigger, + setApplyToIfReady, + showOpsRequestOptions, + + handleUnit, + + getOpsRequestUrl, + isValueExistInModel, + onEnableMonitoringChange, + showMonitoringSection, + onAgentChange, + getResources, + isEqualToModelPathValue, + onCustomizeExporterChange, + showCustomizeExporterSection, + onLabelChange, + setValueFrom, + onValueFromChange, + resourceNames, + getConfigMapKeys, + getSecrets, + getSecretKeys, + isConfigMapTypeValueFrom, + isSecretTypeValueFrom, + getNamespacedResourceList, + returnFalse, + onEnvArrayChange, + initEnvArray, + isEqualToTemp, + initMonitoring, + + setValueFromDbDetails, + mssqlserverTypeEqualsTo, + onTriggerChange, + setMetadata, + addOrRemoveBinding, + isBindingAlreadyOn, + } } diff --git a/charts/kubedbcom-mysql-editor-options/ui/create-ui.yaml b/charts/kubedbcom-mysql-editor-options/ui/create-ui.yaml index 8054fcfd21..d384260e83 100644 --- a/charts/kubedbcom-mysql-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-mysql-editor-options/ui/create-ui.yaml @@ -1,443 +1,450 @@ -steps: -- form: - discriminator: - bundleApiLoaded: - default: false - type: boolean - elements: - - computed: initBundle - if: returnFalse - type: label-element - - disableUnselect: true - fetch: getAdminOptions|databases/MySQL/versions - if: isToggleOn|databases/MySQL/versions - label: - text: labels.database.version - schema: - $ref: schema#/properties/spec/properties/admin/properties/databases/properties/MySQL/properties/versions/properties/default +step: +- type: single-step-form + loader: initBundle + elements: + - type: label-element + label: '' + subtitle: Select the MySQL version you want to deploy on Kubernetes. The chosen version determines the MongoDB engine features, compatibility, and runtime behavior of your database cluster. + - disableUnselect: true + loader: getAdminOptions|databases/MySQL/versions + if: + type: function + name: isToggleOn|databases/MySQL/versions + label: Database Version + schema: schema/properties/spec/properties/admin/properties/databases/properties/MySQL/properties/versions/properties/default + type: select + - init: + type: func + value: getDefault|databases/MySQL/mode + loader: getAdminOptions|databases/MySQL/mode + isHorizontal: true + if: + type: function + name: isToggleOn|databases/MySQL/mode + label: Database Mode + schema: schema/properties/spec/properties/mode + type: radio + - elements: + - type: horizontal-layout + showLabels: true + elements: + - label: Replicaset Number + schema: schema/properties/spec/properties/replicas + type: input + - label: Mode + options: + - text: Single-Primary + value: Single-Primary + - text: Multi-Primary + value: Multi-Primary + schema: schema/properties/spec/properties/groupReplication/properties/mode + type: select + if: + type: function + name: isEqualToModelPathValue|GroupReplication|/spec/mode + type: block-layout + - elements: + - type: horizontal-layout + showLabels: true + elements: + - label: Replicaset Number + schema: schema/properties/spec/properties/replicas + type: input + - label: Router Number + schema: schema/properties/spec/properties/innoDBCluster/properties/router/properties/replicas + type: input + - label: Mode + options: + - text: Single-Primary + value: Single-Primary + - text: Multi-Primary + value: Multi-Primary + schema: schema/properties/spec/properties/innoDBCluster/properties/mode + type: select + if: + type: function + name: isEqualToModelPathValue|InnoDBCluster|/spec/mode + type: block-layout + - elements: + - loader: getAppBindings + label: RemoteReplica SourceRef + validation: + type: required + schema: schema/properties/spec/properties/remoteReplica/properties/sourceRef type: select - - computed: getDefault|databases/MySQL/mode - fetch: getAdminOptions|databases/MySQL/mode - hasDescription: true - if: isToggleOn|databases/MySQL/mode - label: - text: labels.database.mode - schema: - $ref: schema#/properties/spec/properties/mode - type: radio - - elements: - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/replicas - type: input - - label: - text: Mode - options: - - text: Single-Primary - value: Single-Primary - - text: Multi-Primary - value: Multi-Primary - schema: - $ref: schema#/properties/spec/properties/groupReplication/properties/mode - type: select - if: isEqualToModelPathValue|GroupReplication|/spec/mode - type: single-step-form - - elements: - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/replicas - type: input - - label: - text: labels.replicaset.router_number - schema: - $ref: schema#/properties/spec/properties/innoDBCluster/properties/router/properties/replicas - type: input - - label: - text: Mode - options: - - text: Single-Primary - value: Single-Primary - - text: Multi-Primary - value: Multi-Primary - schema: - $ref: schema#/properties/spec/properties/innoDBCluster/properties/mode - type: select - if: isEqualToModelPathValue|InnoDBCluster|/spec/mode - type: single-step-form - - elements: - - fetch: getAppBindings - label: - text: RemoteReplica SourceRef - required: true - schema: - $ref: schema#/properties/spec/properties/remoteReplica/properties/sourceRef - type: select - if: isEqualToModelPathValue|RemoteReplica|/spec/mode - type: single-step-form - - elements: - - fetch: getAppBindings - label: - text: RemoteReplica SourceRef - required: true - schema: - $ref: schema#/properties/spec/properties/remoteReplica/properties/sourceRef - type: select - - label: - text: Errant Transaction Recovery Policy - options: - - text: Clone - value: Clone - - text: PseudoTransaction - value: PseudoTransaction - schema: - $ref: schema#/properties/spec/properties/semiSync/properties/errantTransactionRecoveryPolicy - type: select - if: isEqualToModelPathValue|SemiSync|/spec/mode - type: single-step-form + if: + type: function + name: isEqualToModelPathValue|RemoteReplica|/spec/mode + type: block-layout + - elements: + - type: horizontal-layout + showLabels: true + elements: + - loader: getAppBindings + label: RemoteReplica SourceRef + validation: + type: required + schema: schema/properties/spec/properties/remoteReplica/properties/sourceRef + type: select + - label: Errant Transaction Recovery Policy + options: + - text: Clone + value: Clone + - text: PseudoTransaction + value: PseudoTransaction + schema: schema/properties/spec/properties/semiSync/properties/errantTransactionRecoveryPolicy + type: select + if: + type: function + name: isEqualToModelPathValue|SemiSync|/spec/mode + type: block-layout + - elements: + - type: label-element + label: '' + subtitle: Select a machine profile to allocate CPU and memory resources for your database. Choose 'custom' to manually specify resource requirements or select a predefined profile. + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: Cpu + loader: setLimits|cpu + watcher: + func: setRequests|cpu + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: Memory + loader: setLimits|memory + watcher: + func: setRequests|memory + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + label: Machine profile + showLabels: true + type: block-layout + - elements: + - type: horizontal-layout + showLabels: true + elements: + - loader: getAdminOptions|storageClasses + if: + type: function + name: isToggleOn|storageClasses + label: Storage class + schema: schema/properties/spec/properties/admin/properties/storageClasses/properties/default + type: select + - label: Storage size + schema: schema/properties/spec/properties/persistence/properties/size + type: input + type: block-layout + - description: Configure Credentials, Deployment Mode etc. + elements: - elements: - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.cpu - onChange: setRequests|cpu - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.memory - onChange: setRequests|memory - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - label: - text: labels.machine_profile - show_label: true - type: single-step-form - - fetch: getAdminOptions|storageClasses - if: isToggleOn|storageClasses - label: - text: labels.storage.class - schema: - $ref: schema#/properties/spec/properties/admin/properties/storageClasses/properties/default + - type: label-element + label: '' + subtitle: Add custom labels and annotations to your database resources for organization, monitoring, and integration with other Kubernetes tools and services. + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/annotations + label: Labels & Annotations + showLabels: true + hideBlock: true + type: block-layout + - init: + type: func + value: getDefault|deletionPolicy + customClass: mt-20 + if: + type: function + name: isToggleOn|deletionPolicy + label: Deletion Policy + watcher: + func: setStorageClass + paths: + - schema/properties/spec/properties/deletionPolicy + options: + - description: options.deletionPolicy.delete.description + text: Delete + value: Delete + - description: options.deletionPolicy.halt.description + text: Halt + value: Halt + - description: options.deletionPolicy.wipeOut.description + text: WipeOut + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: DoNotTerminate + value: DoNotTerminate + schema: schema/properties/spec/properties/deletionPolicy type: select - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/persistence/properties/size + - if: + type: function + name: getDefaultValue|spec/admin/authCredential/customize + label: Provide Authentication Credentials? + watcher: + func: onAuthChange + paths: + - temp/createAuthSecret + schema: temp/createAuthSecret + type: switch + - if: + type: function + name: showReferSecretSwitch + label: Refer existing Secret? + watcher: + func: onReferSecretChange + paths: + - temp/referSecret + schema: temp/referSecret + type: switch + - loader: getReferSecrets + if: + type: function + name: showSecretDropdown + label: Secret + schema: schema/properties/spec/properties/authSecret/properties/name + type: select + - if: + type: function + name: showReferSecret + label: Password + schema: schema/properties/spec/properties/authSecret/properties/password type: input - - accordion: true - description: - text: Configure Credentials, Deployment Mode etc. - discriminator: - configDatabase: - default: false - type: boolean - createAuthSecret: - default: false - type: boolean - recovery: - default: false - type: boolean - referSecret: - default: false - type: boolean - elements: - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties + - if: + type: function + name: getDefaultValue|spec/admin/customConfiguration + label: Configure Database? + watcher: + func: clearConfiguration + paths: + - temp/configDatabase + schema: temp/configDatabase + type: switch + - if: + type: function + name: isConfigDatabaseOn + label: Configuration + schema: schema/properties/spec/properties/configuration + type: textarea + - init: + type: func + value: getDefault|pointInTimeRecovery + if: + type: function + name: isToggleOn|pointInTimeRecovery + label: Point in-time Recovery? + schema: temp/recovery + type: switch + - elements: + - type: label-element + label: '' + subtitle: Restore your database to a specific point in time by specifying the source database namespace, name, and the exact recovery timestamp for data restoration. + - type: horizontal-layout + showLabels: true + elements: + - label: Namespace + watcher: + func: setPointInTimeRecovery + paths: + - temp/refNamespace + forceRequired: true + validation: + type: required + schema: temp/refNamespace type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties + - label: Name + watcher: + func: setPointInTimeRecovery + paths: + - temp/refDBName + validation: + type: required + schema: temp/refDBName type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - computed: getDefault|deletionPolicy - customClass: mt-20 - if: isToggleOn|deletionPolicy - 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/spec/properties/deletionPolicy - type: select - - if: getDefaultValue|spec/admin/authCredential/customize - label: - text: Provide Authentication Credentials? - onChange: onAuthChange - schema: - $ref: discriminator#/createAuthSecret - type: switch - - if: showReferSecretSwitch - label: - text: Refer existing Secret? - onChange: onReferSecretChange - schema: - $ref: discriminator#/referSecret + - label: Recovery Timestamp + schema: schema/properties/spec/properties/init/properties/archiver/properties/recoveryTimestamp + type: date-time + watcher: + func: onTimestampChange + paths: + - schema/properties/spec/properties/init/properties/archiver/properties/recoveryTimestamp + if: + type: function + name: showRecovery + label: Point in-time Recovery + showLabels: true + type: block-layout + - if: + type: function + name: isToggleOn|deployment + label: Deployment + options: + - description: shared + text: Shared + value: Shared + - description: Dedicated + text: Dedicated + value: Dedicated + schema: schema/properties/spec/properties/admin/properties/deployment/properties/default + type: radio + - if: + type: function + name: isToggleOn|clusterTier + isHorizontal: true + label: ClusterTier + options: + - text: General Purpose + value: GeneralPurpose + - text: Memory Optimized + value: MemoryOptimized + - text: CPU Optimized + value: CPUOptimized + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/default + type: radio + - disableUnselect: true + loader: getAdminOptions|clusterTier/placement + if: + type: function + name: isToggleOn|clusterTier/placement + label: Placement + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + type: select + - disableUnselect: true + loader: getNodeTopology + if: + type: function + name: isToggleOn|clusterTier/nodeTopology + label: NodeTopology + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + type: select + label: Advanced Configuration + showLabels: true + type: block-layout + - description: Enable Backup, Monitoring, TLS etc. + elements: + - elements: + - init: + type: func + value: setMonitoring + if: + type: function + name: isToggleOn|monitoring + label: Enable Monitoring + watcher: + func: updateAlertValue + paths: + - temp/monitoring + schema: temp/monitoring type: switch - - fetch: getReferSecrets - if: showSecretDropdown - label: - text: Secret - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/name + - customClass: mt-10 + if: + type: function + name: showAlerts + label: Alert Options + options: + - text: None + value: none + - text: Critical + value: critical + - text: Warning + value: warning + - text: Info + value: info + schema: schema/properties/form/properties/alert/properties/enabled type: select - - if: showReferSecret - label: - text: labels.password - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/password - type: input - - computed: isConfigAvailable - if: getDefaultValue|spec/admin/customConfiguration - label: - text: Configure Database? - onChange: clearConfiguration - schema: - $ref: discriminator#/configDatabase + type: block-layout + - init: + type: func + value: setBackup + if: + type: function + name: isToggleOn|backup + label: Enable Backup? + watcher: + func: onBackupSwitch + paths: + - temp/backup + schema: temp/backup + type: switch + - elements: + - disable: showArchiverAlert + label: Enable Archiver? + watcher: + func: onArchiverChange + paths: + - schema/properties/spec/properties/admin/properties/archiver/properties/enable/properties/default + schema: schema/properties/spec/properties/admin/properties/archiver/properties/enable/properties/default type: switch - - if: isConfigDatabaseOn - label: - text: Configuration - schema: - $ref: schema#/properties/spec/properties/configuration - type: editor - - computed: getDefault|pointInTimeRecovery - if: isToggleOn|pointInTimeRecovery - label: - text: Point in-time Recovery? - schema: - $ref: discriminator#/recovery + - if: + type: function + name: showArchiverAlert + label: The selected StorageClass does not support Archiver + type: warning + if: + type: function + name: showArchiver + type: block-layout + - elements: + - if: + type: function + name: isToggleOn|tls + label: Enable TLS? + schema: schema/properties/spec/properties/admin/properties/tls/properties/default type: switch - - discriminator: - refDBName: - type: string - refNamespace: - type: string - elements: - - label: - text: Namespace - onChange: setPointInTimeRecovery - required: true - schema: - $ref: discriminator#/refNamespace - type: input - - label: - text: Name - onChange: setPointInTimeRecovery - required: true - schema: - $ref: discriminator#/refDBName - type: input - - customClass: mt-10 - label: - text: Recovery Timestamp - schema: - $ref: schema#/properties/spec/properties/init/properties/archiver/properties/recoveryTimestamp - type: input - if: showRecovery - label: - text: Point in-time Recovery - schema: - $ref: schema#/properties/spec/properties/init/properties/archiver - show_label: true - type: single-step-form - - hasDescription: true - if: isToggleOn|deployment - label: - text: labels.deployment.name - options: - - description: labels.deployment.shared - text: Shared - value: Shared - - description: labels.deployment.dedicated - text: Dedicated - value: Dedicated - schema: - $ref: schema#/properties/spec/properties/admin/properties/deployment/properties/default - type: radio - - if: isToggleOn|clusterTier - isHorizontal: true - label: - text: labels.clusterTier - options: - - text: General Purpose - value: GeneralPurpose - - text: Memory Optimized - value: MemoryOptimized - - text: CPU Optimized - value: CPUOptimized - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/default - type: radio - - disableUnselect: true - fetch: getAdminOptions|clusterTier/placement - if: isToggleOn|clusterTier/placement - label: - text: labels.placement - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default - type: select - - disableUnselect: true - fetch: getNodeTopology - if: isToggleOn|clusterTier/nodeTopology - label: - text: labels.nodeTopology - refresh: true - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + - loader: getAdminOptions|clusterIssuers + if: + type: function + name: showIssuer + label: Cluster Issuers + validation: + type: required + schema: schema/properties/spec/properties/admin/properties/clusterIssuers/properties/default type: select - hideForm: true - label: - text: Advanced Configuration - show_label: true - type: single-step-form - - accordion: true - description: - text: Enable Backup, Monitoring, TLS etc. - discriminator: - backup: - default: false - type: boolean - elements: - - discriminator: - monitoring: - default: false - type: boolean - elements: - - computed: setMonitoring - if: isToggleOn|monitoring - label: - text: labels.enable_monitoring - onChange: updateAlertValue - schema: - $ref: discriminator#/monitoring - type: switch - - customClass: mt-10 - if: showAlerts - label: - text: labels.alert.options - options: - - text: None - value: none - - text: Critical - value: critical - - text: Warning - value: warning - - text: Info - value: info - schema: - $ref: schema#/properties/form/properties/alert/properties/enabled - sortable: true - type: select - type: single-step-form - - computed: setBackup - if: isToggleOn|backup - label: - text: Enable Backup? - onChange: onBackupSwitch - schema: - $ref: discriminator#/backup + type: block-layout + - elements: + - if: + type: function + name: isToggleOn|expose + label: Expose via Gateway? + schema: schema/properties/spec/properties/admin/properties/expose/properties/default type: switch - - elements: - - disabled: showArchiverAlert - label: - text: Enable Archiver? - onChange: onArchiverChange - schema: - $ref: schema#/properties/spec/properties/admin/properties/archiver/properties/enable/properties/default - type: switch - - alertInfo: - show: true - type: neutral - if: showArchiverAlert - label: - text: The selected StorageClass does not support Archiver - type: label-element - if: showArchiver - type: single-step-form - - elements: - - if: isToggleOn|tls - label: - text: Enable TLS? - schema: - $ref: schema#/properties/spec/properties/admin/properties/tls/properties/default - type: switch - - fetch: getAdminOptions|clusterIssuers - if: showIssuer - label: - text: labels.clusterIssuers - required: true - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterIssuers/properties/default - type: select - type: single-step-form - - elements: - - if: isToggleOn|expose - label: - text: Expose via Gateway? - schema: - $ref: schema#/properties/spec/properties/admin/properties/expose/properties/default - type: switch - type: single-step-form - if: showAdditionalSettings - label: - text: Additional Options - show_label: true - type: single-step-form - type: single-step-form + type: block-layout + if: + type: function + name: showAdditionalSettings + label: Additional Options + showLabels: true + type: block-layout id: options - title: steps.0.label + # title: steps.0.label type: multi-step-form diff --git a/charts/kubedbcom-mysql-editor-options/ui/functions.js b/charts/kubedbcom-mysql-editor-options/ui/functions.js index 044415e568..91706befdd 100644 --- a/charts/kubedbcom-mysql-editor-options/ui/functions.js +++ b/charts/kubedbcom-mysql-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -327,1092 +329,1195 @@ const modeDetails = { }, } -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) + + setDiscriminatorValue('bundleApiLoaded', false) + setDiscriminatorValue('configDatabase', false) + setDiscriminatorValue('createAuthSecret', false) + setDiscriminatorValue('recovery', false) + setDiscriminatorValue('referSecret', false) + setDiscriminatorValue('refDBName', '') + setDiscriminatorValue('refNamespace', '') + setDiscriminatorValue('backup', false) + setDiscriminatorValue('monitoring', false) + + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, }, - }, - ) - const projects = resp?.data?.status?.projects - if (projects) { - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - - namespaces = projectsNamespace - } else { - namespaces = resp?.data?.status?.namespaces || [] + ) + const projects = resp?.data?.status?.projects + if (projects) { + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + + namespaces = projectsNamespace + } else { + namespaces = resp?.data?.status?.namespaces || [] + } + return namespaces + } catch (e) { + console.log(e) + return [] } - return namespaces - } catch (e) { - console.log(e) - return [] } -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } -function showRecovery({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/recovery') - const isRecoveryOn = getValue(discriminator, '/recovery') || '' - return isRecoveryOn -} + function showRecovery() { + // watchDependency('discriminator#/recovery') + const isRecoveryOn = getValue(discriminator, '/recovery') || '' + return isRecoveryOn + } -function getMachineListForOptions({ model, getValue }) { - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') let array = [] + function getMachineListForOptions() { + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') - if (available.length) { - array = available.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - else { - let subText = '', - text = '' - const machineData = machinesFromPreset.find((val) => val.id === machine) - if (machineData) { - subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` - text = machineData.name ? machineData.name : machineData.id - } - return { text, subText, value: machine } - } - }) - } else { - array = machineList - .map((machine) => { + if (available.length) { + array = available.map((machine) => { if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + else { + let subText = '', + text = '' + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + text = machineData.name ? machineData.name : machineData.id + } + return { text, subText, value: machine } + } }) - .filter((val) => !!val) + } else { + array = machineList + .map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { text, subText, value: machine } + }) + .filter((val) => !!val) + } + return array } - return array -} -function setLimits({ model, getValue, commit, watchDependency }, resource, type) { - const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' - watchDependency(`model#${path}`) - const selectedMachine = getValue(model, path) || 'custom' - const reqCommitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - const comparePath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - - const resourceValue = getValue(model, comparePath) - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - - let cpu = '', - memory = '' - if (available.length && selectedMachine !== 'custom') { - const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) - if (machineData) { - cpu = machineData.limits.cpu - memory = machineData.limits.memory + function setLimits(resource, type) { + const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' + // watchDependency(`model#${path}`) + const selectedMachine = getValue(model, path) || 'custom' + const reqCommitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + const comparePath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + + const resourceValue = getValue(model, comparePath) + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + let cpu = '', + memory = '' + if (available.length && selectedMachine !== 'custom') { + const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) + if (machineData) { + cpu = machineData.limits.cpu + memory = machineData.limits.memory + } + } else { + if (selectedMachine === 'custom') { + cpu = resourceValue + memory = resourceValue + } else { + cpu = machines[selectedMachine].resources.limits.cpu + memory = machines[selectedMachine].resources.limits.memory + } } - } else { - if (selectedMachine === 'custom') { - cpu = resourceValue - memory = resourceValue + + if (resource === 'memory') { + commit('wizard/model$update', { + path: reqCommitPath, + value: memory, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: memory, + force: true, + }) + return memory } else { - cpu = machines[selectedMachine].resources.limits.cpu - memory = machines[selectedMachine].resources.limits.memory + commit('wizard/model$update', { + path: reqCommitPath, + value: cpu, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: cpu, + force: true, + }) + return cpu } } - if (resource === 'memory') { + function setRequests(resource, type) { + const modelPath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + + const fullpath = `/spec/podResources/machine` + const modelPathValue = getValue(model, fullpath) + commit('wizard/model$update', { - path: reqCommitPath, - value: memory, + path: commitPath, + value: val, force: true, }) - commit('wizard/model$update', { - path: comparePath, - value: memory, - force: true, + + if (modelPathValue === 'custom') { + return + } + let commitCpuMemory, ModelPathValue + if (resource && type) { + const fullPath = `/spec/${type}/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/${type}/podResources/resources/requests/${resource}` + } else { + const fullPath = `/spec/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/podResources/resources/requests/${resource}` + } + let cpuMemoryValue + array.forEach((item) => { + if (item.value === ModelPathValue) { + // Parse subText like "CPU: 2, Memory: 2Gi" + const subText = item.subText || '' + if (resource === 'cpu') { + // Extract CPU value + const cpuMatch = subText.match(/CPU:\s*([^,]+)/) + cpuMemoryValue = cpuMatch ? cpuMatch[1].trim() : '' + } else if (resource === 'memory') { + // Extract Memory value + const memoryMatch = subText.match(/Memory:\s*(.+)/) + cpuMemoryValue = memoryMatch ? memoryMatch[1].trim() : '' + } + } }) - return memory - } else { commit('wizard/model$update', { - path: reqCommitPath, - value: cpu, + path: commitCpuMemory, + value: cpuMemoryValue, force: true, }) + return cpuMemoryValue + } + + function setRequests(resource) { + const modelPath = `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = `/spec/podResources/resources/limits/${resource}` commit('wizard/model$update', { - path: comparePath, - value: cpu, + path: commitPath, + value: val, force: true, }) - return cpu } -} - -function setRequests({ getValue, model, commit }, resource) { - const modelPath = `/spec/podResources/resources/requests/${resource}` - const val = getValue(model, modelPath) - commitPath = `/spec/podResources/resources/limits/${resource}` - commit('wizard/model$update', { - path: commitPath, - value: val, - force: true, - }) -} -function setMachineToCustom({ getValue, model }) { - const machine = getValue(model, '/spec/admin/machineProfiles/default') - return machine || 'custom' -} + function setMachineToCustom() { + const machine = getValue(model, '/spec/admin/machineProfiles/default') + return machine || 'custom' + } -function isMachineCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue === 'custom' -} + function isMachineCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue === 'custom' + } -function isMachineNotCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue !== 'custom' && !!modelPathValue -} + function isMachineNotCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue !== 'custom' && !!modelPathValue + } -function updateAlertValue({ commit, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const alert = isMonitorEnabled ? 'warning' : 'none' - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: alert, - force: true, - }) - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} + function updateAlertValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const alert = isMonitorEnabled ? 'warning' : 'none' + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: alert, + force: true, + }) + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: agent, + force: true, + }) + } -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function getCreateNameSpaceUrl() { + 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + const domain = storeGet('/domain') || '' + if (domain.includes('bb.test')) { + return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } } -} -const ifCapiProviderIsNotEmpty = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/provider') - const val = getValue(model, '/form/capi/provider') - if (val) return true -} + const ifCapiProviderIsNotEmpty = () => { + // watchDependency('model#/form/capi/provider') + const val = getValue(model, '/form/capi/provider') + if (val) return true + } -const showMultiselectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') + const showMultiselectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') - if (val === 'capz' && ifDedicated({ model, getValue })) return true -} + if (val === 'capz' && ifDedicated()) return true + } -const showSelectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') - if (val !== 'capz' && ifDedicated({ model, getValue })) return true -} + const showSelectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') + if (val !== 'capz' && ifDedicated()) return true + } -const ifDedicated = ({ model, getValue }) => { - const val = getValue(model, 'form/capi/dedicated') - if (val) return true -} + const ifDedicated = () => { + const val = getValue(model, 'form/capi/dedicated') + if (val) return true + } -const dedicatedOnChange = ({ model, getValue, commit }) => { - const val = getValue(model, 'form/capi/dedicated') - if (!val) { - commit('wizard/model$delete', 'form/capi/zones') - commit('wizard/model$delete', 'form/capi/sku') + const dedicatedOnChange = () => { + const val = getValue(model, 'form/capi/dedicated') + if (!val) { + commit('wizard/model$delete', 'form/capi/zones') + commit('wizard/model$delete', 'form/capi/sku') + } } -} -const ifZones = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/zones') - watchDependency('model#/form/capi/dedicated') - const zones = getValue(model, 'form/capi/zones') || [] - const isDedicated = getValue(model, 'form/capi/dedicated') - if (zones.length && isDedicated) return true -} + const ifZones = () => { + // watchDependency('model#/form/capi/zones') + // watchDependency('model#/form/capi/dedicated') + const zones = getValue(model, 'form/capi/zones') || [] + const isDedicated = getValue(model, 'form/capi/dedicated') + if (zones.length && isDedicated) return true + } -const zonesOnChange = ({ model, getValue, commit }) => { - const zones = getValue(model, 'form/capi/zones') || [] - if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') -} + const zonesOnChange = () => { + const zones = getValue(model, 'form/capi/zones') || [] + if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') + } -async function getZones({ storeGet, axios, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const isDedicated = getValue(model, 'form/capi/dedicated') - if (isDedicated) { - try { - const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) - const val = resp.data.map((item) => { - return { value: item, text: item } - }) - return val - } catch (e) { - console.log(e) - return [] + async function getZones() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const isDedicated = getValue(model, 'form/capi/dedicated') + if (isDedicated) { + try { + const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) + const val = resp.data.map((item) => { + return { value: item, text: item } + }) + return val + } catch (e) { + console.log(e) + return [] + } } } -} -async function getSKU({ storeGet, axios, model, getValue, watchDependency }) { - watchDependency('model#/form/capi/zones') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const zones = getValue(model, 'form/capi/zones') || [] - if (zones.length) { - try { - let url = `clustersv2/${owner}/${cluster}/vms?` - if (typeof zones === 'string') { - url += `zones=${encodeURIComponent(zones)}` - } else { - zones.forEach((item) => { - url += `zones=${encodeURIComponent(item)}&` + async function getSKU() { + // watchDependency('model#/form/capi/zones') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const zones = getValue(model, 'form/capi/zones') || [] + if (zones.length) { + try { + let url = `clustersv2/${owner}/${cluster}/vms?` + if (typeof zones === 'string') { + url += `zones=${encodeURIComponent(zones)}` + } else { + zones.forEach((item) => { + url += `zones=${encodeURIComponent(item)}&` + }) + url = url.slice(0, -1) + } + const resp = await axios.get(url) + const val = resp.data.map((item) => { + return { + value: item.name, + text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, + } }) - url = url.slice(0, -1) + return val + } catch (e) { + console.log(e) + return [] } - const resp = await axios.get(url) - const val = resp.data.map((item) => { - return { - value: item.name, - text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, - } - }) - return val - } catch (e) { - console.log(e) - return [] } } -} -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false + } -function setStorageClass({ model, getValue, commit, discriminator, watchDependency }) { - const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' - let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' - const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] - const suffix = '-retain' + function setStorageClass() { + const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' + let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' + const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] + const suffix = '-retain' - const simpleClassList = storageClassList.filter((item) => { - return !item.endsWith(suffix) - }) + const simpleClassList = storageClassList.filter((item) => { + return !item.endsWith(suffix) + }) - const retainClassList = storageClassList.filter((item) => { - return item.endsWith(suffix) - }) + const retainClassList = storageClassList.filter((item) => { + return item.endsWith(suffix) + }) + + if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { + storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] + } else { + storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + } - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] - } else { - storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + const isChangeable = isToggleOn('storageClasses') + if (isChangeable && storageClass) { + commit('wizard/model$update', { + path: '/spec/admin/storageClasses/default', + value: storageClass, + force: true, + }) + } } - const isChangeable = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'storageClasses', - ) - if (isChangeable && storageClass) { + let placement = [] + let versions = [] + let storageClass = [] + let clusterIssuers = [] + let nodetopologiesShared = [] + let nodetopologiesDedicated = [] + let features = [] + let namespaces = [] + async function initBundle() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + + let db = getValue(model, '/metadata/resource/kind') + db = db.toLowerCase() + let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` + const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` + + try { + const resp = await axios.get(url) + features = resp.data.features || [] + placement = resp.data.placementpolicies || [] + versions = resp.data.versions || [] + storageClass = resp.data.storageclasses || [] + clusterIssuers = resp.data.clusterissuers || [] + nodetopologiesDedicated = resp.data.dedicated || [] + nodetopologiesShared = resp.data.shared || [] + + const response = await axios.get(annotationUrl) + const annotations = response.data?.metadata?.annotations || {} + const uidRange = annotations['openshift.io/sa.scc.uid-range'] + if (uidRange) { + const val = uidRange.split('/')[0] + commit('wizard/model$update', { + path: '/spec/openshift/securityContext/runAsUser', + value: val, + force: true, + }) + } + } catch (e) { + console.log(e) + } + commit('wizard/model$update', { - path: '/spec/admin/storageClasses/default', - value: storageClass, + path: '/spec/deletionPolicy', + value: getDefault('deletionPolicy'), force: true, }) - } -} -let placement = [] -let versions = [] -let storageClass = [] -let clusterIssuers = [] -let nodetopologiesShared = [] -let nodetopologiesDedicated = [] -let features = [] -let namespaces = [] -async function initBundle({ commit, model, getValue, axios, storeGet, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - - let db = getValue(model, '/metadata/resource/kind') - db = db.toLowerCase() - let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` - const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - - try { - const resp = await axios.get(url) - features = resp.data.features || [] - placement = resp.data.placementpolicies || [] - versions = resp.data.versions || [] - storageClass = resp.data.storageclasses || [] - clusterIssuers = resp.data.clusterissuers || [] - nodetopologiesDedicated = resp.data.dedicated || [] - nodetopologiesShared = resp.data.shared || [] - - const response = await axios.get(annotationUrl) - const annotations = response.data?.metadata?.annotations || {} - const uidRange = annotations['openshift.io/sa.scc.uid-range'] - if (uidRange) { - const val = uidRange.split('/')[0] + if (!getValue(model, `/spec/admin/databases/MySQL/mode/toggle`)) { + let defMode = getDefault('databases/MySQL/mode') || '' + if (defMode === '') { + const arr = getValue(model, '/spec/databases/MySQL/mode/available') || [] + if (arr.length) defMode = arr[0] + } commit('wizard/model$update', { - path: '/spec/openshift/securityContext/runAsUser', - value: val, + path: '/spec/mode', + value: defMode, force: true, }) } - } catch (e) { - console.log(e) - } - commit('wizard/model$update', { - path: '/spec/deletionPolicy', - value: getDefault({ getValue, model }, 'deletionPolicy'), - force: true, - }) - - if (!getValue(model, `/spec/admin/databases/MySQL/mode/toggle`)) { - let defMode = getDefault({ getValue, model }, 'databases/MySQL/mode') || '' - if (defMode === '') { - const arr = getValue(model, '/spec/databases/MySQL/mode/available') || [] - if (arr.length) defMode = arr[0] + if (!features.includes('tls')) { + commit('wizard/model$update', { + path: '/spec/admin/tls/default', + value: false, + force: true, + }) } - commit('wizard/model$update', { - path: '/spec/mode', - value: defMode, - force: true, - }) + if (!features.includes('binding')) { + commit('wizard/model$update', { + path: '/spec/admin/expose/default', + value: false, + force: true, + }) + } + if (!features.includes('monitoring')) { + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: 'none', + force: true, + }) + } + if (!features.includes('backup')) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: '', + force: true, + }) + } + namespaces = getNamespaces() + setDiscriminatorValue('/bundleApiLoaded', true) } - if (!features.includes('tls')) { - commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: false, - force: true, - }) - } - if (!features.includes('binding')) { - commit('wizard/model$update', { - path: '/spec/admin/expose/default', - value: false, - force: true, - }) - } - if (!features.includes('monitoring')) { - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: 'none', - force: true, - }) + function fetchNamespaces() { + // watchDependency('discriminator#/bundleApiLoaded') + return namespaces } - if (!features.includes('backup')) { - commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, - force: true, - }) - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: '', - force: true, - }) + + async function getRecoveryNames(type) { + // watchDependency(`model#/spec/init/archiver/${type}/namespace`) + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/spec/init/archiver/${type}/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${namespace}/repositories` + if (type === 'encryptionSecret') + url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` + const options = [] + if (namespace) { + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + } + return options } - namespaces = getNamespaces({ axios, storeGet }) - setDiscriminatorValue('/bundleApiLoaded', true) -} -function fetchNamespaces({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return namespaces -} + function fetchOptions(type) { + let kind = getValue(model, '/metadata/resource/kind') + + let returnArray = [] + if (type === 'clusterTier/placement') { + returnArray = placement + } else if (type === `databases/${kind}/versions`) { + returnArray = versions + } else if (type === 'storageClasses') { + returnArray = storageClass + } else if (type === 'clusterIssuers') { + returnArray = clusterIssuers + } -async function getRecoveryNames({ getValue, model, watchDependency, storeGet, axios }, type) { - watchDependency(`model#/spec/init/archiver/${type}/namespace`) - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/spec/init/archiver/${type}/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${namespace}/repositories` - if (type === 'encryptionSecret') - url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - const options = [] - if (namespace) { - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) + if (returnArray.length === 1) { + const path = `/spec/admin/${type}/default` + commit('wizard/model$update', { + path: path, + value: returnArray[0], + force: true, }) - } catch (e) { - console.log(e) } - } - return options -} -function fetchOptions({ model, getValue, commit }, type) { - let kind = getValue(model, '/metadata/resource/kind') - - let returnArray = [] - if (type === 'clusterTier/placement') { - returnArray = placement - } else if (type === `databases/${kind}/versions`) { - returnArray = versions - } else if (type === 'storageClasses') { - returnArray = storageClass - } else if (type === 'clusterIssuers') { - returnArray = clusterIssuers + return returnArray } - if (returnArray.length === 1) { - const path = `/spec/admin/${type}/default` - commit('wizard/model$update', { - path: path, - value: returnArray[0], - force: true, - }) - } + let archiverMap = [] + let archiverCalled = false - return returnArray -} + function getAdminOptions(type) { + // watchDependency('discriminator#/bundleApiLoaded') -let archiverMap = [] -let archiverCalled = false + if (type === 'storageClasses' && !archiverCalled) { + getArchiverName() + } -function getAdminOptions({ getValue, model, watchDependency, axios, storeGet, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') + const options = getValue(model, `/spec/admin/${type}/available`) || [] - if (type === 'storageClasses' && !archiverCalled) { - getArchiverName({ axios, storeGet }) + if (options.length === 0) { + return fetchOptions(type) + } + if (type.endsWith('/mode')) { + return ( + options?.map((item) => ({ + description: modeDetails[item]?.description || '', + text: modeDetails[item]?.text || '', + value: item, + })) || [] + ) + } + return options } - const options = getValue(model, `/spec/admin/${type}/available`) || [] - - if (options.length === 0) { - return fetchOptions({ model, getValue, commit }, type) + function showArchiver() { + return checkIfFeatureOn('archiver') } - if (type.endsWith('/mode')) { - return ( - options?.map((item) => ({ - description: modeDetails[item]?.description || '', - text: modeDetails[item]?.text || '', - value: item, - })) || [] - ) - } - return options -} -function showArchiver({ getValue, model }) { - return checkIfFeatureOn({ getValue, model }, 'archiver') -} + async function getArchiverName() { + try { + archiverCalled = true + const params = storeGet('/route/params') + const { user, cluster, group, resource } = params + const url = `/clusters/${user}/${cluster}/proxy/storage.k8s.io/v1/storageclasses` + const resp = await axios.get(url) -async function getArchiverName({ axios, storeGet }) { - try { - archiverCalled = true - const params = storeGet('/route/params') - const { user, cluster, group, resource } = params - const url = `/clusters/${user}/${cluster}/proxy/storage.k8s.io/v1/storageclasses` - const resp = await axios.get(url) - - resp.data?.items?.forEach((item) => { - const annotations = item.metadata?.annotations - const classname = item.metadata?.name - const annotationKeyToFind = `${resource}.${group}/archiver` - archiverMap.push({ storageClass: classname, annotation: annotations[annotationKeyToFind] }) - return resp.data - }) - } catch (e) { - console.log(e) + resp.data?.items?.forEach((item) => { + const annotations = item.metadata?.annotations + const classname = item.metadata?.name + const annotationKeyToFind = `${resource}.${group}/archiver` + archiverMap.push({ storageClass: classname, annotation: annotations[annotationKeyToFind] }) + return resp.data + }) + } catch (e) { + console.log(e) + } } -} -function onArchiverChange({ model, getValue, commit }) { - const isArchiverOn = getValue(model, '/spec/admin/archiver/enable/default') + function onArchiverChange() { + const isArchiverOn = getValue(model, '/spec/admin/archiver/enable/default') - const stClass = getValue(model, '/spec/admin/storageClasses/default') - const found = archiverMap.find((item) => item.storageClass === stClass) - const via = getValue(model, '/spec/admin/archiver/via') + const stClass = getValue(model, '/spec/admin/storageClasses/default') + const found = archiverMap.find((item) => item.storageClass === stClass) + const via = getValue(model, '/spec/admin/archiver/via') - if (!isArchiverOn) { - commit('wizard/model$update', { - path: '/spec/archiverName', - value: '', - force: true, - }) - } else { - if (via === 'VolumeSnapshotter') { + if (!isArchiverOn) { commit('wizard/model$update', { path: '/spec/archiverName', - value: found.annotation, + value: '', force: true, }) } else { - const kind = getValue(model, '/metadata/resource/kind') - commit('wizard/model$update', { - path: '/spec/archiverName', - value: kind.toLowerCase(), - force: true, - }) + if (via === 'VolumeSnapshotter') { + commit('wizard/model$update', { + path: '/spec/archiverName', + value: found.annotation, + force: true, + }) + } else { + const kind = getValue(model, '/metadata/resource/kind') + commit('wizard/model$update', { + path: '/spec/archiverName', + value: kind.toLowerCase(), + force: true, + }) + } } } -} - -function showArchiverAlert({ watchDependency, model, getValue, commit }) { - watchDependency('model#/spec/admin/storageClasses/default') - const mode = getValue(model, '/spec/mode') - if (mode === 'Standalone') return false + function showArchiverAlert() { + // watchDependency('model#/spec/admin/storageClasses/default') - const via = getValue(model, '/spec/admin/archiver/via') + const mode = getValue(model, '/spec/mode') + if (mode === 'Standalone') return false - if (via === 'VolumeSnapshotter') { - // toggle archiver to false when storageClass annotation not found - const stClass = getValue(model, '/spec/admin/storageClasses/default') - const found = archiverMap.find((item) => item.storageClass === stClass) - const show = !found?.annotation - if (show) { - commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, - force: true, - }) - return true - } else onArchiverChange({ model, getValue, commit }) - } else onArchiverChange({ model, getValue, commit }) - return false -} + const via = getValue(model, '/spec/admin/archiver/via') -function checkIfFeatureOn({ getValue, model }, type) { - let val = getValue(model, `/spec/admin/${type}/toggle`) - if (type === 'backup' || type === 'archiver') { - val = getValue(model, `/spec/admin/${type}/enable/toggle`) - } - const backupVal = getValue(model, '/spec/backup/tool') - - if (type === 'backup') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } else if (type === 'tls') { - return features.includes('tls') && val - } else if (type === 'expose') { - return features.includes('binding') && val - } else if (type === 'monitoring') { - return features.includes('monitoring') && val - } else if (type === 'archiver') { - return features.includes('backup') && val + if (via === 'VolumeSnapshotter') { + // toggle archiver to false when storageClass annotation not found + const stClass = getValue(model, '/spec/admin/storageClasses/default') + const found = archiverMap.find((item) => item.storageClass === stClass) + const show = !found?.annotation + if (show) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + return true + } else onArchiverChange() + } else onArchiverChange() + return false } -} -function isToggleOn({ getValue, model, discriminator, watchDependency, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') - watchDependency('model#/spec/admin/deployment/default') - const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') - let deploymentType = getValue(model, `/spec/admin/deployment/default`) - if (type === 'tls' || type === 'backup' || type === 'expose' || type === 'monitoring') { - return checkIfFeatureOn({ getValue, model }, type) - } else if ( - type === 'clusterTier' || - type === 'clusterTier/placement' || - type === 'clusterTier/nodeTopology' - ) { - if (deploymentType === 'Dedicated' && bundleApiLoaded) return true - else return false - } else if (type === 'deployment') { - const deploymentType = getValue(model, '/spec/admin/deployment/default') - if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { - commit('wizard/model$update', { - path: '/spec/admin/deployment/default', - value: 'Shared', - force: true, - }) + let backupToolInitialValue = '' + function checkIfFeatureOn(type) { + let val = getValue(model, `/spec/admin/${type}/toggle`) + if (type === 'backup' || type === 'archiver') { + val = getValue(model, `/spec/admin/${type}/enable/toggle`) } - return ( - getValue(model, `/spec/admin/${type}/toggle`) && - nodetopologiesDedicated.length && - bundleApiLoaded - ) - } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded -} + const backupVal = getValue(model, '/spec/backup/tool') + if (type === 'backup') { + if (backupToolInitialValue === '') { + backupToolInitialValue = + features.includes('backup') && backupVal === 'KubeStash' && val ? 'on' : 'off' + return features.includes('backup') && backupVal === 'KubeStash' && val + } else { + if (backupToolInitialValue === 'on') { + return true + } else { + return false + } + } + } else if (type === 'tls') { + return features.includes('tls') && val + } else if (type === 'expose') { + return features.includes('binding') && val + } else if (type === 'monitoring') { + return features.includes('monitoring') && val + } else if (type === 'archiver') { + return features.includes('backup') && val + } + } -async function getNodeTopology({ model, getValue, axios, storeGet, watchDependency }) { - watchDependency('model#/spec/admin/deployment/default') - watchDependency('model#/spec/admin/clusterTier/default') - const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' - const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' - let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + function isToggleOn(type) { + // watchDependency('discriminator#/bundleApiLoaded') + // watchDependency('model#/spec/admin/deployment/default') + const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') + let deploymentType = getValue(model, `/spec/admin/deployment/default`) + if (type === 'tls' || type === 'backup' || type === 'expose' || type === 'monitoring') { + return checkIfFeatureOn(type) + } else if ( + type === 'clusterTier' || + type === 'clusterTier/placement' || + type === 'clusterTier/nodeTopology' + ) { + if (deploymentType === 'Dedicated' && bundleApiLoaded) return true + else return false + } else if (type === 'deployment') { + const deploymentType = getValue(model, '/spec/admin/deployment/default') + if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + commit('wizard/model$update', { + path: '/spec/admin/deployment/default', + value: 'Shared', + force: true, + }) + } + return ( + getValue(model, `/spec/admin/${type}/toggle`) && + nodetopologiesDedicated.length && + bundleApiLoaded + ) + } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded + } - const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + async function getNodeTopology() { + // watchDependency('model#/spec/admin/deployment/default') + // watchDependency('model#/spec/admin/clusterTier/default') + const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' + const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' + let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] - if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared - else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' - const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) - return filteredList -} + if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared + else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated -function filterNodeTopology(list, tier, provider) { - // first filter the list from value that exists from the filtered list got from API - const filteredlist = list + const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) + return filteredList + } - // filter the list based on clusterTier - if (provider === 'EKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('c') - else if (tier === 'MemoryOptimized') return item.startsWith('r') - else return !item.startsWith('c') && !item.startsWith('r') - }) - } else if (provider === 'AKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - else - return ( - !(item.startsWith('f') || item.startsWith('fx')) && - !( + function filterNodeTopology(list, tier, provider) { + // first filter the list from value that exists from the filtered list got from API + const filteredlist = list + + // filter the list based on clusterTier + if (provider === 'EKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('c') + else if (tier === 'MemoryOptimized') return item.startsWith('r') + else return !item.startsWith('c') && !item.startsWith('r') + }) + } else if (provider === 'AKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('e') || item.startsWith('eb') || item.startsWith('ec') || item.startsWith('m') || item.startsWith('d') ) - ) - }) - } else if (provider === 'GKE') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') - return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - else - return ( - !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && - !( + else + return ( + !(item.startsWith('f') || item.startsWith('fx')) && + !( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + ) + }) + } else if (provider === 'GKE') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') + return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('x4') || item.startsWith('m1') || item.startsWith('m2') || item.startsWith('m3') ) - ) - }) - } else return filteredlist -} + else + return ( + !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && + !( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + ) + }) + } else return filteredlist + } -function returnFalse() { - return false -} + function returnFalse() { + return false + } -function showAlerts({ watchDependency, model, getValue, discriminator }) { - watchDependency('discriminator#/monitoring') - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const isAlertToggleEnabled = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'alert', - ) - return isMonitorEnabled && isAlertToggleEnabled -} + function showAlerts() { + // watchDependency('discriminator#/monitoring') + const isMonitorEnabled = getValue(discriminator, '/monitoring') + return isMonitorEnabled && isToggleOn('alert') + } -function showIssuer({ model, getValue, watchDependency, discriminator }) { - watchDependency('model#/spec/admin/tls/default') - const isTlsEnabled = getValue(model, '/spec/admin/tls/default') - const isIssuerToggleEnabled = isToggleOn( - { getValue, model, watchDependency, discriminator }, - 'clusterIssuers', - ) - return isTlsEnabled && isIssuerToggleEnabled -} + function showIssuer() { + // watchDependency('model#/spec/admin/tls/default') + const isTlsEnabled = getValue(model, '/spec/admin/tls/default') + const isIssuerToggleEnabled = isToggleOn('clusterIssuers') + return isTlsEnabled && isIssuerToggleEnabled + } -function onBackupSwitch({ discriminator, getValue, commit }) { - const isBackupOn = getValue(discriminator, '/backup') - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: isBackupOn ? 'KubeStash' : '', - force: true, - }) -} + function onBackupSwitch() { + const isBackupOn = getValue(discriminator, '/backup') + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: isBackupOn ? 'KubeStash' : '', + force: true, + }) + } -function setMonitoring({ getValue, model }) { - const agent = getValue(model, '/spec/admin/monitoring/agent') || '' - return !!agent -} + function setMonitoring() { + const agent = getValue(model, '/spec/admin/monitoring/agent') || '' + return !!agent + } -function setBackup({ model, getValue }) { - const backup = getValue(model, '/spec/backup/tool') - const val = getValue(model, '/spec/admin/backup/enable/default') - return backup === 'KubeStash' && features.includes('backup') && val -} + function setBackup() { + const backup = getValue(model, '/spec/backup/tool') + const val = getValue(model, '/spec/admin/backup/enable/default') + return backup === 'KubeStash' && features.includes('backup') && val + } -function onAuthChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/authSecret/password', - value: '', - force: true, - }) -} + function onAuthChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/spec/authSecret/password', + value: '', + force: true, + }) + } -function isConfigDatabaseOn({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configDatabase') - return getValue(discriminator, '/configDatabase') -} + function isConfigDatabaseOn() { + // watchDependency('discriminator#/configDatabase') + return getValue(discriminator, '/configDatabase') + } -function clearConfiguration({ discriminator, getValue, commit }) { - const configOn = getValue(discriminator, '/configDatabase') + function clearConfiguration() { + const configOn = getValue(discriminator, '/configDatabase') - if (!configOn) { - commit('wizard/model$delete', '/spec/configuration') + if (!configOn) { + commit('wizard/model$delete', '/spec/configuration') + } } -} -function showAdditionalSettings({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return features.length -} + function showAdditionalSettings() { + // watchDependency('discriminator#/bundleApiLoaded') + return features.length + } -function getDefault({ getValue, model }, type) { - const val = getValue(model, `/spec/admin/${type}/default`) || '' - return val -} + function getDefault(type) { + const val = getValue(model, `/spec/admin/${type}/default`) || '' + return val + } -function convertToLocal(input) { - const date = new Date(input) + function convertToLocal(input) { + const date = new Date(input) - if (isNaN(date.getTime())) { - return null + if (isNaN(date.getTime())) { + return null + } + + return date.toString() } - return date.toString() -} + function convertToUTC(localTime) { + const date = new Date(localTime) + if (isNaN(date.getTime())) return -function getComponentLogStats(snapshot) { - if (!snapshot || !snapshot.status || !snapshot.status.components) { - return null + const utcString = date.toISOString() + return utcString } - const components = snapshot.status.components - const appKind = snapshot.spec?.appRef?.kind + function onTimestampChange() { + const localTime = getValue(model, '/spec/init/archiver/recoveryTimestamp') + if (!localTime) return - if (appKind === 'MongoDB') { - for (const [key, value] of Object.entries(components)) { - if (key.endsWith('0') && value.logStats) { - return value.logStats - } + const utcString = convertToUTC(localTime) + + // Only update if the value is valid & not already in UTC format + if (utcString && localTime !== utcString) { + commit('wizard/model$update', { + path: '/spec/init/archiver/recoveryTimestamp', + value: utcString, + force: true, + }) } } - if (components['log'] && components['log'].logStats) { - return components['log'].logStats - } - return null -} + function getComponentLogStats(snapshot) { + if (!snapshot || !snapshot.status || !snapshot.status.components) { + return null + } -async function setPointInTimeRecovery({ commit, axios, storeGet, discriminator, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const refNamespace = getValue(discriminator, '/refNamespace') - const refDBName = getValue(discriminator, '/refDBName') + const components = snapshot.status.components + const appKind = snapshot.spec?.appRef?.kind - try { - const repositoriesUrl = `clusters/${owner}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${refNamespace}/repositories/${refDBName}-full` - const snapshotsUrl = `clusters/${owner}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${refNamespace}/snapshots/${refDBName}-incremental-snapshot` - const repositoriesResp = await axios.get(repositoriesUrl) - const snapshotsResp = await axios.get(snapshotsUrl) + if (appKind === 'MongoDB') { + for (const [key, value] of Object.entries(components)) { + if (key.endsWith('0') && value.logStats) { + return value.logStats + } + } + } + if (components['log'] && components['log'].logStats) { + return components['log'].logStats + } - commit('wizard/model$update', { - path: `/spec/init/archiver/encryptionSecret/name`, - value: repositoriesResp.data?.spec.encryptionSecret.name, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/encryptionSecret/namespace`, - value: repositoriesResp.data?.spec.encryptionSecret.namespace, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/fullDBRepository/name`, - value: `${refDBName}-full`, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/fullDBRepository/namespace`, - value: `${refNamespace}`, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/manifestRepository/name`, - value: `${refDBName}-manifest`, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/manifestRepository/namespace`, - value: `${refNamespace}`, - force: true, - }) + return null + } - const resp = getComponentLogStats(snapshotsResp.data) + async function setPointInTimeRecovery() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const refNamespace = getValue(discriminator, '/refNamespace') + const refDBName = getValue(discriminator, '/refDBName') - commit('wizard/model$update', { - path: `/spec/init/archiver/recoveryTimestamp`, - value: convertToLocal(resp?.end), - force: true, - }) - commit('wizard/model$update', { - path: `/minDate`, - value: convertToLocal(resp?.start), - force: true, - }) - commit('wizard/model$update', { - path: `/maxDate`, - value: convertToLocal(resp?.end), - force: true, - }) - } catch (e) { - commit('wizard/model$update', { - path: `/spec/init/archiver/recoveryTimestamp`, - value: '', - force: true, - }) - commit('wizard/model$update', { - path: `/minDate`, - value: '', - force: true, - }) - commit('wizard/model$update', { - path: `/maxDate`, - value: '', - force: true, - }) - console.log(e) - } -} + try { + const repositoriesUrl = `clusters/${owner}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${refNamespace}/repositories/${refDBName}-full` + const snapshotsUrl = `clusters/${owner}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${refNamespace}/snapshots/${refDBName}-incremental-snapshot` + const repositoriesResp = await axios.get(repositoriesUrl) + const snapshotsResp = await axios.get(snapshotsUrl) -function isConfigAvailable({ getValue, model }) { - const val = getValue(model, '/spec/configuration') - return val !== '' -} + commit('wizard/model$update', { + path: `/spec/init/archiver/encryptionSecret/name`, + value: repositoriesResp.data?.spec.encryptionSecret.name, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/encryptionSecret/namespace`, + value: repositoriesResp.data?.spec.encryptionSecret.namespace, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/fullDBRepository/name`, + value: `${refDBName}-full`, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/fullDBRepository/namespace`, + value: `${refNamespace}`, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/manifestRepository/name`, + value: `${refDBName}-manifest`, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/manifestRepository/namespace`, + value: `${refNamespace}`, + force: true, + }) -async function getReferSecrets({ getValue, model, storeGet, axios, discriminator }) { - const referSecret = getValue(discriminator, '/referSecret') - if (!referSecret) { - return [] + const resp = getComponentLogStats(snapshotsResp.data) + + commit('wizard/model$update', { + path: `/spec/init/archiver/recoveryTimestamp`, + value: convertToUTC(resp?.end), + force: true, + }) + commit('wizard/model$update', { + path: `/minDate`, + value: convertToUTC(resp?.start), + force: true, + }) + commit('wizard/model$update', { + path: `/maxDate`, + value: convertToUTC(resp?.end), + force: true, + }) + } catch (e) { + pointIntimeError = + e.response?.data?.message || 'Invalid name / namespace for recovery timestamp' + commit('wizard/model$update', { + path: `/spec/init/archiver/recoveryTimestamp`, + value: '', + force: true, + }) + commit('wizard/model$update', { + path: `/minDate`, + value: '', + force: true, + }) + commit('wizard/model$update', { + path: `/maxDate`, + value: '', + force: true, + }) + commit('wizard/model$delete', '/spec/init/archiver/encryptionSecret') + commit('wizard/model$delete', '/spec/init/archiver/fullDBRepository') + commit('wizard/model$delete', '/spec/init/archiver/manifestRepository') + console.log(e) + } } - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/metadata/release/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - - const options = [] - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) - } catch (e) { - console.log(e) + let pointIntimeError = '' + function pointInTimeErrorCheck() { + if (pointIntimeError.length) return pointIntimeError + return } - return options -} -function showAuthPasswordField({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + async function getReferSecrets() { + const referSecret = getValue(discriminator, '/referSecret') + if (!referSecret) { + return [] + } -function showSecretDropdown({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/metadata/release/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` -function showReferSecret({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/createAuthSecret') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue -} + const options = [] + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + return options + } -function getDefaultValue({ getValue, model }, path) { - const val = getValue(model, `/${path}`) || '' - return val -} + function showAuthPasswordField() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !modelPathValue && showReferSecret() + } -function showReferSecretSwitch({ model, getValue, watchDependency, discriminator }) { - const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showSecretDropdown() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !!modelPathValue && showReferSecret() + } -function onReferSecretChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) -} + function showReferSecret() { + const modelPathValue = getValue(discriminator, '/createAuthSecret') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue + } -async function getAppBindings({ commit, axios, storeGet, model, getValue }) { - const namespace = getValue(model, '/metadata/release/namespace') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function getDefaultValue(path) { + const val = getValue(model, `/${path}`) || '' + return val + } - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { type: null }, - }, - }, + function showReferSecretSwitch() { + const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue && showReferSecret() } - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/appcatalog.appscode.com/v1alpha1/appbindings`, - { - params: queryParams, - }, - ) - const resources = (resp && resp.data && resp.data.items) || [] + function onReferSecretChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + } - const fileredResources = resources - .filter((item) => item.spec?.type === 'kubedb.com/mysql') - .map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: `${namespace}/${name}`, - value: { name, namespace }, - } - }) - return fileredResources - } catch (e) { - console.log(e) - return [] + async function getAppBindings() { + const namespace = getValue(model, '/metadata/release/namespace') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + + const queryParams = { + filter: { + items: { + metadata: { name: null }, + spec: { type: null }, + }, + }, + } + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/appcatalog.appscode.com/v1alpha1/appbindings`, + { + params: queryParams, + }, + ) + + const resources = (resp && resp.data && resp.data.items) || [] + + const fileredResources = resources + .filter((item) => item.spec?.type === 'kubedb.com/mysql') + .map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: `${namespace}/${name}`, + value: { name, namespace }, + } + }) + return fileredResources + } catch (e) { + console.log(e) + return [] + } } -} -return { - showReferSecretSwitch, - onReferSecretChange, - getDefaultValue, - isRancherManaged, - showSecretDropdown, - showReferSecret, - getReferSecrets, - isConfigAvailable, - setPointInTimeRecovery, - getRecoveryNames, - fetchNamespaces, - showRecovery, - showAdditionalSettings, - initBundle, - returnFalse, - isVariantAvailable, - showAuthPasswordField, - isEqualToModelPathValue, - getNamespaces, - getMachineListForOptions, - setLimits, - setRequests, - setMachineToCustom, - isMachineNotCustom, - isMachineCustom, - updateAlertValue, - getCreateNameSpaceUrl, - ifCapiProviderIsNotEmpty, - ifDedicated, - dedicatedOnChange, - ifZones, - zonesOnChange, - getZones, - getSKU, - showMultiselectZone, - showSelectZone, - setStorageClass, - getNodeTopology, - filterNodeTopology, - getAdminOptions, - isToggleOn, - showAlerts, - showIssuer, - onBackupSwitch, - setMonitoring, - onAuthChange, - isConfigDatabaseOn, - clearConfiguration, - setBackup, - getDefault, - onArchiverChange, - showArchiverAlert, - showArchiver, - getAppBindings, + return { + showReferSecretSwitch, + onReferSecretChange, + getDefaultValue, + isRancherManaged, + showSecretDropdown, + showReferSecret, + getReferSecrets, + setPointInTimeRecovery, + pointInTimeErrorCheck, + getRecoveryNames, + fetchNamespaces, + showRecovery, + showAdditionalSettings, + initBundle, + returnFalse, + isVariantAvailable, + showAuthPasswordField, + isEqualToModelPathValue, + getNamespaces, + getMachineListForOptions, + setLimits, + setRequests, + setMachineToCustom, + isMachineNotCustom, + isMachineCustom, + updateAlertValue, + getCreateNameSpaceUrl, + ifCapiProviderIsNotEmpty, + ifDedicated, + dedicatedOnChange, + ifZones, + zonesOnChange, + getZones, + getSKU, + showMultiselectZone, + showSelectZone, + setStorageClass, + getNodeTopology, + filterNodeTopology, + getAdminOptions, + isToggleOn, + showAlerts, + showIssuer, + onBackupSwitch, + setMonitoring, + onAuthChange, + isConfigDatabaseOn, + clearConfiguration, + setBackup, + getDefault, + onArchiverChange, + showArchiverAlert, + showArchiver, + getAppBindings, + onTimestampChange, + } } diff --git a/charts/kubedbcom-mysql-editor/ui/edit-ui.yaml b/charts/kubedbcom-mysql-editor/ui/edit-ui.yaml index 88601293dc..7ded163508 100644 --- a/charts/kubedbcom-mysql-editor/ui/edit-ui.yaml +++ b/charts/kubedbcom-mysql-editor/ui/edit-ui.yaml @@ -1,1337 +1,735 @@ -steps: -- form: - elements: - - disabled: true - label: - text: labels.database.name - onChange: onNameChange - schema: - $ref: schema#/properties/metadata/properties/release/properties/name - type: input - - disabled: true - fetch: getResources|core|v1|namespaces - label: - text: labels.namespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/metadata/properties/release/properties/namespace - type: select - - disableUnselect: true - disabled: 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 - 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 - - disabled: true - label: - text: labels.secret - schema: - $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/authSecret/properties/name - type: input - type: single-step-form - id: basic - title: steps.0.label -- form: - elements: - - alias: reusable_alert - chart: - name: uibytebuildersdev-component-alert - version: v0.29.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 +type: multi-step-form +step: + - type: single-step-form + id: backupconfiguration + # label: Backup + schema: schema/ elements: - - if: isNotEqualToDatabaseMode|Standalone - label: - text: labels.to_update_disabled_section - type: label-element - - customClass: mb-20 - if: isNotEqualToDatabaseMode|Standalone - label: - text: labels.create_opsrequest - type: anchor - url: - params: - cluster: - $ref: store#/route/params/cluster - dbname: - $ref: model#/metadata/release/name - domain: - $ref: store#/domain - group: - $ref: model#/metadata/resource/group - kind: - $ref: model#/metadata/resource/kind - namespace: - $ref: model#/metadata/release/namespace - owner: - $ref: store#/route/params/user - resource: - $ref: model#/metadata/resource/name - version: - $ref: model#/metadata/resource/version - path: ${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 - - computed: setDatabaseMode - disabled: true - hasDescription: true - label: - text: labels.database.mode - onChange: deleteDatabaseModePath + - type: radio + label: Schedule a Backup? + schema: temp/properties/scheduleBackup + isHorizontal: true 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 - - disabled: true - if: isNotEqualToDatabaseMode|Standalone - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/replicas - type: input - - disabled: true - 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 - - disabled: true - 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: - - label: - text: labels.to_update_tls - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - params: - cluster: - $ref: store#/route/params/cluster - dbname: - $ref: model#/metadata/release/name - domain: - $ref: store#/domain - group: - $ref: model#/metadata/resource/group - kind: - $ref: model#/metadata/resource/kind - namespace: - $ref: model#/metadata/release/namespace - owner: - $ref: store#/route/params/user - resource: - $ref: model#/metadata/resource/name - version: - $ref: model#/metadata/resource/version - path: ${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=ReconfigureTLS - - computed: isValueExistInModel|/resources/kubedbComMySQL/spec/tls - disabled: true - label: - text: labels.enable_tls - onChange: onTlsConfigureChange - schema: - $ref: discriminator#/configureTLS - type: switch - - disabled: true + - text: 'Yes' + value: 'yes' + - text: 'No' + value: 'no' + if: + type: function + name: showScheduleBackup + init: + type: func + value: initScheduleBackupForEdit + watcher: + func: onScheduleBackupChange + paths: + - temp/properties/scheduleBackup + - type: block-layout + label: Backup Form + showLabels: false + loader: initBackupData + if: + type: function + name: showBackupForm 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 + - type: radio + label: Select Backup Type + schema: temp/properties/backupType + isHorizontal: true 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.29.0 - 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: + - text: BackupConfig + value: BackupConfig + description: 'Create, Delete or Modify BackupConfig' + - text: BackupBlueprint + value: BackupBlueprint + description: Enable/Disable BackupBlueprint + if: + type: function + name: isBackupDataLoadedTrue + init: + type: func + value: setBackupType + loader: getTypes + watcher: + func: onBackupTypeChange + paths: + - temp/properties/backupType + - type: block-layout + label: Config + if: + type: function + name: isBackupType|BackupConfig + elements: + - type: select + label: Select Context + schema: temp/properties/backupConfigContext + validation: + type: required + loader: getContext + watcher: + func: onContextChange + paths: + - temp/properties/backupConfigContext + - type: select + label: Select BackupConfig + schema: temp/properties/config + validation: + type: required + if: + type: function + name: showConfigList + loader: getConfigList + watcher: + func: onConfigChange + paths: + - temp/properties/config + - type: input + label: Schedule + schema: temp/properties/schedule + validation: + type: required + if: + type: function + name: showSchedule + loader: + name: getDefaultSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions + watchPaths: + - temp/properties/config + watcher: + func: onInputChangeSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions|schedule + paths: + - temp/properties/schedule + - type: switch + label: Paused + fullwidth: true + schema: schema/properties/resources/properties/coreKubestashComBackupConfiguration/properties/spec/properties/paused + if: + type: function + name: showPause + watcher: + func: setPausedValue + paths: + - temp/properties/config + init: + type: func + value: setPausedValue + - type: block-layout + label: Blueprint + if: + type: function + name: isBackupType|BackupBlueprint + elements: + - type: switch + label: Enable Backup Blueprint + fullwidth: true + schema: temp/properties/blueprintEnabled + init: + type: func + value: setBlueprintSwitch + watcher: + func: onBlueprintChange + paths: + - temp/properties/blueprintEnabled + - type: block-layout + label: Archiver + if: + type: function + name: isBackupType|Archiver + elements: + - type: switch + label: Enable Archiver + fullwidth: true + schema: temp/properties/archiverEnabled + init: + type: func + value: setArchiverSwitch + watcher: + func: onArchiverChange + paths: + - temp/properties/archiverEnabled + + - type: single-step-form + id: compute-autoscaler + loader: getMysqlDbs elements: - - disabled: disableInitializationSection - discriminator: - prePopulateDatabase: - type: string - elements: - - computed: initPrePopulateDatabase - label: - text: labels.prePopulateDatabase - onChange: onPrePopulateDatabaseChange + - type: block-layout + if: + type: function + name: isConsole + elements: + - type: input + label: Name + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/metadata/properties/name + - type: select + label: Select Namespace + loader: getNamespaces + if: + type: function + name: isRancherManaged + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/metadata/properties/namespace + - type: select + label: Select Db + loader: getMysqlDbs + validation: + type: required + refresh: true + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/databaseRef/properties/name + watcher: + func: initMetadata + paths: + - schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/databaseRef/properties/name + + - type: radio + if: + type: function + name: isConsole + label: Select Type + validation: + type: required + schema: temp/properties/autoscalingType + watcher: + func: initMetadata + paths: + - temp/properties/autoscalingType 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 + - text: Compute + value: compute + description: Scale your CPU Memory based on resource usage + - text: Storage + value: storage + description: Expand your database size based on volume usage + + - type: block-layout + showLabels: false + loader: fetchTopologyMachines 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 + # mysql mode + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComMySQLAutoscaler/spec/compute/mysql/trigger + schema: temp/properties/compute/properties/mysql/properties/trigger + watcher: + func: onTriggerChange|compute/mysql + paths: + - temp/properties/compute/properties/mysql/properties/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/podLifeTimeThreshold + customClass: width-300 + - type: block-layout + label: Mysql + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql 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.29.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 + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|mysql|min + loader: + name: getMachines|mysql|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-max + watcher: + func: onMachineChange|mysql + paths: + - temp/properties/allowedMachine-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + 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: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|mysql|max + loader: + name: getMachines|mysql|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-min + watcher: + func: onMachineChange|mysql + paths: + - temp/properties/allowedMachine-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + 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: select + 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: block-layout + label: In Memory Storage + showLabels: true + if: + type: function + name: showStorageMemoryOption + # schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/inMemoryStorage + elements: + - type: threshold-input + 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: block-layout + label: Node Topology + if: + type: function + name: hasNoAnnotations + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/nodeTopology 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.29.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 - type: single-step-form - id: initialization - title: steps.3.label -- form: - discriminator: - repoInitialSelectionStatus: - type: string - scheduleBackup: - default: "yes" - type: string - elements: - - computed: initScheduleBackupForEdit - if: showScheduleBackup - 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: - backupType: - type: string - isBackupDataLoaded: - default: false - type: boolean - elements: - - computed: initBackupData - if: returnFalse - type: input - - computed: setBackupType - fetch: getTypes - hasDescription: true - if: isBackupDataLoadedTrue - label: - text: Select Backup Type - onChange: onBackupTypeChange - schema: - $ref: discriminator#/backupType - type: radio - - discriminator: - backupConfigContext: - type: string - config: - type: string - paused: - default: false - type: boolean - schedule: - type: string - elements: - - fetch: getContext - label: - text: Select Context - onChange: onContextChange - required: true - schema: - $ref: discriminator#/backupConfigContext - type: select - - fetch: getConfigList - if: showConfigList - label: - text: Select BackupConfig - onChange: onConfigChange - required: true - schema: - $ref: discriminator#/config - type: select - - computed: getDefaultSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions - if: showSchedule - label: - text: Schedule - onChange: onInputChangeSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions|schedule - required: true - schema: - $ref: discriminator#/schedule - type: input - - if: showPause - label: - text: Paused - schema: - $ref: schema#/properties/resources/properties/coreKubestashComBackupConfiguration/properties/spec/properties/paused - type: switch - if: isBackupType|BackupConfig - type: single-step-form - - discriminator: - blueprintEnabled: - default: false - type: boolean - elements: - - computed: setBlueprintSwitch - label: - text: Enable Backup Blueprint - onChange: onBlueprintChange - schema: - $ref: discriminator#/blueprintEnabled - type: switch - if: isBackupType|BackupBlueprint - type: single-step-form - - discriminator: - archiverEnabled: - default: false - type: boolean - elements: - - computed: setArchiverSwitch - label: - text: Enable Archiver - onChange: onArchiverChange - schema: - $ref: discriminator#/archiverEnabled - type: switch - if: isBackupType|Archiver - 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 + - type: select + label: Select NodeTopology + loader: fetchNodeTopology + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name + - type: threshold-input + label: ScaleUp Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage + - type: threshold-input + label: ScaleDown Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage + + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + # schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/opsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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: single-step-form + id: storage-autoscaler elements: - - label: - text: labels.to_update_exporter_resources - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - function: getOpsRequestUrl|VerticalScaling - - computed: isValueExistInModel|/resources/kubedbComMySQL/spec/monitor - label: - text: labels.enable_monitoring - onChange: onEnableMonitoringChange - schema: - $ref: discriminator#/enableMonitoring - type: switch - - discriminator: - customizeExporter: - default: true - type: boolean + - type: block-layout + showLabels: false 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: - - if: returnFalse - 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.29.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: - - elements: - - alias: pod_template_standalone - chart: - name: uibytebuildersdev-component-pod-template - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - functionCallbacks: - isEditWizard: - $ref: functions#/returnTrue - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComMySQL/properties/spec/properties/podTemplate - type: reusable-element - type: single-step-form - 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.29.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: - - elements: - - discriminator: - configurationSource: - default: use-existing-config - type: string - elements: - - label: - text: labels.to_update_config - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - params: - cluster: - $ref: store#/route/params/cluster - dbname: - $ref: model#/metadata/release/name - domain: - $ref: store#/domain - group: - $ref: model#/metadata/resource/group - kind: - $ref: model#/metadata/resource/kind - namespace: - $ref: model#/metadata/release/namespace - owner: - $ref: store#/route/params/user - resource: - $ref: model#/metadata/resource/name - version: - $ref: model#/metadata/resource/version - path: ${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=Reconfigure - - disabled: true - label: - text: labels.custom_config - onChange: onConfigurationSourceChange + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComMySQLAutoscaler/spec/storage/mysql/trigger + schema: temp/properties/storage/properties/mysql/properties/trigger + watcher: + func: onTriggerChange|storage/mysql + paths: + - temp/properties/storage/properties/mysql/properties/trigger + - type: label-element + 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: select + label: Mode + description: Select how the storage expansion should be handled. 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 - disabled: 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 - type: single-step-form - type: single-step-form - type: single-step-form - id: custom-config - title: steps.8.label -- form: + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/storage/properties/mysql/properties/expansionMode + - type: block-layout + label: Mysql + showLabels: true + elements: + - type: threshold-input + label: UsageThreshold (%) + subtitle: Set the threshold percentage of storage usage to trigger scaling. + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/storage/properties/mysql/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/storage/properties/mysql/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComMySQL/spec/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComMySQLAutoscaler/spec/storage/mysql/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/storage/properties/mysql/properties/scalingRules + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/storage/properties/mysql/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComMySQLAutoscaler/spec/storage/mysql/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/storage/properties/mysql/properties/upperBound + - type: block-layout + label: OpsRequest Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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: single-step-form + id: monitoring + loader: initMonitoring elements: - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: Select Namespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getMysqlDbs - label: - text: Select Db - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: Select Type - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - discriminator: - topologyMachines: - default: [] - type: array + - type: label-element + label: To update Exporter Resource section click on Create OpsRequest + - type: anchor + label: Create OpsRequest + schema: temp/properties/opsRequestUrl + init: + type: func + value: getOpsRequestUrl|scale-vertically + - type: switch + label: Enable Monitoring + fullwidth: true + schema: temp/properties/enableMonitoring + init: + type: func + value: isValueExistInModel|/resources/kubedbComMySQL/spec/monitor + watcher: + func: onEnableMonitoringChange + paths: + - temp/properties/enableMonitoring + - type: block-layout + if: + type: function + name: showMonitoringSection elements: - - fetch: fetchTopologyMachines - if: returnFalse - schema: - $ref: discriminator#/topologyMachines - type: input - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComMySQLAutoscaler/spec/compute/mysql/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-max: - type: string - allowedMachine-min: - type: string - elements: - - computed: setAllowedMachine|min - disableUnselect: true - fetch: getMachines|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|mysql - schema: - $ref: discriminator#/properties/allowedMachine-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|max - disableUnselect: true - fetch: getMachines|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|mysql - schema: - $ref: discriminator#/properties/allowedMachine-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|mysql - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/controlledResources - type: multiselect - - elements: - - label: - text: Scaling Factor Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/inMemoryStorage/properties/scalingFactorPercentage - type: input - - label: - text: Usage Threshold Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/inMemoryStorage/properties/usageThresholdPercentage - type: input - label: - text: In Memory Storage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/inMemoryStorage - show_label: true - type: single-step-form - - label: - text: containerControlledValues - options: - - RequestsAndLimits - - RequestsOnly - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql/properties/containerControlledValues - type: select - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql - type: single-step-form - label: - text: Mysql - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/mysql - show_label: true - type: single-step-form - - elements: - - fetch: fetchNodeTopology - label: - text: Select NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name - type: select - - if: isNodeTopologySelected - label: - text: scaleUp Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage - type: input - - if: isNodeTopologySelected - label: - text: scaleDown Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage - type: input - if: hasNoAnnotations - label: - text: NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/compute/properties/nodeTopology - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: compute-autoscaler - title: steps.9.label -- form: - elements: - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: Select Namespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getMysqlDbs - label: - text: Select Db - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: Select Type - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComMySQLAutoscaler/spec/storage/mysql/trigger - label: - text: Trigger + - type: radio + label: Select a Monitoring Method + schema: schema/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/agent + isHorizontal: true options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/storage/properties/mysql/properties/trigger - type: select - - label: - text: Expansion Mode - options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/storage/properties/mysql/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/storage/properties/mysql/properties/usageThreshold - type: input - - addFormLabel: Scaling Rules - element: + - text: Prometheus Operator + value: prometheus.io/operator + description: Inject metric exporter sidecar and creates a ServiceMonitor + - text: Custom ServiceMonitor + value: prometheus.io + description: Injects the metric exporter sidecar and let you customize ServiceMonitor + - text: Custom Scrapper + value: prometheus.io/builtin + description: Inject metric exporter sidecar and add Prometheus annotations to the stats Service + init: + type: static + value: prometheus.io/operator + watcher: + func: onAgentChange + paths: + - schema/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/agent + - type: block-layout + label: ServiceMonitor Configuration + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComMySQL/spec/monitor/agent + elements: + - label: Scrapping Interval + schema: schema/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval + type: input + - type: block-layout + label: Service Monitor + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComMySQL/spec/monitor/agent + elements: + - type: array-object-form + label: Endpoints + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/endpoints + buttonClass: is-light is-outlined elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/storage/properties/mysql/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/storage/properties/mysql/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComMySQLAutoscaler/spec/storage/mysql/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/storage/properties/mysql/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComMySQLAutoscaler/spec/storage/mysql/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/storage/properties/mysql/properties/upperBound - type: input - - label: - text: Scaling Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/storage/properties/mysql/properties/scalingThreshold - type: input - label: - text: Mysql - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/storage/properties/mysql - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComMySQLAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: storage-autoscaler - title: steps.10.label -- form: - discriminator: - binding: - default: false - type: boolean + - type: switch + label: Honor labels + fullwidth: true + schema: honorLabels + - type: input + label: Interval + schema: interval + validation: + type: required + - type: input + label: Path + schema: path + validation: + type: required + - type: input + label: Port + schema: port + validation: + type: required + - type: select + multiple: true + label: Match Namespaces + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/namespaceSelector/properties/matchNames + loader: getResources|core|v1|namespaces + if: + type: function + name: returnFalse + - type: block-layout + showLabels: false + # schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector + if: + type: function + name: returnFalse + elements: + - type: object-item + label: Labels + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector/properties/matchLabels + - type: object-item + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/metadata/properties/labels + label : Labels + buttonClass: is-light is-outlined + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComMySQL/spec/monitor/agent + # individualItemDisabilityCheck: disableLableChecker + - type: label-element + label: Exporter Configuration + schema: '' + - type: switch + label: Customize Exporter Sidecar + fullwidth: true + schema: temp/properties/customizeExporter + init: + type: static + value: true + watcher: + func: onCustomizeExporterChange + paths: + - temp/properties/customizeExporter + - type: block-layout + label: Customer Exporter Section + showLabels: false + if: + type: function + name: showCustomizeExporterSection + elements: + - type: machine-compare + label: Resources + schema: schema/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/resources + if: + type: function + name: returnFalse + - type: label-element + label: Security Context + schema: '' + - type: input + schema: schema/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsUser + label: Run as User + - type: input + schema: schema/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup + label: Run as Group + - type: input + schema: schema/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/port + label: Port + - type: array-item-form + label: Args + schema: schema/properties/resources/properties/kubedbComMySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args + buttonClass: is-light is-outlined + init: + type: static + value: ['--compatible-mode'] + element: + type: input + label: Args + # isSubsection: true + - type: block-layout + label: Metadata + showLabels: false + elements: + - type: array-object-form + init: + type: func + value: initEnvArray + label: Environment Variables + buttonClass: is-light is-outlined + watcher: + func: onEnvArrayChange + paths: + - temp/properties/env + schema: temp/properties/env + elements: + - type: input + label: Name + schema: name + validation: + type: required + - type: radio + label: Value From + schema: temp/properties/valueFromType + validation: + type: required + init: + type: func + value: setValueFrom + options: + - text: Input + value: input + - text: Secret + value: secret + - text: ConfigMap + value: configMap + watcher: + func: onValueFromChange + paths: + - temp/properties/valueFromType + - type: input + label: Value + schema: value + validation: + type: required + if: + name: isEqualToTemp|input + type: function + - type: select + if: + type: function + name: isEqualToTemp|configMap + label: ConfigMap Name + schema: valueFrom/properties/configMapKeyRef/properties/name + loader: + name: resourceNames|core|v1|configmaps + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: ConfigMap Key + schema: valueFrom/properties/configMapKeyRef/properties/key + if: + type: function + name: isEqualToTemp|configMap + loader: + name: getConfigMapKeys + watchPaths: + - schema/resources/kubedbComMySQL/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/configMapKeyRef/name + - schema/metadata/release/namespace + - type: select + label: Secret Name + schema: valueFrom/properties/secretKeyRef/properties/name + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecrets + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: Secret Key + schema: valueFrom/properties/secretKeyRef/properties/key + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecretKeys + watchPaths: + - schema/resources/kubedbComMySQL/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/secretKeyRef/name + - schema/metadata/release/namespace + + + - type: single-step-form + id: binding elements: - - computed: isBindingAlreadyOn - label: - text: Expose Database - onChange: addOrRemoveBinding - schema: - $ref: discriminator#/properties/binding - type: switch - type: single-step-form - id: binding - title: Gateway Binding -type: multi-step-form + - type: switch + label: Expose Database + schema: temp/properties/binding + fullwidth: true + init: + type: func + value: isBindingAlreadyOn + watcher: + func: addOrRemoveBinding + paths: + - temp/properties/binding \ No newline at end of file diff --git a/charts/kubedbcom-mysql-editor/ui/functions.js b/charts/kubedbcom-mysql-editor/ui/functions.js index 4e9488a134..ec977e6b73 100644 --- a/charts/kubedbcom-mysql-editor/ui/functions.js +++ b/charts/kubedbcom-mysql-editor/ui/functions.js @@ -1,1775 +1,1206 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + // ************************* common functions ******************************************** // eslint-disable-next-line no-empty-pattern -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, - } -} +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) -function disableLableChecker({ itemCtx }) { - const { key } = itemCtx - if (key.startsWith('app.kubernetes.io') || key.includes('helm')) return true - else return false -} + /********** 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, + ) -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} + initRepositoryChoiseForEdit() -async function getResources({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' + else return 'no' + } - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, + function initScheduleBackup() { + const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( + getValue, + model, ) - 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 [] + if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' + else return 'no' } -} - -function isEqualToDiscriminatorPath( - { discriminator, getValue, watchDependency }, - value, - discriminatorPath, -) { - watchDependency('discriminator#' + discriminatorPath) - const discriminatorValue = getValue(discriminator, discriminatorPath) - return discriminatorValue === value -} -function setValueFromModel({ getValue, model }, path) { - return getValue(model, path) -} + function onScheduleBackupChange() { + const scheduleBackup = getValue(discriminator, '/scheduleBackup') -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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) - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + // create stashAppscodeComBackupConfiguration and initialize it if not exists - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }) + const dbName = getValue(model, '/metadata/release/name') - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + 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, + }) + } + } } - return ans -} - -async function getResourceList(axios, storeGet, { 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) + function valueExists(value, getValue, path) { + const val = getValue(value, path) + if (val) return true + else return false } - return ans -} + function getBackupConfigsAndAnnotations(getValue, model) { + const stashAppscodeComBackupConfiguration = getValue( + model, + '/resources/stashAppscodeComBackupConfiguration', + ) + const kubedbComMySQLAnnotations = + getValue(model, '/resources/kubedbComMySQL/metadata/annotations') || {} -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - 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) - }) - } + 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 resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' return { - text: name, - value: name, + stashAppscodeComBackupConfiguration, + isBluePrint, } - }) -} + } -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) - - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) + 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, }) } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} - -function returnTrue() { - return true -} - -function returnStringYes() { - return 'yes' -} -function setAddressType({ model, getValue }) { - const value = getValue(model, '/resources/kubedbComMySQL/spec/useAddressType') - - if (!value) { - return 'DNS' + // backup form + function showBackupForm() { + const scheduleBackup = getValue(discriminator, '/scheduleBackup') + // watchDependency('discriminator#/scheduleBackup') + if (scheduleBackup === 'yes') return true + else return false } - return value -} + 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 -// ************************* Basic Info ********************************************** -async function getMySqlVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + // 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 - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, - }, - }, - } + let url = `/clusters/${user}/${cluster}/helm/packageview/values?name=${chartName}&sourceApiGroup=${sourceApiGroup}&sourceKind=${sourceKind}&sourceNamespace=${sourceNamespace}&sourceName=${sourceName}&version=${chartVersion}&format=json` - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) + if (spoke) + url = `/clusters/${user}/${spoke}/helm/packageview/values?name=${chartName}&sourceApiGroup=${sourceApiGroup}&sourceKind=${sourceKind}&sourceNamespace=${sourceNamespace}&sourceName=${sourceName}&version=${chartVersion}&format=json` - const resources = (resp && resp.data && resp.data.items) || [] + const resp = await axios.get(url) - // keep only non deprecated versions - const filteredMongoDbVersions = resources.filter((item) => item.spec && !item.spec.deprecated) + valuesFromWizard = objectCopy(resp.data?.resources?.coreKubestashComBackupConfiguration) || {} + } catch (e) { + console.log(e) + } - filteredMongoDbVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredMongoDbVersions - } catch (e) { - console.log(e) - return [] - } -} + // 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) + } + } -// ********************* Database Mode *********************** -function setDatabaseMode({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/resources/kubedbComMySQL/spec/topology') - watchDependency('model#/resources/kubedbComMySQL/spec/topology') + // 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, + ) - if (modelPathValue?.mode) { - return modelPathValue.mode - } else { - return 'Standalone' - } -} + // 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, + ) -let storageClassList = [] -async function getStorageClassNames({ axios, storeGet, commit, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + // set backup switch here + isBackupOn = !!config - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/storage.k8s.io/v1/storageclasses`, - { - params: { - filter: { items: { metadata: { name: null, annotations: null } } }, - }, - }, - ) + // set initial data from stash-presets + const stashPreset = storeGet('/backup/stashPresets') + if (stashPreset) { + const { retentionPolicy, encryptionSecret, schedule, storageRef } = stashPreset - const resources = (resp && resp.data && resp.data.items) || [] + const tempBackends = valuesFromWizard.spec?.backends + tempBackends[0]['storageRef'] = storageRef + tempBackends[0]['retentionPolicy'] = retentionPolicy + valuesFromWizard.spec['backends'] = tempBackends - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) + 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}` - storageClassList = resources - const initialStorageClass = getValue( - model, - '/resources/kubedbComMySQL/spec/storage/storageClassName', - ) - if (!initialStorageClass) setStorageClass({ model, getValue, commit }) - return resources -} + tempSessions[0]['repositories'] = tempRepositories + tempSessions[0]['scheduler']['schedule'] = schedule + valuesFromWizard.spec['sessions'] = tempSessions + } -function setStorageClass({ model, getValue, commit }) { - const deletionPolicy = getValue(model, '/resources/kubedbComMySQL/spec/deletionPolicy') || '' - let storageClass = - getValue(model, '/resources/kubedbComMySQL/spec/storage/storageClassName') || '' - const suffix = '-retain' + 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, + } - const simpleClassList = storageClassList.filter((item) => { - return !item.metadata?.name?.endsWith(suffix) - }) + setDiscriminatorValue('isBackupDataLoaded', true) + } - const retainClassList = storageClassList.filter((item) => { - return item.metadata?.name?.endsWith(suffix) - }) + function isBackupDataLoadedTrue() { + // watchDependency('discriminator#/isBackupDataLoaded') + return !!getValue(discriminator, '/isBackupDataLoaded') + } - const defaultSimpleList = simpleClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] - ) - }) + function setBackupType() { + return 'BackupConfig' + } - const defaultRetainList = retainClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] - ) - }) - - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - if (simpleClassList.length > 1) { - const found = defaultSimpleList.length ? defaultSimpleList[0] : simpleClassList[0] - storageClass = found.value - } else if (simpleClassList.length === 1) { - storageClass = simpleClassList[0]?.value - } else { - const found = defaultRetainList.length - ? defaultRetainList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found - } - } else { - if (retainClassList.length > 1) { - const found = defaultRetainList.length ? defaultRetainList[0] : retainClassList[0] - storageClass = found.value - } else if (retainClassList.length === 1) { - storageClass = retainClassList[0]?.value - } else { - const found = defaultSimpleList.length - ? defaultSimpleList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found + 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 } - if (storageClass) { + function onBackupTypeChange() { + const type = getValue(discriminator, '/backupType') commit('wizard/model$update', { - path: '/resources/kubedbComMySQL/spec/storage/storageClassName', - value: storageClass, + path: '/backupType', + value: type, force: true, }) - } -} - -function deleteDatabaseModePath({ discriminator, getValue, commit, model }) { - const mode = getValue(discriminator, '/activeDatabaseMode') - if (mode === 'GroupReplication' || mode === 'InnoDBCluster') { - replicas = getValue(model, '/resources/kubedbComMySQL/spec/replicas') - if (!replicas) { + if (!isBackupOnModel) { + commit('wizard/model$delete', '/resources/coreKubestashComBackupConfiguration') + } else { commit('wizard/model$update', { - path: '/resources/kubedbComMySQL/spec/replicas', - value: 3, + path: '/resources/coreKubestashComBackupConfiguration', + value: objectCopy(initialModel), force: true, }) } + commit('wizard/model$delete', '/context') commit('wizard/model$update', { - path: '/resources/kubedbComMySQL/spec/topology/mode', - value: mode, - force: true, - }) - if (mode === 'GroupReplication') - commit('wizard/model$delete', '/resources/kubedbComMySQL/spec/topology/innoDBCluster') - else commit('wizard/model$delete', '/resources/kubedbComMySQL/spec/topology/group') - } else if (mode === 'Standalone') { - commit('wizard/model$update', { - path: '/resources/kubedbComMySQL/spec/replicas', - value: 1, + path: '/resources/kubedbComMySQL', + value: objectCopy(dbResource), force: true, }) - commit('wizard/model$delete', '/resources/kubedbComMySQL/spec/topology') } -} -function isEqualToDatabaseMode({ getValue, watchDependency, discriminator }, value) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - return mode === value -} + function isBackupType(type) { + // watchDependency('discriminator#/backupType') + const selectedType = getValue(discriminator, '/backupType') -function isNotEqualToDatabaseMode({ getValue, watchDependency, discriminator }, value) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - return mode !== value -} + return selectedType === type + } -// ************************** TLS ******************************88 + function setBlueprintSwitch() { + const annotations = initialDbMetadata?.annotations -function setApiGroup() { - return 'cert-manager.io' -} + return !!( + annotations['blueprint.kubestash.com/name'] && + annotations['blueprint.kubestash.com/namespace'] + ) + } -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - watchDependency('model#/resources/kubedbComMySQL/spec/tls/issuerRef/apiGroup') - watchDependency('model#/resources/kubedbComMySQL/spec/tls/issuerRef/kind') - watchDependency('model#/metadata/release/namespace') - const apiGroup = getValue(model, '/resources/kubedbComMySQL/spec/tls/issuerRef/apiGroup') - const kind = getValue(model, '/resources/kubedbComMySQL/spec/tls/issuerRef/kind') - const namespace = getValue(model, '/metadata/release/namespace') + function onBlueprintChange() { + const blueprintSwitch = getValue(discriminator, '/blueprintEnabled') + if (blueprintSwitch) addLabelAnnotation('annotations') + else deleteLabelAnnotation('annotations') + } - let url - if (kind === 'Issuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/namespaces/${namespace}/issuers` - } else if (kind === 'ClusterIssuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/clusterissuers` + function setArchiverSwitch() { + const archiver = dbResource?.spec?.archiver + return !!archiver } - if (!url) return [] + 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) + } + } - try { - const resp = await axios.get(url) + function addLabelAnnotation(type) { + const obj = objectCopy(initialDbMetadata[type]) - const resources = (resp && resp.data && resp.data.items) || [] + 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' + } - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + commit('wizard/model$update', { + path: `/resources/kubedbComMySQL/metadata/${type}`, + value: obj, + force: true, }) - return resources - } catch (e) { - console.log(e) - return [] } -} - -async function hasIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await getIssuerRefsName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !!(resp && resp.length) -} - -async function hasNoIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await hasIssuerRefName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !resp -} -function setSSLMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComMySQL/spec/sslMode') - return val || 'require' -} + function deleteLabelAnnotation(type) { + const obj = initialDbMetadata[type] -function showTlsConfigureSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configureTLS') - const configureStatus = getValue(discriminator, '/configureTLS') - return configureStatus -} + if (type === 'annotations') { + delete obj['blueprint.kubestash.com/name'] + delete obj['blueprint.kubestash.com/namespace'] + } else delete obj['kubedb.com/archiver'] -function onTlsConfigureChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/configureTLS') - if (configureStatus) { commit('wizard/model$update', { - path: '/resources/kubedbComMySQL/spec/tls', - value: { issuerRef: {}, certificates: [] }, + path: `/resources/kubedbComMySQL/metadata/${type}`, + value: obj, force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComMySQL/spec/tls') - commit('wizard/model$delete', '/resources/kubedbComMySQL/spec/sslMode') } -} -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} - -/****** Monitoring *********/ - -function showMonitoringSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/enableMonitoring') - const configureStatus = getValue(discriminator, '/enableMonitoring') - return configureStatus -} + function getContext() { + if (isBackupOn) return ['Create', 'Delete', 'Modify'] + return ['Create'] + } -function onEnableMonitoringChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/enableMonitoring') - if (configureStatus) { + function onContextChange() { + const context = getValue(discriminator, '/backupConfigContext') commit('wizard/model$update', { - path: '/resources/kubedbComMySQL/spec/monitor', - value: {}, + path: '/context', + value: context, force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComMySQL/spec/monitor') + if (context === 'Create') { + commit('wizard/model$update', { + path: '/resources/coreKubestashComBackupConfiguration', + value: valuesFromWizard, + force: true, + }) + } + if (context === 'Delete') setDiscriminatorValue('hidePreviewFromWizard', true) + else setDiscriminatorValue('hidePreviewFromWizard', undefined) } - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: configureStatus ? 'warning' : 'none', - force: true, - }) -} + 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 showCustomizeExporterSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/customizeExporter') - const configureStatus = getValue(discriminator, '/customizeExporter') - return configureStatus -} + function onConfigChange() { + const configName = getValue(discriminator, '/config') + const configs = objectCopy(backupConfigurationsFromStore) + const configDetails = configs?.find((item) => item?.metadata?.name === configName) -function onCustomizeExporterChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/customizeExporter') - if (configureStatus) { commit('wizard/model$update', { - path: '/resources/kubedbComMySQL/spec/monitor/prometheus/exporter', - value: {}, + path: '/resources/coreKubestashComBackupConfiguration', + value: configDetails, force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComMySQL/spec/monitor/prometheus/exporter') } -} -// ********************************* Initialization & Backup ************************************* -const stashAppscodeComRestoreSession_init = { - spec: { - repository: { - name: '', - }, - rules: [ - { - snapshots: ['latest'], - }, - ], - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} -const initScript = { - scriptPath: '', - secret: { - secretName: '', - }, -} -const stashAppscodeComRepository_init_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const stashAppscodeComRepository_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const restoreSessionInitRunTimeSettings = { - container: { - resources: { - requests: { - cpu: '', - memory: '', - }, - limits: { - cpu: '', - memory: '', - }, - }, - nice: { - adjustment: null, - }, - ionice: { - class: null, - classData: null, - }, - securityContext: { - privileged: false, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - env: [], - envFrom: [], - }, - pod: { - serviceAccountName: '', - imagePullSecrets: [], - securityContext: { - fsGroup: null, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - }, -} + function showPause() { + // watchDependency('discriminator#/backupConfigContext') + // watchDependency('discriminator#/config') + const contex = getValue(discriminator, '/backupConfigContext') + const configName = getValue(discriminator, '/config') + return !!configName && contex === 'Modify' + } -const stashAppscodeComBackupConfiguration = { - spec: { - repository: { - name: '', - }, - retentionPolicy: { - keepLast: 5, - name: 'keep-last-5', - prune: true, - }, - schedule: '*/5 * * * *', - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} + 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 valueExists(value, getValue, path) { - const val = getValue(value, path) - if (val) return true - else return false -} + function showConfigList() { + // watchDependency('discriminator#/backupConfigContext') + const contex = getValue(discriminator, '/backupConfigContext') + return contex === 'Modify' || contex === 'Delete' + } -function initPrePopulateDatabase({ getValue, model }) { - const waitForInitialRestore = getValue( - model, - '/resources/kubedbComMySQL/spec/init/waitForInitialRestore', - ) - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - const script = getValue(model, '/resources/kubedbComMySQL/spec/init/script') + 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 + } - return waitForInitialRestore || !!stashAppscodeComRestoreSession_init || !!script ? 'yes' : 'no' -} + function showScheduleBackup() { + const operationQuery = storeGet('/route/params/actions') || '' + const isBackupOperation = operationQuery === 'edit-self-backupconfiguration' ? true : false + return !isBackupOperation + } -function onPrePopulateDatabaseChange({ commit, getValue, discriminator, model }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - if (prePopulateDatabase === 'no') { - // delete related properties - commit('wizard/model$update', { - path: '/resources/kubedbComMySQL/spec/init/waitForInitialRestore', - value: false, - }) - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - commit('wizard/model$delete', '/resources/kubedbComMySQL/spec/init/script') - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else { - const dbName = getValue(model, '/metadata/release/name') - // set stashAppscodeComRestoreSession_init if it doesn't exist - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - force: true, - }) + 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: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, + path: modelPath, + value: session, }) } } -} - -function initDataSource({ getValue, model }) { - const script = getValue(model, '/resources/kubedbComMySQL/spec/init/script') - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - - if (script) return 'script' - else if (stashAppscodeComRestoreSession_init) return 'stashBackup' - else return undefined -} -function onDataSourceChange({ commit, getValue, discriminator, model }) { - const dataSource = getValue(discriminator, '/dataSource') + function objectCopy(obj) { + const temp = JSON.stringify(obj) + return JSON.parse(temp) + } - commit('wizard/model$update', { - path: '/resources/kubedbComMySQL/spec/init/waitForInitialRestore', - value: dataSource === 'stashBackup', - force: true, - }) + /*********** Compute Autoscaling ************/ - if (dataSource === 'script') { - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') + let autoscaleType = '' + let dbDetails = {} + let instance = '' - // create a new script if there is no script property - if (!valueExists(model, getValue, '/resources/kubedbComMySQL/spec/init/script')) - commit('wizard/model$update', { - path: '/resources/kubedbComMySQL/spec/init/script', - value: initScript, - }) - } else if (dataSource === 'stashBackup') { - commit('wizard/model$delete', '/resources/kubedbComMySQL/spec/init/script') + function isKubedb() { + return !!storeGet('/route/params/actions') + } - // create a new stashAppscodeComRestoreSession_init if there is no stashAppscodeComRestoreSession_init property - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - const dbName = getValue(model, '/metadata/release/name') + function isConsole() { + const isKube = isKubedb() + if (isKube) { + const dbName = storeGet('/route/params/name') || '' commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, + 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/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, + 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 } -} -// // for script -function initVolumeType({ getValue, model }) { - const configMap = getValue(model, '/resources/kubedbComMySQL/spec/init/script/configMap/name') - const secret = getValue(model, '/resources/kubedbComMySQL/spec/init/script/secret/secretName') + async function getNamespaces() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - if (configMap) return 'configMap' - else if (secret) return 'secret' - else return undefined -} + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, + }) -function onVolumeTypeChange({ commit, getValue, discriminator, model }) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - if (sourceVolumeType === 'configMap') { - // add configMap object and delete secret object - commit('wizard/model$delete', '/resources/kubedbComMySQL/spec/init/script/secret') + const resources = (resp && resp.data && resp.data.items) || [] - if (!valueExists(model, getValue, '/resources/kubedbComMySQL/spec/init/script/configMap')) { - commit('wizard/model$update', { - path: '/resources/kubedbComMySQL/spec/init/script/configMap', - value: { - name: '', - }, - }) - } - } else if (sourceVolumeType === 'secret') { - // delete configMap object and add secret object - commit('wizard/model$delete', '/resources/kubedbComMySQL/spec/init/script/configMap') - - if (!valueExists(model, getValue, '/resources/kubedbComMySQL/spec/init/script/secret')) { - commit('wizard/model$update', { - path: '/resources/kubedbComMySQL/spec/init/script/secret', - value: { - secretName: '', - }, - }) - } - } -} - -function showInitializationForm({ getValue, discriminator, watchDependency }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - watchDependency('discriminator#/prePopulateDatabase') - return prePopulateDatabase === 'yes' -} - -function showScriptOrStashForm({ getValue, discriminator, watchDependency }, value) { - const dataSource = getValue(discriminator, '/dataSource') - watchDependency('discriminator#/dataSource') - return dataSource === value -} - -function showConfigMapOrSecretName({ getValue, discriminator, watchDependency }, value) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - watchDependency('discriminator#/sourceVolumeType') - return sourceVolumeType === value -} - -// for stash backup -function initializeNamespace({ getValue, model }) { - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} - -function showRepositorySelectOrCreate({ getValue, discriminator, watchDependency }, value) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - return repositoryChoise === value -} - -function onInitRepositoryChoiseChange({ getValue, discriminator, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - if (repositoryChoise === 'select') { - // delete stashAppscodeComRepository_init_repo from model - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else if (repositoryChoise === 'create') { - // add stashAppscodeComRepository_init_repo to model - commit('wizard/model$update', { - path: 'resources/stashAppscodeComRepository_init_repo', - value: stashAppscodeComRepository_init_repo, - }) - - const repositoryName = `${getValue(model, '/metadata/release/name')}-init-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: repositoryName, + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } }) } -} - -function initCustomizeRestoreJobRuntimeSettings({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function initCustomizeRestoreJobRuntimeSettingsForBackup({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} -function onCustomizeRestoreJobRuntimeSettingsChange({ commit, getValue, discriminator, model }) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - value: restoreSessionInitRunTimeSettings, - }) - } + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found } -} -function onCustomizeRestoreJobRuntimeSettingsChangeForBackup({ - commit, - getValue, - discriminator, - model, -}) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - ) { - // set new value + 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/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - value: {}, + path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + value: [namespace], force: true, }) } } -} - -function showRuntimeForm({ discriminator, getValue, watchDependency }, value) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - watchDependency('discriminator#/customizeRestoreJobRuntimeSettings') - return customizeRestoreJobRuntimeSettings === value -} -async function getImagePullSecrets({ getValue, model, watchDependency, axios, storeGet }) { - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') + 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 } } } }, + }, + ) - let resources = await getNamespacedResourceList(axios, storeGet, { - namespace, - group: 'core', - version: 'v1', - resource: 'secrets', - }) + const resources = (resp && resp.data && resp.data.items) || [] - resources = resources.filter((item) => { - const validType = ['kubernetes.io/dockerconfigjson'] - return validType.includes(item.type) - }) + 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, + }) - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: { name: name }, + // 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' + } -// FOR Backup Configuration + function onTriggerChange(type) { + const trigger = getValue(discriminator, `/${type}/trigger`) + const commitPath = `/resources/autoscalingKubedbComMySQLAutoscaler/spec/${type}/trigger` -// schedule bakcup + commit('wizard/model$update', { + path: commitPath, + value: trigger ? 'On' : 'Off', + force: true, + }) + } -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/'), - ) + function hasAnnotations() { + const annotations = + getValue(model, '/resources/autoscalingKubedbComMySQLAutoscaler/metadata/annotations') || {} + const instance = annotations['kubernetes.io/instance-type'] - return { - stashAppscodeComBackupConfiguration, - isBluePrint, + return !!instance } -} -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, - }) -} + function setAllowedMachine(minmax) { + const mx = instance?.includes(',') ? instance.split(',')[1] : '' + const mn = instance?.includes(',') ? instance.split(',')[0] : '' + const machineName = minmax === 'min' ? mn : mx -function addKubeDbComMySqlDbAnnotation(getValue, model, commit, key, value, force) { - const annotations = getValue(model, '/resources/kubedbComMySQL/metadata/annotations') || {} + // Find the machine details from topologyMachines + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] + const machineData = nodeGroups.find((item) => item.topologyValue === machineName) - if (annotations[key] === undefined) { - annotations[key] = value - } else if (force) { - annotations[key] = value + // 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: '', + } } - commit('wizard/model$update', { - path: '/resources/kubedbComMySQL/metadata/annotations', - value: annotations, - force: true, - }) -} + function getMachines(minmax) { + // watchDependency('discriminator#/topologyMachines') + const depends = minmax === 'min' ? 'max' : 'min' + const dependantPath = `/allowedMachine-${depends}` -function initScheduleBackupForEdit({ getValue, model, setDiscriminatorValue }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) + // watchDependency(`discriminator#${dependantPath}`) + const dependantMachineObj = getValue(discriminator, dependantPath) + const dependantMachine = dependantMachineObj?.machine || '' - initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} + const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) -function initScheduleBackup({ getValue, model }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) + // 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, + }, + } + }) - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} + const filteredMachine = machines?.filter((item, ind) => + minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, + ) -function onScheduleBackupChange({ commit, getValue, discriminator, model }) { - const scheduleBackup = getValue(discriminator, '/scheduleBackup') + return dependantIndex === -1 ? machines : filteredMachine + } - 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) + function onMachineChange(type) { + const annoPath = '/resources/autoscalingKubedbComMySQLAutoscaler/metadata/annotations' + const annotations = getValue(model, annoPath) || {} + const instance = annotations['kubernetes.io/instance-type'] - // create stashAppscodeComBackupConfiguration and initialize it if not exists + // 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 - const dbName = getValue(model, '/metadata/release/name') + // 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 ( - !valueExists(model, getValue, '/resources/stashAppscodeComBackupConfiguration') && - !isBluePrint - ) { + if (minMachine && maxMachine && instance !== minMaxMachine) { commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration', - value: stashAppscodeComBackupConfiguration, + path: `${allowedPath}/maxAllowed`, + value: maxMachineAllocatable, + force: true, }) commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, + path: `${allowedPath}/minAllowed`, + value: minMachineAllocatable, + force: true, + }) + commit('wizard/model$update', { + path: annoPath, + value: { ...annotations }, force: true, }) } } -} -// backup form -let isBackupOnModel = false -let dbResource = {} -let initialDbMetadata = {} -let namespaceList = [] -let backupConfigurationsFromStore = {} -let valuesFromWizard = {} -let initialArchiver = {} -let isArchiverAvailable = false -let archiverObjectToCommit = {} - -function showBackupForm({ getValue, discriminator, watchDependency }) { - const scheduleBackup = getValue(discriminator, '/scheduleBackup') - watchDependency('discriminator#/scheduleBackup') - - if (scheduleBackup === 'yes') return true - else return false -} + 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 initBackupData({ commit, storeGet, axios, getValue, model, setDiscriminatorValue }) { - // 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}` + 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 archAnnotation = resp.data?.metadata?.annotations - const annotationKeyToFind = `${resource}.${group}/archiver` - if (archAnnotation[annotationKeyToFind]) { - isArchiverAvailable = true - archiverObjectToCommit = { - ref: { - name: archAnnotation[annotationKeyToFind], - namespace: 'kubedb', - }, - } - } + 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 [] } - // 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, - ) + function isNodeTopologySelected() { + // watchDependency( + // 'model#/resources/autoscalingKubedbComMySQLAutoscaler/spec/compute/nodeTopology/name', + // ) + const nodeTopologyName = + getValue( + model, + '/resources/autoscalingKubedbComMySQLAutoscaler/spec/compute/nodeTopology/name', + ) || '' + return !!nodeTopologyName.length + } - // 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, + 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') ) + } - // set backup switch here - isBackupOn = !!config + function setApplyToIfReady() { + return 'IfReady' + } - // set initial data from stash-presets - const stashPreset = storeGet('/backup/stashPresets') - if (stashPreset) { - const { retentionPolicy, encryptionSecret, schedule, storageRef } = stashPreset + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } - const tempBackends = valuesFromWizard.spec?.backends - tempBackends[0]['storageRef'] = storageRef - tempBackends[0]['retentionPolicy'] = retentionPolicy - valuesFromWizard.spec['backends'] = tempBackends + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - 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}` + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) - tempSessions[0]['repositories'] = tempRepositories - tempSessions[0]['scheduler']['schedule'] = schedule - valuesFromWizard.spec['sessions'] = tempSessions - } + const resources = (resp && resp.data && resp.data.items) || [] - 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, + 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 [] + } } - setDiscriminatorValue('isBackupDataLoaded', true) -} + async function getNamespacedResourceList( + axios, + storeGet, + { namespace, group, version, resource }, + ) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function isBackupDataLoadedTrue({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/isBackupDataLoaded') - return !!getValue(discriminator, '/isBackupDataLoaded') -} + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` -async function setBackupType() { - return 'BackupConfig' -} + let ans = [] + try { + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) -async 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?.topology && isArchiverAvailable) { - arr.push({ - description: 'Enable/Disable Archiver', - text: 'Archiver', - value: 'Archiver', - }) + const items = (resp && resp.data && resp.data.items) || [] + ans = items + } catch (e) { + console.log(e) + } + + return ans } - return arr -} -function onBackupTypeChange({ commit, getValue, discriminator }) { - const type = getValue(discriminator, '/backupType') - commit('wizard/model$update', { - path: '/backupType', - value: type, - force: true, - }) - if (!isBackupOnModel) { - commit('wizard/model$delete', '/resources/coreKubestashComBackupConfiguration') - } else { + /********** 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: '/resources/coreKubestashComBackupConfiguration', - value: objectCopy(initialModel), + path: '/form/alert/enabled', + value: configureStatus ? 'warning' : 'none', force: true, }) } - commit('wizard/model$delete', '/context') - commit('wizard/model$update', { - path: '/resources/kubedbComMySQL', - value: objectCopy(dbResource), - force: true, - }) -} -function isBackupType({ watchDependency, getValue, discriminator }, type) { - watchDependency('discriminator#/backupType') - const selectedType = getValue(discriminator, '/backupType') + function showCustomizeExporterSection() { + // watchDependency('discriminator#/customizeExporter') + const configureStatus = getValue(discriminator, '/customizeExporter') + return configureStatus + } - return selectedType === type -} + 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 setBlueprintSwitch() { - const annotations = initialDbMetadata?.annotations + function isValueExistInModel(path) { + const modelValue = getValue(model, path) || null + return !!modelValue + } - return !!( - annotations['blueprint.kubestash.com/name'] && annotations['blueprint.kubestash.com/namespace'] - ) -} + // 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 onBlueprintChange({ getValue, discriminator, commit, model, storeGet }) { - const blueprintSwitch = getValue(discriminator, '/blueprintEnabled') - if (blueprintSwitch) addLabelAnnotation(commit, storeGet, 'annotations') - else deleteLabelAnnotation(commit, 'annotations') -} + function onLabelChange() { + const labels = getValue(model, '/resources/kubedbComMySQL/spec/metadata/labels') -function setArchiverSwitch() { - const archiver = dbResource?.spec?.archiver - return !!archiver -} + const agent = getValue(model, '/resources/kubedbComMySQL/spec/monitor/agent') -function onArchiverChange({ getValue, discriminator, commit, model, storeGet }) { - 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) + if (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', + value: labels, + force: true, + }) + } } -} -function addLabelAnnotation(commit, storeGet, type) { - const obj = objectCopy(initialDbMetadata[type]) + 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, + }) - 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' + onNamespaceChange() + onLabelChange() + } else { + commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') + } } - commit('wizard/model$update', { - path: `/resources/kubedbComMySQL/metadata/${type}`, - value: obj, - force: true, - }) -} - -function deleteLabelAnnotation(commit, 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'] + 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}` - commit('wizard/model$update', { - path: `/resources/kubedbComMySQL/metadata/${type}`, - value: obj, - force: true, - }) -} + const isKube = !!storeGet('/route/params/actions') -function getContext() { - if (isBackupOn) return ['Create', 'Delete', 'Modify'] - return ['Create'] -} + 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 onContextChange({ getValue, discriminator, commit, model }) { - 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, - }) + function onNamespaceChange() { + const namespace = getValue( + model, + '/resources/autoscalingKubedbComMySQLAutoscaler/metadata/namespace', + ) + if (!namespace) { + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComMySQLAutoscaler/spec/databaseRef/name', + ) + } } -} -function getConfigList({ storeGet }) { - 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 setValueFrom() { + if (isConfigMapTypeValueFrom()) { + return 'configMap' + } else if (isSecretTypeValueFrom()) { + return 'secret' + } else { + return 'input' + } + } -function onConfigChange({ getValue, discriminator, commit, storeGet, model }) { - const configName = getValue(discriminator, '/config') - const configs = objectCopy(backupConfigurationsFromStore) - const configDetails = configs?.find((item) => item?.metadata?.name === configName) + 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, + }) + } + } - commit('wizard/model$update', { - path: '/resources/coreKubestashComBackupConfiguration', - value: configDetails, - force: true, - }) -} + // function isEqualToValueFromType(value) { + // //watchDependency('discriminator#/valueFromType') + // const valueFrom = getValue(discriminator, '/valueFromType') + // return valueFrom === value + // } -function showPause({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/backupConfigContext') - watchDependency('discriminator#/config') - const contex = getValue(discriminator, '/backupConfigContext') - const configName = getValue(discriminator, '/config') - return !!configName && contex === 'Modify' -} + async function resourceNames(group, version, resource) { + const namespace = getValue(model, '/metadata/release/namespace') + // watchDependency('model#/metadata/release/namespace') -function showConfigList({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/backupConfigContext') - const contex = getValue(discriminator, '/backupConfigContext') - return contex === 'Modify' || contex === 'Delete' -} + let resources = await getNamespacedResourceList(axios, storeGet, { + namespace, + group, + version, + resource, + }) -function showSchedule({ watchDependency, getValue, discriminator }) { - 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 -} + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } -function getNamespaceArray() { - return namespaceList -} + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -// backup configuration form -function initalizeTargetReferenceName({ getValue, model, watchDependency }) { - const databaseName = getValue(model, '/metadata/release/name') - watchDependency('model#/metadata/release/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`, + ) - return databaseName -} + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/configMapKeyRef/name') -// restore session repository -function setInitialRestoreSessionRepo({ getValue, model }) { - const value = getValue(model, 'resources/stashAppscodeComRepository_init_repo') - return value ? 'create' : 'select' -} + if (!configMapName) return [] -// backup config repository -function initRepositoryChoise({ getValue, model }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/configmaps/${configMapName}`, + ) - if (stashAppscodeComRepository_repo) return 'create' - else return 'select' -} + const configMaps = (resp && resp.data && resp.data.data) || {} -function initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' - setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) + const configMapKeys = Object.keys(configMaps).map((item) => ({ + text: item, + value: item, + })) - return repoInitialSelectionStatus -} + return configMapKeys + } catch (e) { + console.log(e) + return [] + } + } -function onRepositoryChoiseChange({ getValue, discriminator, watchDependency, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') + 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') - if (repositoryChoise === 'select') { - // delete the stashAppscodeComRepository_repo - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') - } else if (repositoryChoise === 'create') { - // create new stashAppscodeComRepository_repo - if (!valueExists(model, getValue, '/resources/stashAppscodeComRepository_repo')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRepository_repo', - value: stashAppscodeComRepository_repo, - }) - const repositoryName = `${getValue(model, '/metadata/release/name')}-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) - } - } -} - -function onRepositoryNameChange({ getValue, model, commit }) { - const repositoryName = getValue(model, 'resources/stashAppscodeComRepository_repo/metadata/name') - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) -} - -// backup blueprint form -function getMongoAnnotations(getValue, model) { - const annotations = getValue(model, '/resources/kubedbComMySQL/metadata/annotations') - return { ...annotations } || {} -} - -function initFromAnnotationValue({ getValue, model }, key) { - const annotations = getMongoAnnotations(getValue, model) - return annotations[key] -} - -function onBackupBlueprintNameChange({ getValue, discriminator, commit, model }) { - const backupBlueprintName = getValue(discriminator, '/backupBlueprintName') - addKubeDbComMySqlDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/backup-blueprint', - backupBlueprintName, - true, - ) -} - -function onBackupBlueprintScheduleChange({ getValue, discriminator, commit, model }) { - const backupBlueprintSchedule = getValue(discriminator, '/schedule') - addKubeDbComMySqlDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/schedule', - backupBlueprintSchedule, - true, - ) -} - -function initFromAnnotationKeyValue({ getValue, model }, prefix) { - const annotations = getMongoAnnotations(getValue, model) - const newOb = {} - Object.keys(annotations).forEach((key) => { - if (key.startsWith(prefix)) { - const newKey = key.replace(prefix, '') - newOb[newKey] = annotations[key] - } - }) - return newOb -} - -function onTaskParametersChange({ getValue, discriminator, model, commit }) { - const taskParameters = getValue(discriminator, '/taskParameters') - - const taskParamterKeys = Object.keys(taskParameters).map( - (tp) => `params.stash.appscode.com/${tp}`, - ) - const oldAnnotations = getValue(model, '/resources/kubedbComMySQL/metadata/annotations') || {} - const newAnnotations = {} - - const filteredAnnotationKeys = Object.keys(oldAnnotations).filter( - (key) => !taskParamterKeys.includes(key) && !key.startsWith('params.stash.appscode.com/'), - ) - - filteredAnnotationKeys.forEach((key) => { - newAnnotations[key] = oldAnnotations[key] - }) - - Object.keys(taskParameters).forEach((tpk) => { - newAnnotations[`params.stash.appscode.com/${tpk}`] = taskParameters[tpk] - }) - - commit('wizard/model$update', { - path: '/resources/kubedbComMySQL/metadata/annotations', - value: newAnnotations, - }) -} - -function isValueExistInModel({ model, getValue }, path) { - const modelValue = getValue(model, path) - return !!modelValue -} - -function onNamespaceChange({ commit, model, getValue }) { - 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({ commit, model, getValue }) { - 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 onNameChange({ commit, model, getValue }) { - const dbName = getValue(model, '/metadata/release/name') - - const agent = getValue(model, '/resources/kubedbComMySQL/spec/monitor/agent') - - const labels = getValue(model, '/resources/kubedbComMySQL/spec/metadata/labels') - - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) - } - - const scheduleBackup = getValue(model, '/resources/stashAppscodeComBackupConfiguration') - - if (scheduleBackup) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_repo') - if (creatingNewRepo) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: `${dbName}-repo`, - force: true, - }) - } - } - - const prePopulateDatabase = getValue(model, '/resources/stashAppscodeComRestoreSession_init') - - if (prePopulateDatabase) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_init_repo') - if (creatingNewRepo) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: `${dbName}-init-repo`, - force: true, - }) - } - } - - // to reset configSecret name field - const hasSecretConfig = getValue(model, '/resources/secret_config') - if (hasSecretConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComMySQL/spec/configSecret/name', - value: `${dbName}-config`, - force: true, - }) - } -} - -function returnFalse() { - return false -} - -function onAgentChange({ commit, model, getValue }) { - 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({ commit, model, getValue }) - onLabelChange({ commit, model, getValue }) - } else { - commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') - } -} - -/************************************* Database Secret Section ********************************************/ - -function getCreateAuthSecret({ model, getValue }) { - const authSecret = getValue(model, '/resources/kubedbComMySQL/spec/authSecret') - - return !authSecret -} - -function showExistingSecretSection({ getValue, watchDependency, discriminator }) { - watchDependency('discriminator#/createAuthSecret') - const hasAuthSecretName = getValue(discriminator, '/createAuthSecret') - return !hasAuthSecretName -} - -function showPasswordSection({ getValue, watchDependency, discriminator }) { - return !showExistingSecretSection({ - getValue, - watchDependency, - discriminator, - }) -} - -function setAuthSecretPassword({ model, getValue }) { - const encodedPassword = getValue(model, '/resources/secret_auth/data/password') - return encodedPassword ? decodePassword({}, encodedPassword) : '' -} - -function onAuthSecretPasswordChange({ getValue, discriminator, commit }) { - const stringPassword = getValue(discriminator, '/password') - - if (stringPassword) { - commit('wizard/model$update', { - path: '/resources/secret_auth/data/password', - value: encodePassword({}, stringPassword), - force: true, - }) - commit('wizard/model$update', { - path: '/resources/secret_auth/data/username', - value: encodePassword({}, 'root'), - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/secret_auth') - } -} - -function disableInitializationSection({ model, getValue, watchDependency }) { - const initialized = getValue(model, '/resources/kubedbComMySQL/spec/init/initialized') - watchDependency('model#/resources/kubedbComMySQL/spec/init/initialized') - return !!initialized -} - -// eslint-disable-next-line no-empty-pattern -function encodePassword({}, value) { - return btoa(value) -} - -// eslint-disable-next-line no-empty-pattern -function decodePassword({}, value) { - return atob(value) -} - -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/resources/kubedbComMySQL/spec/authSecret') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/resources/secret_auth') - } -} - -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - - if (owner && cluster && namespace) { try { const resp = await axios.get( `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, { params: { - filter: { - items: { - data: { username: null, password: null }, - metadata: { name: null }, - type: null, - }, - }, + filter: { items: { metadata: { name: null }, type: null } }, }, }, ) @@ -1777,11 +1208,7 @@ async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) const secrets = (resp && resp.data && resp.data.items) || [] const filteredSecrets = secrets.filter((item) => { - const validType = [ - 'kubernetes.io/service-account-token', - 'Opaque', - 'kubernetes.io/basic-auth', - ] + const validType = ['kubernetes.io/service-account-token', 'Opaque'] return validType.includes(item.type) }) @@ -1794,863 +1221,266 @@ async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) return filteredSecrets } catch (e) { console.log(e) + return [] } } - return [] -} - -//////////////////// custom config ///////////////// -function onConfigurationSourceChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSource') - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_config') - } else { - const value = getValue(model, '/resources/secret_config') - if (!value) { - commit('wizard/model$update', { - path: '/resources/secret_config', - value: {}, - force: true, - }) - } - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComMySQL/spec/configSecret/name', - value: configSecretName, - force: true, - }) - } -} -function onConfigurationChange({ getValue, commit, discriminator, model }) { - const value = getValue(discriminator, '/configuration') - commit('wizard/model$update', { - path: '/resources/secret_config/stringData/my-config.cnf', - value: value, - force: true, - }) - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComMySQL/spec/configSecret/name', - value: configSecretName, - force: true, - }) -} + 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`, + ) -function setConfigurationSource({ model, getValue }) { - const modelValue = getValue(model, '/resources/secret_config') - if (modelValue) { - return 'create-new-config' - } - return 'use-existing-config' -} + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/secretKeyRef/name') -function setSecretConfigNamespace({ getValue, model, watchDependency }) { - watchDependency('model#/metadata/release/namespace') - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} + if (!secretName) return [] -function setConfiguration({ model, getValue }) { - return getValue(model, '/resources/secret_config/stringData/my-config.cnf') -} + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets/${secretName}`, + ) -function setConfigurationFiles({ model, getValue }) { - const value = getValue(model, '/resources/secret_config/data/my-config.cnf') - return atob(value) -} + const secret = (resp && resp.data && resp.data.data) || {} -function onSetCustomConfigChange({ discriminator, getValue, commit }) { - const value = getValue(discriminator, '/setCustomConfig') + const secretKeys = Object.keys(secret).map((item) => ({ + text: item, + value: item, + })) - if (value === 'no') { - commit('wizard/model$delete', '/resources/kubedbComMySQL/spec/configSecret') - commit('wizard/model$delete', '/resources/secret_config') + return secretKeys + } catch (e) { + console.log(e) + return [] + } } -} - -function getOpsRequestUrl({ storeGet, model, getValue, mode }, 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 + `/create-opsrequest-${reqType.toLowerCase()}?namespace=${namespace}` - - if (mode === 'standalone-step') 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 getCreateNameSpaceUrl({ model, getValue, storeGet }) { - 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + function returnFalse() { + return false } -} -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} + /********** Binding **********/ -function showScheduleBackup({ storeGet }) { - const operationQuery = storeGet('/route/params/actions') || '' - const isBackupOperation = operationQuery === 'edit-self-backupconfiguration' ? true : false - return !isBackupOperation -} - -function showBackupOptions({ discriminator, getValue, watchDependency }, backup) { - const backupEnabled = getValue(discriminator, '/backupEnabled') - if (backupEnabled) { - if (backup === 'alert') return true - else return false - } else { - if (backup === 'alert') return false - else return true + function isBindingAlreadyOn() { + const value = getValue(model, '/resources') + const keys = Object.keys(value) + const isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComMySQLBinding') + return isExposeBinding } -} - -function isBlueprintOption({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/blueprintOptions') - const blueprintOptions = getValue(discriminator, '/blueprintOptions') - return blueprintOptions === value -} - -function ifUsagePolicy({ discriminator, getValue, watchDependency, model }, value) { - watchDependency( - 'model#/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', - ) - const usagePolicy = getValue( - model, - '/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', - ) - return usagePolicy === value -} -async function getBlueprints({ getValue, model, setDiscriminatorValue, axios, storeGet }, backup) { - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const url = `clusters/${username}/${clusterName}/proxy/core.kubestash.com/v1alpha1/backupblueprints` - - try { - const resp = await axios.get(url) - let data = resp.data.items - return data - } catch (e) { - console.log(e) - } -} - -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} - -async function fetchNamespaces({ axios, storeGet }) { - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const group = storeGet('/route/params/group') - const version = storeGet('/route/params/version') - const resource = storeGet('/route/params/resource') - - const url = `clusters/${username}/${clusterName}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews` - - try { - const resp = await axios.post(url, { - _recurringCall: false, - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', + 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: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], + sourceRef: { + name: dbName, + namespace: dbNamespace, + }, }, - }) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] } - } catch (e) { - console.log(e) - } - return [] -} - -async function fetchNames( - { getValue, axios, storeGet, watchDependency, discriminator }, - version, - type, - discriminatorName, -) { - watchDependency(`discriminator#/${discriminatorName}`) - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const namespace = getValue(discriminator, `${discriminatorName}`) - const url = - type !== 'secrets' - ? `clusters/${username}/${clusterName}/proxy/storage.kubestash.com/${version}/namespaces/${namespace}/${type}` - : `clusters/${username}/${clusterName}/proxy/core/${version}/namespaces/${namespace}/${type}` - try { - if (namespace) { - const resp = await axios.get(url) - let data = resp.data.items - if (type === 'secrets') data = data.filter((ele) => !!ele.data['RESTIC_PASSWORD']) - data = data.map((ele) => ele.metadata.name) - return data - } - } catch (e) { - console.log(e) - } - return [] -} - -function initBlueprint() { - return 'create' -} - -function initUsagePolicy() { - return 'Same' -} - -function onInputChange( - { getValue, discriminator, watchDependency, commit, model }, - modelPath, - field, - subfield, - discriminatorName, -) { - const value = getValue(discriminator, `/${discriminatorName}`) - const backends = getValue(model, modelPath) || [] - if (field !== 'encryptionSecret') backends[0][field][subfield] = value - else backends[0]['repositories'][0][field][subfield] = value - commit('wizard/model$update', { - path: modelPath, - value: backends, - }) -} -function setFileValueFromStash({ getValue, commit, model }, modelPath, field, subfield, value) { - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') backends[0][field][subfield] = value - else backends[0]['repositories'][0][field][subfield] = value - commit('wizard/model$update', { - path: modelPath, - value: backends, - }) -} - -function onInputChangeSchedule( - { getValue, discriminator, commit, model }, - modelPath, - discriminatorName, -) { - const value = getValue(discriminator, `/${discriminatorName}`) - const session = getValue(model, modelPath) - session[0].scheduler.schedule = value - commit('wizard/model$update', { - path: modelPath, - value: session, - }) -} - -function setInitSchedule( - { getValue, discriminator, watchDependency, commit, model }, - modelPath, - value, -) { - const session = getValue(model, modelPath) - session[0].scheduler.schedule = value - commit('wizard/model$update', { - path: modelPath, - value: session, - }) -} - -function getDefault({ getValue, model }, modelPath, field, subfield) { - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') return backends[0][field][subfield] - else { - return backends[0]['repositories'][0][field][subfield] - } -} - -function getDefaultSchedule({ getValue, model, watchDependency }, modelPath) { - watchDependency('discriminator#/config') - const session = getValue(model, modelPath) - return session?.length ? session[0]?.scheduler.schedule : '' -} -//////////////////// Auto Scaler ///////////////// -let autoscaleType = '' -let dbDetails = {} - -function isConsole({ storeGet, commit }) { - const isKube = isKubedb({ storeGet }) - - 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) { + if (value) { commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComMySQLAutoscaler/metadata/namespace', - value: namespace, + path: '/resources/catalogAppscodeComMySQLBinding', + value: bindingValues, force: true, }) + } else { + commit('wizard/model$delete', '/resources/catalogAppscodeComMySQLBinding') } } - return !isKube -} - -function isKubedb({ storeGet }) { - return !!storeGet('/route/params/actions') -} - -function showOpsRequestOptions({ model, getValue, watchDependency, storeGet, discriminator }) { - if (isKubedb({ storeGet }) === true) return true - watchDependency('model#/resources/autoscalingKubedbComMySQLAutoscaler/spec/databaseRef/name') - watchDependency('discriminator#/autoscalingType') - return ( - !!getValue(model, '/resources/autoscalingKubedbComMySQLAutoscaler/spec/databaseRef/name') && - !!getValue(discriminator, '/autoscalingType') - ) -} - -async function getNamespaces({ axios, storeGet }) { - 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 getMysqlDbs({ axios, storeGet, model, getValue, watchDependency }) { - 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 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 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 initMetadata({ getValue, discriminator, model, commit, storeGet }) { - 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') -} - -function onNamespaceChange({ model, getValue, commit }) { - const namespace = getValue( - model, - '/resources/autoscalingKubedbComMySQLAutoscaler/metadata/namespace', - ) - if (!namespace) { - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComMySQLAutoscaler/spec/databaseRef/name', - ) - } -} - -function ifScalingTypeEqualsTo( - { storeGet, watchDependency, getValue, discriminator, model }, - type, -) { - watchDependency('discriminator#/autoscalingType') - watchDependency('model#/resources/autoscalingKubedbComMySQLAutoscaler/spec/databaseRef/name') - - const operation = storeGet('/route/params/actions') || '' - if (operation.length) { - const splitOp = operation.split('-') - if (splitOp.length > 2) autoscaleType = splitOp[2] - } else autoscaleType = getValue(discriminator, '/autoscalingType') || '' - const isDatabaseSelected = !!getValue( - model, - '/resources/autoscalingKubedbComMySQLAutoscaler/spec/databaseRef/name', - ) - return autoscaleType === type && isDatabaseSelected -} - -async function fetchNodeTopology({ axios, storeGet }) { - 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, getValue }) { - watchDependency( - 'model#/resources/autoscalingKubedbComMySQLAutoscaler/spec/compute/nodeTopology/name', - ) - const nodeTopologyName = - getValue( - model, - '/resources/autoscalingKubedbComMySQLAutoscaler/spec/compute/nodeTopology/name', - ) || '' - return !!nodeTopologyName.length -} - -function setControlledResources({ commit }, 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 -} - -function setTrigger({ model, getValue }, path) { - let value = getValue(model, `/resources/${path}`) - if (value) return value - return 'On' -} - -function setApplyToIfReady() { - return 'IfReady' -} -function handleUnit({ commit, model, getValue }, 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' + 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 } } } - if (!isNaN(threshold)) { - threshold += 'pc' - } - updatedValue.push({ threshold, appliesUpto }) + return ret }) - if (JSON.stringify(updatedValue) !== JSON.stringify(value)) { - commit('wizard/model$update', { - path: `/resources/${path}`, - value: updatedValue, - force: true, - }) - } - } else { - if (!isNaN(value)) { - value += 'Gi' + + if (filteredEnv.length) commit('wizard/model$update', { - path: `/resources/${path}`, - value: value, + path: '/resources/kubedbComMySQL/spec/monitor/prometheus/exporter/env', + value: filteredEnv, force: true, }) - } } -} -function objectCopy(obj) { - const temp = JSON.stringify(obj) - return JSON.parse(temp) -} - -function isBindingAlreadyOn({ model, getValue }) { - const value = getValue(model, '/resources') - const keys = Object.keys(value) - isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComMySQLBinding') - return isExposeBinding -} + function initEnvArray() { + const env = getValue(model, '/resources/kubedbComMySQL/spec/monitor/prometheus/exporter/env') -async function addOrRemoveBinding({ commit, model, getValue, discriminator }) { - 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) { - await commit('wizard/model$update', { - path: '/resources/catalogAppscodeComMySQLBinding', - value: bindingValues, - force: true, - }) - } else { - await commit('wizard/model$delete', '/resources/catalogAppscodeComMySQLBinding') + return env || [] } -} - -async function fetchTopologyMachines({ axios, getValue, storeGet, model, setDiscriminatorValue }) { - const instance = hasAnnotations({ model, getValue }) - 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 isEqualToTemp(value, index) { + //watchDependency('discriminator#/valueFromType') + const valueFrom = getValue(discriminator, `/env/${index}/temp/valueFromType`) + return valueFrom === value } -} - -function setAllowedMachine({ model, getValue }, minmax) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComMySQLAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - const mx = instance?.includes(',') ? instance.split(',')[1] : '' - const mn = instance?.includes(',') ? instance.split(',')[0] : '' - - if (minmax === 'min') return mn - else return mx -} - -async function getMachines({ getValue, watchDependency, discriminator }, minmax) { - watchDependency('discriminator#/topologyMachines') - const depends = minmax === 'min' ? 'max' : 'min' - const dependantPath = `/allowedMachine-${depends}` - - watchDependency(`discriminator#${dependantPath}`) - const dependantMachine = getValue(discriminator, dependantPath) - - const nodeGroups = getValue(discriminator, '/topologyMachines') || [] - - const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) - - const machines = nodeGroups?.map((item) => { - const subText = `CPU: ${item.allocatable.cpu}, Memory: ${item.allocatable.memory}` - const text = item.topologyValue - return { text, subText, value: item.topologyValue } - }) - - const filteredMachine = machines?.filter((item, ind) => - minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, - ) - - return dependantIndex === -1 ? machines : filteredMachine -} -function hasAnnotations({ model, getValue }) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComMySQLAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - - return !!instance -} - -function hasNoAnnotations({ model, getValue }) { - return !hasAnnotations({ model, getValue }) -} - -function onMachineChange({ model, getValue, discriminator, commit }, type) { - const annoPath = '/resources/autoscalingKubedbComMySQLAutoscaler/metadata/annotations' - const annotations = getValue(model, annoPath) - const instance = annotations['kubernetes.io/instance-type'] - - const minMachine = getValue(discriminator, '/allowedMachine-min') - const maxMachine = getValue(discriminator, '/allowedMachine-max') - const minMaxMachine = `${minMachine},${maxMachine}` - annotations['kubernetes.io/instance-type'] = minMaxMachine - - const machines = getValue(discriminator, `/topologyMachines`) || [] - const minMachineObj = machines.find((item) => item.topologyValue === minMachine) - const maxMachineObj = machines.find((item) => item.topologyValue === maxMachine) - const minMachineAllocatable = minMachineObj?.allocatable - const maxMachineAllocatable = maxMachineObj?.allocatable - 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 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 { - getMachines, - setAllowedMachine, - hasAnnotations, - hasNoAnnotations, - fetchTopologyMachines, - onMachineChange, - handleUnit, - isConsole, - getNamespaces, - getMysqlDbs, - isKubedb, - initMetadata, - onNamespaceChange, - ifScalingTypeEqualsTo, - fetchNodeTopology, - isNodeTopologySelected, - setControlledResources, - setTrigger, - setApplyToIfReady, - showOpsRequestOptions, - setInitSchedule, - fetchNames, - fetchNamespaces, - isRancherManaged, - onInputChangeSchedule, - getDefaultSchedule, - getBlueprints, - ifUsagePolicy, - initUsagePolicy, - isBlueprintOption, - initBlueprint, - getDefault, - onInputChange, - showBackupOptions, - showScheduleBackup, - isVariantAvailable, - fetchJsons, - disableLableChecker, - isEqualToModelPathValue, - getResources, - isEqualToDiscriminatorPath, - setValueFromModel, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - returnTrue, - returnStringYes, - setAddressType, - getMySqlVersions, - setDatabaseMode, - getStorageClassNames, - deleteDatabaseModePath, - isEqualToDatabaseMode, - isNotEqualToDatabaseMode, - setApiGroup, - getIssuerRefsName, - hasIssuerRefName, - hasNoIssuerRefName, - setSSLMode, - showTlsConfigureSection, - onTlsConfigureChange, - getAliasOptions, - showMonitoringSection, - onEnableMonitoringChange, - showCustomizeExporterSection, - onCustomizeExporterChange, - valueExists, - initPrePopulateDatabase, - onPrePopulateDatabaseChange, - initDataSource, - onDataSourceChange, - initVolumeType, - onVolumeTypeChange, - showInitializationForm, - showScriptOrStashForm, - showConfigMapOrSecretName, - initializeNamespace, - showRepositorySelectOrCreate, - onInitRepositoryChoiseChange, - initCustomizeRestoreJobRuntimeSettings, - initCustomizeRestoreJobRuntimeSettingsForBackup, - onCustomizeRestoreJobRuntimeSettingsChange, - onCustomizeRestoreJobRuntimeSettingsChangeForBackup, - showRuntimeForm, - getImagePullSecrets, - getBackupConfigsAndAnnotations, - deleteKubeDbComMySqlDbAnnotation, - addKubeDbComMySqlDbAnnotation, - initScheduleBackup, - initScheduleBackupForEdit, - onScheduleBackupChange, - showBackupForm, - initalizeTargetReferenceName, - setInitialRestoreSessionRepo, - initRepositoryChoise, - initRepositoryChoiseForEdit, - onRepositoryChoiseChange, - onRepositoryNameChange, - getMongoAnnotations, - initFromAnnotationValue, - onBackupBlueprintNameChange, - onBackupBlueprintScheduleChange, - initFromAnnotationKeyValue, - onTaskParametersChange, - isValueExistInModel, - onNamespaceChange, - onLabelChange, - onNameChange, - returnFalse, - onAgentChange, - getCreateAuthSecret, - showExistingSecretSection, - showPasswordSection, - setAuthSecretPassword, - onAuthSecretPasswordChange, - disableInitializationSection, - encodePassword, - decodePassword, - onCreateAuthSecretChange, - getSecrets, - onConfigurationSourceChange, - onConfigurationChange, - setConfigurationSource, - setSecretConfigNamespace, - setConfiguration, - setConfigurationFiles, - onSetCustomConfigChange, - getOpsRequestUrl, - getCreateNameSpaceUrl, - setStorageClass, - - initBackupData, - isBackupDataLoadedTrue, - setBackupType, - getTypes, - isBackupType, - getContext, - onContextChange, - getConfigList, - onConfigChange, - showPause, - showSchedule, - showConfigList, - setBlueprintSwitch, - onBlueprintChange, - setArchiverSwitch, - onArchiverChange, - onBackupTypeChange, - getNamespaceArray, - isBindingAlreadyOn, - addOrRemoveBinding, + 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, + } } diff --git a/charts/kubedbcom-oracle-editor-options/ui/create-ui.yaml b/charts/kubedbcom-oracle-editor-options/ui/create-ui.yaml index 07fcf859e7..e0eade71cf 100644 --- a/charts/kubedbcom-oracle-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-oracle-editor-options/ui/create-ui.yaml @@ -1,310 +1,315 @@ -steps: -- form: - discriminator: - bundleApiLoaded: - default: false - type: boolean +step: +- type: single-step-form + loader: initBundle + elements: + - type: label-element + label: '' + subtitle: Select the Oracle version you want to deploy on Kubernetes. The chosen version determines the Oracle engine features, compatibility, and runtime behavior of your database. + - disableUnselect: true + loader: getAdminOptions|databases/Oracle/versions + if: + type: function + name: isToggleOn|databases/Oracle/versions + label: Database Version + schema: schema/properties/spec/properties/admin/properties/databases/properties/Oracle/properties/versions/properties/default + type: select + - init: + type: func + value: getDefault|databases/Oracle/mode + loader: getAdminOptions|databases/Oracle/mode + isHorizontal: true + if: + type: function + name: isToggleOn|databases/Oracle/mode + label: Database Mode + watcher: + func: toggleTls + paths: + - schema/properties/spec/properties/mode + schema: schema/properties/spec/properties/mode + type: radio + - if: + type: function + name: isEqualToModelPathValue|Replicaset|/spec/mode + label: Replica number + schema: schema/properties/spec/properties/replicas + type: input + - elements: + - type: label-element + label: '' + subtitle: Select a machine profile to allocate CPU and memory resources for your database. Choose 'custom' to manually specify resource requirements or select a predefined profile. + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: CPU + watcher: + func: setRequests|cpu + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: Memory + watcher: + func: setRequests|memory + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + label: Machine Profile + showLabels: true + type: block-layout + - type: horizontal-layout + showLabels: true elements: - - computed: initBundle - if: returnFalse - type: label-element - - disableUnselect: true - fetch: getAdminOptions|databases/Oracle/versions - if: isToggleOn|databases/Oracle/versions - label: - text: labels.database.version - schema: - $ref: schema#/properties/spec/properties/admin/properties/databases/properties/Oracle/properties/versions/properties/default + - loader: getAdminOptions|storageClasses + if: + type: function + name: isToggleOn|storageClasses + label: Storage Class + schema: schema/properties/spec/properties/admin/properties/storageClasses/properties/default type: select - - computed: getDefault|databases/Oracle/mode - fetch: getAdminOptions|databases/Oracle/mode - hasDescription: true - if: isToggleOn|databases/Oracle/mode - label: - text: labels.database.mode - onChange: toggleTls - schema: - $ref: schema#/properties/spec/properties/mode - type: radio - - if: isEqualToModelPathValue|Replicaset|/spec/mode - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/replicas + - label: Storage Size + schema: schema/properties/spec/properties/persistence/properties/size type: input + - description: Configure Credentials, Deployment Mode etc. + elements: - elements: - - computed: setMachineToCustom - customClass: mt-10 - fetch: getMachineListForOptions - label: - text: labels.machine - schema: - $ref: schema#/properties/spec/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.cpu - onChange: setRequests|cpu - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.memory - onChange: setRequests|memory - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - label: - text: labels.machine_profile - show_label: true - type: single-step-form - - fetch: getAdminOptions|storageClasses - if: isToggleOn|storageClasses - label: - text: labels.storage.class - schema: - $ref: schema#/properties/spec/properties/admin/properties/storageClasses/properties/default + - type: label-element + label: '' + subtitle: Add custom labels and annotations to your database resources for organization, monitoring, and integration with other Kubernetes tools and services. + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/annotations + label: Labels & Annotations + showLabels: true + hideBlock: true + type: block-layout + - init: + type: func + value: getDefault|deletionPolicy + customClass: mt-20 + if: + type: function + name: isToggleOn|deletionPolicy + label: Deletion Policy + watcher: + func: setStorageClass + paths: + - schema/properties/spec/properties/deletionPolicy + options: + - description: options.deletionPolicy.delete.description + text: Delete + value: Delete + - description: options.deletionPolicy.halt.description + text: Halt + value: Halt + - description: options.deletionPolicy.wipeOut.description + text: WipeOut + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: DoNotTerminate + value: DoNotTerminate + schema: schema/properties/spec/properties/deletionPolicy + type: select + - if: + type: function + name: getDefaultValue|spec/admin/authCredential/customize + label: Provide Authentication Credentials? + watcher: + func: onAuthChange + paths: + - temp/createAuthSecret + schema: temp/createAuthSecret + type: switch + - if: + type: function + name: showReferSecretSwitch + label: Refer existing Secret? + watcher: + func: onReferSecretChange + paths: + - temp/referSecret + schema: temp/referSecret + type: switch + - loader: getReferSecrets + if: + type: function + name: showSecretDropdown + label: Secret + schema: schema/properties/spec/properties/authSecret/properties/name type: select - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/persistence/properties/size + - if: + type: function + name: showReferSecret + label: Password + schema: schema/properties/spec/properties/authSecret/properties/password type: input - - accordion: true - description: - text: Configure Credentials, Deployment Mode etc. - discriminator: - configDatabase: - default: false - type: boolean - createAuthSecret: - default: false - type: boolean - referSecret: - default: false - type: boolean - elements: - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties - type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties - type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - computed: getDefault|deletionPolicy - customClass: mt-20 - if: isToggleOn|deletionPolicy - 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/spec/properties/deletionPolicy - type: select - - if: getDefaultValue|spec/admin/authCredential/customize - label: - text: Provide Authentication Credentials? - onChange: onAuthChange - schema: - $ref: discriminator#/createAuthSecret - type: switch - - if: showReferSecretSwitch - label: - text: Refer existing Secret? - onChange: onReferSecretChange - schema: - $ref: discriminator#/referSecret + - if: + type: function + name: getDefaultValue|spec/admin/customConfiguration + label: Configure Database? + watcher: + func: clearConfiguration + paths: + - temp/configDatabase + schema: temp/configDatabase + type: switch + - if: + type: function + name: isConfigDatabaseOn + label: Configuration + schema: schema/properties/spec/properties/configuration + type: textarea + - isHorizontal: true + if: + type: function + name: isToggleOn|deployment + label: Deployment Mode + options: + - description: Shared + text: Shared + value: Shared + - description: Dedicated + text: Dedicated + value: Dedicated + schema: schema/properties/spec/properties/admin/properties/deployment/properties/default + type: radio + - if: + type: function + name: isToggleOn|clusterTier + isHorizontal: true + label: Cluster Tier + options: + - text: General Purpose + value: GeneralPurpose + - text: Memory Optimized + value: MemoryOptimized + - text: CPU Optimized + value: CPUOptimized + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/default + type: radio + - disableUnselect: true + loader: getAdminOptions|clusterTier/placement + if: + type: function + name: isToggleOn|clusterTier/placement + label: Placement Policy + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + type: select + - disableUnselect: true + loader: getNodeTopology + if: + type: function + name: isToggleOn|clusterTier/nodeTopology + label: Node Topology + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + type: select + label: Advanced Configuration + showLabels: true + type: block-layout + - description: Enable Backup, Monitoring, TLS etc. + elements: + - init: + type: func + value: setBackup + if: + type: function + name: returnFalse + label: Enable Backup? + watcher: + func: onBackupSwitch + paths: + - temp/backup + schema: temp/backup + type: switch + - elements: + - disable: showArchiverAlert + label: Enable Archiver? + watcher: + func: onArchiverChange + paths: + - schema/properties/spec/properties/admin/properties/archiver/properties/enable/properties/default + schema: schema/properties/spec/properties/admin/properties/archiver/properties/enable/properties/default type: switch - - fetch: getReferSecrets - if: showSecretDropdown - label: - text: Secret - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/name - type: select - - if: showReferSecret - label: - text: labels.password - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/password - type: input - - computed: isConfigAvailable - if: getDefaultValue|spec/admin/customConfiguration - label: - text: Configure Database? - onChange: clearConfiguration - schema: - $ref: discriminator#/configDatabase + - if: + type: function + name: showArchiverAlert + label: The selected StorageClass does not support Archiver + type: warning + if: + type: function + name: returnFalse + type: block-layout + - elements: + - init: + type: func + value: checkHostnameOrIP + if: + type: function + name: returnFalse + label: Enable TLS? + watcher: + func: checkHostnameOrIP + paths: + - schema/properties/spec/properties/admin/properties/tls/properties/default + schema: schema/properties/spec/properties/admin/properties/tls/properties/default type: switch - - if: isConfigDatabaseOn - label: - text: Configuration - schema: - $ref: schema#/properties/spec/properties/configuration - type: editor - - hasDescription: true - if: isToggleOn|deployment - label: - text: labels.deployment.name - options: - - description: labels.deployment.shared - text: Shared - value: Shared - - description: labels.deployment.dedicated - text: Dedicated - value: Dedicated - schema: - $ref: schema#/properties/spec/properties/admin/properties/deployment/properties/default - type: radio - - if: isToggleOn|clusterTier - isHorizontal: true - label: - text: labels.clusterTier - options: - - text: General Purpose - value: GeneralPurpose - - text: Memory Optimized - value: MemoryOptimized - - text: CPU Optimized - value: CPUOptimized - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/default - type: radio - - disableUnselect: true - fetch: getAdminOptions|clusterTier/placement - if: isToggleOn|clusterTier/placement - label: - text: labels.placement - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + - loader: getAdminOptions|clusterIssuers + if: + type: function + name: showIssuer + label: Cluster Issuers + validation: + type: required + schema: schema/properties/spec/properties/admin/properties/clusterIssuers/properties/default type: select - - disableUnselect: true - fetch: getNodeTopology - if: isToggleOn|clusterTier/nodeTopology - label: - text: labels.nodeTopology - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default - type: select - hideForm: true - label: - text: Advanced Configuration - show_label: true - type: single-step-form - - accordion: true - description: - text: Enable Backup, Monitoring, TLS etc. - discriminator: - backup: - default: false - type: boolean - elements: - - computed: setBackup - if: returnFalse - label: - text: Enable Backup? - onChange: onBackupSwitch - schema: - $ref: discriminator#/backup + type: block-layout + - elements: + - init: + type: func + value: checkHostnameOrIP + if: + type: function + name: isToggleOn|expose + label: Expose via Gateway? + watcher: + func: checkHostnameOrIP + paths: + - schema/properties/spec/properties/admin/properties/expose/properties/default + schema: schema/properties/spec/properties/admin/properties/expose/properties/default type: switch - - disabled: true - elements: - - disabled: showArchiverAlert - label: - text: Enable Archiver? - onChange: onArchiverChange - schema: - $ref: schema#/properties/spec/properties/admin/properties/archiver/properties/enable/properties/default - type: switch - - alertInfo: - show: true - type: neutral - if: showArchiverAlert - label: - text: The selected StorageClass does not support Archiver - type: label-element - if: returnFalse - type: single-step-form - - elements: - - computed: checkHostnameOrIP - if: returnFalse - label: - text: Enable TLS? - onChange: checkHostnameOrIP - schema: - $ref: schema#/properties/spec/properties/admin/properties/tls/properties/default - type: switch - - fetch: getAdminOptions|clusterIssuers - if: showIssuer - label: - text: labels.clusterIssuers - required: true - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterIssuers/properties/default - type: select - type: single-step-form - - elements: - - computed: checkHostnameOrIP - if: isToggleOn|expose - label: - text: Expose via Gateway? - onChange: checkHostnameOrIP - schema: - $ref: schema#/properties/spec/properties/admin/properties/expose/properties/default - type: switch - type: single-step-form - if: showAdditionalSettings - label: - text: Additional Options - show_label: true - type: single-step-form - type: single-step-form + type: block-layout + if: + type: function + name: showAdditionalSettings + label: Additional Options + showLabels: true + type: block-layout id: options - title: steps.0.label type: multi-step-form diff --git a/charts/kubedbcom-oracle-editor-options/ui/functions.js b/charts/kubedbcom-oracle-editor-options/ui/functions.js index b89dc56ca3..517285f4f7 100644 --- a/charts/kubedbcom-oracle-editor-options/ui/functions.js +++ b/charts/kubedbcom-oracle-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -315,1133 +317,1155 @@ const modeDetails = { }, } -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} - -function showAuthSecretField({ discriminator, getValue, watchDependency }) { - return !showAuthPasswordField({ - discriminator, - getValue, - watchDependency, - }) -} -async function getResources({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, ) - const resources = (resp && resp.data && resp.data.items) || [] + setDiscriminatorValue('bundleApiLoaded', false) + setDiscriminatorValue('configDatabase', false) + setDiscriminatorValue('createAuthSecret', false) + setDiscriminatorValue('referSecret', false) + setDiscriminatorValue('backup', false) - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return resources -} + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // // watchDependency('model#' + modelPath) + return modelPathValue === value + } + + function showAuthSecretField() { + return !showAuthPasswordField() + } -async function getMySqlVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, + 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 } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) + async function getMySqlVersions(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - const resources = (resp && resp.data && resp.data.items) || [] + const queryParams = { + filter: { + items: { + metadata: { name: null }, + spec: { version: null, deprecated: null }, + }, + }, + } - // keep only non deprecated versions - const filteredMySqlVersions = resources.filter((item) => item.spec && !item.spec.deprecated) + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: queryParams, + }, + ) - filteredMySqlVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredMySqlVersions -} + const resources = (resp && resp.data && resp.data.items) || [] + + // keep only non deprecated versions + const filteredMySqlVersions = resources.filter((item) => item.spec && !item.spec.deprecated) -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/spec/authSecret/name') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/spec/authSecret/password') + filteredMySqlVersions.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + const specVersion = (item.spec && item.spec.version) || '' + item.text = `${name} (${specVersion})` + item.value = name + return true + }) + return filteredMySqlVersions } -} -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') + function onCreateAuthSecretChange() { + const createAuthSecret = getValue(discriminator, '/createAuthSecret') + if (createAuthSecret) { + commit('wizard/model$delete', '/spec/authSecret/name') + } else if (createAuthSecret === false) { + commit('wizard/model$delete', '/spec/authSecret/password') + } + } - if (owner && cluster && namespace) { - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { - items: { - data: { username: null, password: null }, - metadata: { name: null }, - type: null, + 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') + + if (owner && cluster && namespace) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { + items: { + data: { username: null, password: null }, + metadata: { name: null }, + type: null, + }, }, }, }, - }, - ) + ) - const secrets = (resp && resp.data && resp.data.items) || [] + const secrets = (resp && resp.data && resp.data.items) || [] - const filteredSecrets = secrets.filter((item) => { - const validType = [ - 'kubernetes.io/service-account-token', - 'Opaque', - 'kubernetes.io/basic-auth', - ] - return validType.includes(item.type) - }) + const filteredSecrets = secrets.filter((item) => { + const validType = [ + 'kubernetes.io/service-account-token', + 'Opaque', + 'kubernetes.io/basic-auth', + ] + 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) + 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 [] } - return [] -} -function getMachineListForOptions({ model, getValue }) { - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - let array = [] - - if (available.length) { - array = available.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - else { - let subText = '', - text = '' - const machineData = machinesFromPreset.find((val) => val.id === machine) - if (machineData) { - subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` - text = machineData.name ? machineData.name : machineData.id - } - return { text, subText, value: machine } - } - }) - } else { - array = machineList - .map((machine) => { + function getMachineListForOptions() { + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + let array = [] + + if (available.length) { + array = available.map((machine) => { if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + else { + let subText = '', + text = '' + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + text = machineData.name ? machineData.name : machineData.id + } + return { text, subText, value: machine } + } }) - .filter((val) => !!val) + } else { + array = machineList + .map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { text, subText, value: machine } + }) + .filter((val) => !!val) + } + return array } - return array -} -function setMachineToCustom({ getValue, model }) { - const machine = getValue(model, '/spec/admin/machineProfiles/default') - return machine || 'custom' -} + function setMachineToCustom() { + const machine = getValue(model, '/spec/admin/machineProfiles/default') + return machine || 'custom' + } -async function fetchJsons({ axios, itemCtx }) { - let ui = {} - let language = {} - let functions = {} - const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart + async function fetchJsons() { + 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) - } + 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, + return { + ui: ui.data || {}, + language: language.data || {}, + functions, + } } -} -function updateAgentValue({ commit }, val) { - commit('wizard/model$update', { - path: '/spec/monitoring/agent', - value: val ? 'prometheus.io/operator' : '', - force: true, - }) - - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: val ? 'warning' : 'none', - force: true, - }) -} + function updateAgentValue(val) { + commit('wizard/model$update', { + path: '/spec/monitoring/agent', + value: val ? 'prometheus.io/operator' : '', + force: true, + }) -function setReplicaNumber({ model, getValue }) { - const modelPathValue = getValue(model, '/spec/mode') - if (modelPathValue === 'Topology') { - return 2 - } else return 1 -} -function setRouterNumber({ model, getValue }) { - const modelPathValue = getValue(model, '/spec/mode') - if (modelPathValue === 'Topology') { - return 3 - } else return 1 -} + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: val ? 'warning' : 'none', + force: true, + }) + } + + function setReplicaNumber() { + const modelPathValue = getValue(model, '/spec/mode') + if (modelPathValue === 'Topology') { + return 2 + } else return 1 + } + function setRouterNumber() { + const modelPathValue = getValue(model, '/spec/mode') + if (modelPathValue === 'Topology') { + return 3 + } else return 1 + } -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function getCreateNameSpaceUrl() { + 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + const domain = storeGet('/domain') || '' + if (domain.includes('bb.test')) { + return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } } -} -const ifCapiProviderIsNotEmpty = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/provider') - const val = getValue(model, '/form/capi/provider') - if (val) return true -} + const ifCapiProviderIsNotEmpty = ({ model, getValue, watchDependency }) => { + // // // // watchDependency('model#/form/capi/provider') + const val = getValue(model, '/form/capi/provider') + if (val) return true + } -const showMultiselectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') + const showMultiselectZone = ({ model, getValue, watchDependency }) => { + // // // // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') - if (val === 'capz' && ifDedicated({ model, getValue })) return true -} + if (val === 'capz' && ifDedicated()) return true + } -const showSelectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') - if (val !== 'capz' && ifDedicated({ model, getValue })) return true -} + const showSelectZone = ({ model, getValue, watchDependency }) => { + // // // // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') + if (val !== 'capz' && ifDedicated()) return true + } -const ifDedicated = ({ model, getValue }) => { - const val = getValue(model, 'form/capi/dedicated') - if (val) return true -} + const ifDedicated = ({ model, getValue }) => { + const val = getValue(model, 'form/capi/dedicated') + if (val) return true + } -const dedicatedOnChange = ({ model, getValue, commit }) => { - const val = getValue(model, 'form/capi/dedicated') - if (!val) { - commit('wizard/model$delete', 'form/capi/zones') - commit('wizard/model$delete', 'form/capi/sku') + const dedicatedOnChange = ({ model, getValue, commit }) => { + const val = getValue(model, 'form/capi/dedicated') + if (!val) { + commit('wizard/model$delete', 'form/capi/zones') + commit('wizard/model$delete', 'form/capi/sku') + } } -} -const ifZones = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/zones') - watchDependency('model#/form/capi/dedicated') - const zones = getValue(model, 'form/capi/zones') || [] - const isDedicated = getValue(model, 'form/capi/dedicated') - if (zones.length && isDedicated) return true -} + const ifZones = ({ model, getValue, watchDependency }) => { + // // // // watchDependency('model#/form/capi/zones') + // // // // watchDependency('model#/form/capi/dedicated') + const zones = getValue(model, 'form/capi/zones') || [] + const isDedicated = getValue(model, 'form/capi/dedicated') + if (zones.length && isDedicated) return true + } -const zonesOnChange = ({ model, getValue, commit }) => { - const zones = getValue(model, 'form/capi/zones') || [] - if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') -} + const zonesOnChange = ({ model, getValue, commit }) => { + const zones = getValue(model, 'form/capi/zones') || [] + if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') + } -async function getZones({ storeGet, axios, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const isDedicated = getValue(model, 'form/capi/dedicated') - if (isDedicated) { - try { - const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) - const val = resp.data.map((item) => { - return { value: item, text: item } - }) - return val - } catch (e) { - console.log(e) - return [] + async function getZones() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const isDedicated = getValue(model, 'form/capi/dedicated') + if (isDedicated) { + try { + const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) + const val = resp.data.map((item) => { + return { value: item, text: item } + }) + return val + } catch (e) { + console.log(e) + return [] + } } } -} -async function getSKU({ storeGet, axios, model, getValue, watchDependency }) { - watchDependency('model#/form/capi/zones') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const zones = getValue(model, 'form/capi/zones') || [] - if (zones.length) { - try { - let url = `clustersv2/${owner}/${cluster}/vms?` - if (typeof zones === 'string') { - url += `zones=${encodeURIComponent(zones)}` - } else { - zones.forEach((item) => { - url += `zones=${encodeURIComponent(item)}&` + async function getSKU() { + // // // // watchDependency('model#/form/capi/zones') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const zones = getValue(model, 'form/capi/zones') || [] + if (zones.length) { + try { + let url = `clustersv2/${owner}/${cluster}/vms?` + if (typeof zones === 'string') { + url += `zones=${encodeURIComponent(zones)}` + } else { + zones.forEach((item) => { + url += `zones=${encodeURIComponent(item)}&` + }) + url = url.slice(0, -1) + } + const resp = await axios.get(url) + const val = resp.data.map((item) => { + return { + value: item.name, + text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, + } }) - url = url.slice(0, -1) + return val + } catch (e) { + console.log(e) + return [] } - const resp = await axios.get(url) - const val = resp.data.map((item) => { - return { - value: item.name, - text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, - } - }) - return val - } catch (e) { - console.log(e) - return [] } } -} -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} - -function setStorageClass({ model, getValue, commit, discriminator, watchDependency }) { - const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' - let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' - const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] - const suffix = '-retain' - - const simpleClassList = storageClassList.filter((item) => { - return !item.endsWith(suffix) - }) - const retainClassList = storageClassList.filter((item) => { - return item.endsWith(suffix) - }) - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] - } else { - storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] - } - - const isChangeable = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'storageClasses', - ) - if (isChangeable && storageClass) { - commit('wizard/model$update', { - path: '/spec/admin/storageClasses/default', - value: storageClass, - force: true, - }) + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false } -} -function showAlerts({ watchDependency, model, getValue, discriminator }) { - watchDependency('discriminator#/monitoring') - const isMonitorEnabled = getValue(discriminator, '/monitoring') - return ( - isMonitorEnabled && isToggleOn({ getValue, model, discriminator, watchDependency }, 'alert') - ) -} - -function onBackupSwitch({ discriminator, getValue, commit }) { - const isBackupOn = getValue(discriminator, '/backup') - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: isBackupOn ? 'KubeStash' : '', - force: true, - }) -} + function setStorageClass() { + const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' + let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' + const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] + const suffix = '-retain' -function clearArbiterHidden({ commit }) { - commit('wizard/model$update', { - path: `/spec/arbiter/enabled`, - value: false, - force: true, - }) - - commit('wizard/model$update', { - path: `/spec/hidden/enabled`, - value: false, - force: true, - }) -} + const simpleClassList = storageClassList.filter((item) => { + return !item.endsWith(suffix) + }) + const retainClassList = storageClassList.filter((item) => { + return item.endsWith(suffix) + }) + if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { + storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] + } else { + storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + } -let placement = [] -let versions = [] -let storageClass = [] -let clusterIssuers = [] -let nodetopologiesShared = [] -let nodetopologiesDedicated = [] -let features = [] -async function initBundle({ commit, model, getValue, axios, storeGet, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - - let db = getValue(model, '/metadata/resource/kind') - db = db.toLowerCase() - let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` - const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - - try { - const resp = await axios.get(url) - features = resp.data.features || [] - placement = resp.data.placementpolicies || [] - versions = resp.data.versions || [] - storageClass = resp.data.storageclasses || [] - clusterIssuers = resp.data.clusterissuers || [] - nodetopologiesDedicated = resp.data.dedicated || [] - nodetopologiesShared = resp.data.shared || [] - - const response = await axios.get(annotationUrl) - const annotations = response.data?.metadata?.annotations || {} - const uidRange = annotations['openshift.io/sa.scc.uid-range'] - if (uidRange) { - const val = uidRange.split('/')[0] + const isChangeable = isToggleOn('storageClasses', + ) + if (isChangeable && storageClass) { commit('wizard/model$update', { - path: '/spec/openshift/securityContext/runAsUser', - value: val, + path: '/spec/admin/storageClasses/default', + value: storageClass, force: true, }) } - } catch (e) { - console.log(e) } - commit('wizard/model$update', { - path: '/spec/deletionPolicy', - value: getDefault({ getValue, model }, 'deletionPolicy'), - force: true, - }) + function showAlerts() { + // // // // watchDependency('discriminator#/monitoring') + const isMonitorEnabled = getValue(discriminator, '/monitoring') + return ( + isMonitorEnabled && isToggleOn('alert') + ) + } - if (!getValue(model, `/spec/admin/databases/Oracle/mode/toggle`)) { - let defMode = getDefault({ getValue, model }, 'databases/Oracle/mode') || '' - if (defMode === '') { - const arr = getValue(model, '/spec/databases/Oracle/mode/available') || [] - if (arr.length) defMode = arr[0] - } + function onBackupSwitch() { + const isBackupOn = getValue(discriminator, '/backup') commit('wizard/model$update', { - path: '/spec/mode', - value: defMode, + path: '/spec/backup/tool', + value: isBackupOn ? 'KubeStash' : '', force: true, }) } - if (!features.includes('tls')) { + function clearArbiterHidden() { commit('wizard/model$update', { - path: '/spec/admin/tls/default', + path: `/spec/arbiter/enabled`, value: false, force: true, }) - } - if (!features.includes('binding')) { + commit('wizard/model$update', { - path: '/spec/admin/expose/default', + path: `/spec/hidden/enabled`, value: false, force: true, }) } - if (!features.includes('monitoring')) { - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: 'none', - force: true, - }) - } - if (!features.includes('backup')) { - commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, - force: true, - }) + + let placement = [] + let versions = [] + let storageClass = [] + let clusterIssuers = [] + let nodetopologiesShared = [] + let nodetopologiesDedicated = [] + let features = [] + async function initBundle() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + + let db = getValue(model, '/metadata/resource/kind') + db = db.toLowerCase() + let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` + const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` + + try { + const resp = await axios.get(url) + features = resp.data.features || [] + placement = resp.data.placementpolicies || [] + versions = resp.data.versions || [] + storageClass = resp.data.storageclasses || [] + clusterIssuers = resp.data.clusterissuers || [] + nodetopologiesDedicated = resp.data.dedicated || [] + nodetopologiesShared = resp.data.shared || [] + + const response = await axios.get(annotationUrl) + const annotations = response.data?.metadata?.annotations || {} + const uidRange = annotations['openshift.io/sa.scc.uid-range'] + if (uidRange) { + const val = uidRange.split('/')[0] + commit('wizard/model$update', { + path: '/spec/openshift/securityContext/runAsUser', + value: val, + force: true, + }) + } + } catch (e) { + console.log(e) + } + commit('wizard/model$update', { - path: '/spec/backup/tool', - value: '', + path: '/spec/deletionPolicy', + value: getDefault('deletionPolicy'), force: true, }) - } - setDiscriminatorValue('/bundleApiLoaded', true) -} + if (!getValue(model, `/spec/admin/databases/Oracle/mode/toggle`)) { + let defMode = getDefault('databases/Oracle/mode') || '' + if (defMode === '') { + const arr = getValue(model, '/spec/databases/Oracle/mode/available') || [] + if (arr.length) defMode = arr[0] + } + commit('wizard/model$update', { + path: '/spec/mode', + value: defMode, + force: true, + }) + } -function fetchOptions({ model, getValue, commit }, type) { - let kind = getValue(model, '/metadata/resource/kind') + if (!features.includes('tls')) { + commit('wizard/model$update', { + path: '/spec/admin/tls/default', + value: false, + force: true, + }) + } + if (!features.includes('binding')) { + commit('wizard/model$update', { + path: '/spec/admin/expose/default', + value: false, + force: true, + }) + } + if (!features.includes('monitoring')) { + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: 'none', + force: true, + }) + } + if (!features.includes('backup')) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: '', + force: true, + }) + } - let returnArray = [] - if (type === 'clusterTier/placement') { - returnArray = placement - } else if (type === `databases/${kind}/versions`) { - returnArray = versions - } else if (type === 'storageClasses') { - returnArray = storageClass - } else if (type === 'clusterIssuers') { - returnArray = clusterIssuers + setDiscriminatorValue('/bundleApiLoaded', true) } - if (returnArray.length === 1) { - const path = `/spec/admin/${type}/default` - commit('wizard/model$update', { - path: path, - value: returnArray[0], - force: true, - }) - } + function fetchOptions(type) { + let kind = getValue(model, '/metadata/resource/kind') + + let returnArray = [] + if (type === 'clusterTier/placement') { + returnArray = placement + } else if (type === `databases/${kind}/versions`) { + returnArray = versions + } else if (type === 'storageClasses') { + returnArray = storageClass + } else if (type === 'clusterIssuers') { + returnArray = clusterIssuers + } - return returnArray -} + if (returnArray.length === 1) { + const path = `/spec/admin/${type}/default` + commit('wizard/model$update', { + path: path, + value: returnArray[0], + force: true, + }) + } -function getAdminOptions({ getValue, model, watchDependency, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') + return returnArray + } - const options = getValue(model, `/spec/admin/${type}/available`) || [] + function getAdminOptions(type) { + // // // // watchDependency('discriminator#/bundleApiLoaded') - if (options.length === 0) { - return fetchOptions({ model, getValue, commit }, type) - } - if (type.endsWith('/mode')) { - return ( - options?.map((item) => ({ - description: modeDetails[item]?.description || '', - text: modeDetails[item]?.text || '', - value: item, - })) || [] - ) - } - return options -} + const options = getValue(model, `/spec/admin/${type}/available`) || [] -function checkIfFeatureOn({ getValue, model }, type) { - let val = getValue(model, `/spec/admin/${type}/toggle`) - if (type === 'backup' || type === 'archiver') { - val = getValue(model, `/spec/admin/${type}/enable/toggle`) + if (options.length === 0) { + return fetchOptions(type) + } + if (type.endsWith('/mode')) { + return ( + options?.map((item) => ({ + description: modeDetails[item]?.description || '', + text: modeDetails[item]?.text || '', + value: item, + })) || [] + ) + } + return options } - const backupVal = getValue(model, '/spec/backup/tool') - if (type === 'backup') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } else if (type === 'tls') { - return features.includes('tls') && val - } else if (type === 'expose') { - return features.includes('binding') && val - } else if (type === 'monitoring') { - return features.includes('monitoring') && val - } else if (type === 'archiver') { - return features.includes('backup') && backupVal === 'KubeStash' && val + function checkIfFeatureOn(type) { + let val = getValue(model, `/spec/admin/${type}/toggle`) + if (type === 'backup' || type === 'archiver') { + val = getValue(model, `/spec/admin/${type}/enable/toggle`) + } + const backupVal = getValue(model, '/spec/backup/tool') + + if (type === 'backup') { + return features.includes('backup') && backupVal === 'KubeStash' && val + } else if (type === 'tls') { + return features.includes('tls') && val + } else if (type === 'expose') { + return features.includes('binding') && val + } else if (type === 'monitoring') { + return features.includes('monitoring') && val + } else if (type === 'archiver') { + return features.includes('backup') && backupVal === 'KubeStash' && val + } } -} -function isToggleOn({ getValue, model, discriminator, watchDependency }, type) { - watchDependency('discriminator#/bundleApiLoaded') - watchDependency('model#/spec/admin/deployment/default') - const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') - let deploymentType = getValue(model, `/spec/admin/deployment/default`) - if ( - type === 'tls' || - type === 'backup' || - type === 'expose' || - type === 'monitoring' || - type === 'archiver' - ) { - return checkIfFeatureOn({ getValue, model }, type) - } else if ( - type === 'clusterTier' || - type === 'clusterTier/placement' || - type === 'clusterTier/nodeTopology' - ) { - if (deploymentType === 'Dedicated' && bundleApiLoaded) return true - else return false - } else if (type === 'deployment') { - const deploymentType = getValue(model, '/spec/admin/deployment/default') - if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { - commit('wizard/model$update', { - path: '/spec/admin/deployment/default', - value: 'Shared', - force: true, - }) - } - return ( - getValue(model, `/spec/admin/${type}/toggle`) && - nodetopologiesDedicated.length && - bundleApiLoaded - ) - } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded -} + function isToggleOn(type) { + // // // // watchDependency('discriminator#/bundleApiLoaded') + // // // // watchDependency('model#/spec/admin/deployment/default') + const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') + let deploymentType = getValue(model, `/spec/admin/deployment/default`) + if ( + type === 'tls' || + type === 'backup' || + type === 'expose' || + type === 'monitoring' || + type === 'archiver' + ) { + return checkIfFeatureOn(type) + } else if ( + type === 'clusterTier' || + type === 'clusterTier/placement' || + type === 'clusterTier/nodeTopology' + ) { + if (deploymentType === 'Dedicated' && bundleApiLoaded) return true + else return false + } else if (type === 'deployment') { + const deploymentType = getValue(model, '/spec/admin/deployment/default') + if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + commit('wizard/model$update', { + path: '/spec/admin/deployment/default', + value: 'Shared', + force: true, + }) + } + return ( + getValue(model, `/spec/admin/${type}/toggle`) && + nodetopologiesDedicated.length && + bundleApiLoaded + ) + } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded + } -async function getNodeTopology({ model, getValue, axios, storeGet, watchDependency }) { - watchDependency('model#/spec/admin/deployment/default') - watchDependency('model#/spec/admin/clusterTier/default') - const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' - const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' - let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + async function getNodeTopology() { + // // // // watchDependency('model#/spec/admin/deployment/default') + // // // // watchDependency('model#/spec/admin/clusterTier/default') + const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' + const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' + let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] - const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' - if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared - else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared + else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated - const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) - return filteredList -} + const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) + return filteredList + } -function filterNodeTopology(list, tier, provider) { - // first filter the list from value that exists from the filtered list got from API - const filteredlist = list + function filterNodeTopology(list, tier, provider) { + // first filter the list from value that exists from the filtered list got from API + const filteredlist = list - // filter the list based on clusterTier - if (provider === 'EKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('c') - else if (tier === 'MemoryOptimized') return item.startsWith('r') - else return !item.startsWith('c') && !item.startsWith('r') - }) - } else if (provider === 'AKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - else - return ( - !(item.startsWith('f') || item.startsWith('fx')) && - !( + // filter the list based on clusterTier + if (provider === 'EKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('c') + else if (tier === 'MemoryOptimized') return item.startsWith('r') + else return !item.startsWith('c') && !item.startsWith('r') + }) + } else if (provider === 'AKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('e') || item.startsWith('eb') || item.startsWith('ec') || item.startsWith('m') || item.startsWith('d') ) - ) - }) - } else if (provider === 'GKE') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') - return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - else - return ( - !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && - !( + else + return ( + !(item.startsWith('f') || item.startsWith('fx')) && + !( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + ) + }) + } else if (provider === 'GKE') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') + return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('x4') || item.startsWith('m1') || item.startsWith('m2') || item.startsWith('m3') ) - ) - }) - } else return filteredlist -} + else + return ( + !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && + !( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + ) + }) + } else return filteredlist + } -function returnFalse() { - return false -} + function returnFalse() { + return false + } -function isConfigDatabaseOn({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configDatabase') - return getValue(discriminator, '/configDatabase') -} -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} -function showStorageSizeField({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - const validType = [] - return !validType.includes(modelPathValue) -} -function showHidden({ watchDependency, model, getValue }) { - watchDependency('model#/spec/hidden/enabled') - const isHiddenOn = getValue(model, '/spec/hidden/enabled') || '' - const notStandalone = notEqualToDatabaseMode({ model, getValue, watchDependency }, 'Standalone') - return isHiddenOn && notStandalone -} -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} -function showArbiter({ watchDependency, model, getValue }) { - watchDependency('model#/spec/arbiter/enabled') - const isArbiterOn = getValue(model, '/spec/arbiter/enabled') || '' - const notStandalone = notEqualToDatabaseMode({ model, getValue, watchDependency }, 'Standalone') - return isArbiterOn && notStandalone -} -function clearConfiguration({ discriminator, getValue, commit }) { - const configOn = getValue(discriminator, '/configDatabase') + function isConfigDatabaseOn() { + // // // // watchDependency('discriminator#/configDatabase') + return getValue(discriminator, '/configDatabase') + } + function notEqualToDatabaseMode(mode) { + const modelPathValue = getValue(model, '/spec/mode') + // // // // watchDependency('model#/spec/mode') + return modelPathValue && modelPathValue !== mode + } + function showStorageSizeField() { + const modelPathValue = getValue(model, '/spec/mode') + // // // // watchDependency('model#/spec/mode') + const validType = [] + return !validType.includes(modelPathValue) + } + function showHidden() { + // // // // watchDependency('model#/spec/hidden/enabled') + const isHiddenOn = getValue(model, '/spec/hidden/enabled') || '' + const notStandalone = notEqualToDatabaseMode('Standalone') + return isHiddenOn && notStandalone + } + function notEqualToDatabaseMode(mode) { + const modelPathValue = getValue(model, '/spec/mode') + // // // // watchDependency('model#/spec/mode') + return modelPathValue && modelPathValue !== mode + } + function showArbiter() { + // // // // watchDependency('model#/spec/arbiter/enabled') + const isArbiterOn = getValue(model, '/spec/arbiter/enabled') || '' + const notStandalone = notEqualToDatabaseMode('Standalone') + return isArbiterOn && notStandalone + } + function clearConfiguration() { + const configOn = getValue(discriminator, '/configDatabase') - if (!configOn) { - commit('wizard/model$delete', '/spec/configuration') + if (!configOn) { + commit('wizard/model$delete', '/spec/configuration') + } } -} -function showIssuer({ model, getValue, watchDependency, discriminator }) { - watchDependency('model#/spec/admin/tls/default') - const isTlsEnabled = getValue(model, '/spec/admin/tls/default') - const isIssuerToggleEnabled = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'clusterIssuers', - ) - return isTlsEnabled && isIssuerToggleEnabled -} -function onAuthChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/authSecret/password', - value: '', - force: true, - }) -} -function setMonitoring({ getValue, model }) { - const agent = getValue(model, '/spec/admin/monitoring/agent') || '' - return !!agent -} + function showIssuer() { + // // // // watchDependency('model#/spec/admin/tls/default') + const isTlsEnabled = getValue(model, '/spec/admin/tls/default') + const isIssuerToggleEnabled = isToggleOn('clusterIssuers', + ) + return isTlsEnabled && isIssuerToggleEnabled + } + function onAuthChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/spec/authSecret/password', + value: '', + force: true, + }) + } + function setMonitoring() { + const agent = getValue(model, '/spec/admin/monitoring/agent') || '' + return !!agent + } -function setBackup({ model, getValue }) { - const backup = getValue(model, '/spec/backup/tool') - const val = getValue(model, '/spec/admin/backup/enable/default') - return backup === 'KubeStash' && features.includes('backup') && val -} + function setBackup() { + const backup = getValue(model, '/spec/backup/tool') + const val = getValue(model, '/spec/admin/backup/enable/default') + return backup === 'KubeStash' && features.includes('backup') && val + } -function isMachineCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue === 'custom' -} + function isMachineCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue === 'custom' + } -function isMachineNotCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue !== 'custom' && !!modelPathValue -} -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], + function isMachineNotCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue !== 'custom' && !!modelPathValue + } + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, }, - }, - ) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] + ) + if (resp.data?.status?.projects) { + const projects = resp.data?.status?.projects + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } + } catch (e) { + console.log(e) } - } catch (e) { - console.log(e) + return [] } - return [] -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } -function updateAlertValue({ commit, model, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const alert = isMonitorEnabled ? 'warning' : 'none' - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: alert, - force: true, - }) - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} + function updateAlertValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const alert = isMonitorEnabled ? 'warning' : 'none' + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: alert, + force: true, + }) + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: agent, + force: true, + }) + } -function setLimits({ model, getValue, commit, watchDependency }, resource, type) { - const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' - watchDependency(`model#${path}`) - const selectedMachine = getValue(model, path) || 'custom' - const reqCommitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - const comparePath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - - const resourceValue = getValue(model, comparePath) - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - - let cpu = '', - memory = '' - if (available.length && selectedMachine !== 'custom') { - const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) - if (machineData) { - cpu = machineData.limits.cpu - memory = machineData.limits.memory + function setLimits(resource, type) { + const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' + // watchDependency(`model#${path}`) + const selectedMachine = getValue(model, path) || 'custom' + const reqCommitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + const comparePath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + + const resourceValue = getValue(model, comparePath) + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + let cpu = '', + memory = '' + if (available.length && selectedMachine !== 'custom') { + const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) + if (machineData) { + cpu = machineData.limits.cpu + memory = machineData.limits.memory + } + } else { + if (selectedMachine === 'custom') { + cpu = resourceValue + memory = resourceValue + } else { + cpu = machines[selectedMachine].resources.limits.cpu + memory = machines[selectedMachine].resources.limits.memory + } } - } else { - if (selectedMachine === 'custom') { - cpu = resourceValue - memory = resourceValue + + if (resource === 'memory') { + commit('wizard/model$update', { + path: reqCommitPath, + value: memory, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: memory, + force: true, + }) + return memory } else { - cpu = machines[selectedMachine].resources.limits.cpu - memory = machines[selectedMachine].resources.limits.memory + commit('wizard/model$update', { + path: reqCommitPath, + value: cpu, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: cpu, + force: true, + }) + return cpu } } - if (resource === 'memory') { + function setRequests(resource, type) { + const modelPath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` commit('wizard/model$update', { - path: reqCommitPath, - value: memory, + path: commitPath, + value: val, force: true, }) + } + + function toggleTls() { + let modelPathValue = getValue(model, '/spec/mode') commit('wizard/model$update', { - path: comparePath, - value: memory, - force: true, - }) - return memory - } else { - commit('wizard/model$update', { - path: reqCommitPath, - value: cpu, + path: '/spec/admin/tls/default', + value: modelPathValue !== 'Standalone', force: true, }) commit('wizard/model$update', { - path: comparePath, - value: cpu, + path: '/spec/admin/tls/toggle', + value: modelPathValue !== 'Standalone', force: true, }) - return cpu } -} -function setRequests({ getValue, model, commit }, resource, type) { - const modelPath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - const val = getValue(model, modelPath) - commitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - commit('wizard/model$update', { - path: commitPath, - value: val, - force: true, - }) -} - -function toggleTls({ commit, model, getValue }) { - let modelPathValue = getValue(model, '/spec/mode') - commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: modelPathValue !== 'Standalone', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/admin/tls/toggle', - value: modelPathValue !== 'Standalone', - force: true, - }) -} + function showAdditionalSettings() { + // // // // watchDependency('discriminator#/bundleApiLoaded') + return features.length + } -function showAdditionalSettings({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return features.length -} + function getDefault(type) { + const val = getValue(model, `/spec/admin/${type}/default`) || '' + return val + } -function getDefault({ getValue, model }, type) { - const val = getValue(model, `/spec/admin/${type}/default`) || '' - return val -} + async function getReferSecrets() { + const referSecret = getValue(discriminator, '/referSecret') + if (!referSecret) { + return [] + } -function isConfigAvailable({ getValue, model }) { - const val = getValue(model, '/spec/configuration') - return val !== '' -} + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/metadata/release/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` -async function getReferSecrets({ getValue, model, storeGet, axios, discriminator }) { - const referSecret = getValue(discriminator, '/referSecret') - if (!referSecret) { - return [] + const options = [] + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + return options } - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/metadata/release/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - - const options = [] - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) - } catch (e) { - console.log(e) + function showAuthPasswordField() { + const modelPathValue = getValue(discriminator, '/referSecret') + // // // // watchDependency('discriminator#/referSecret') + return !modelPathValue && showReferSecret() } - return options -} -function showAuthPasswordField({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} - -function showSecretDropdown({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} - -function showReferSecret({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/createAuthSecret') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue -} - -function getDefaultValue({ getValue, model }, path) { - const val = getValue(model, `/${path}`) || '' - return val -} + function showSecretDropdown() { + const modelPathValue = getValue(discriminator, '/referSecret') + // // // // watchDependency('discriminator#/referSecret') + return !!modelPathValue && showReferSecret() + } -function showReferSecretSwitch({ model, getValue, watchDependency, discriminator }) { - const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showReferSecret() { + const modelPathValue = getValue(discriminator, '/createAuthSecret') + // // // // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue + } -function onReferSecretChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) -} + function getDefaultValue(path) { + const val = getValue(model, `/${path}`) || '' + return val + } -function showArchiver({ watchDependency, getValue, model, commit }) { - watchDependency('model#/spec/mode') - const dbmode = getValue(model, '/spec/mode') + function showReferSecretSwitch() { + const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') + // // // // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue && showReferSecret() + } - if (dbmode === 'Standalone') { + function onReferSecretChange() { commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, + path: '/spec/authSecret/name', + value: '', force: true, }) - return false } - return checkIfFeatureOn({ getValue, model }, 'archiver') -} -async function checkHostnameOrIP({ commit, model, getValue }) { - const tls = getValue(model, '/spec/admin/tls/default') - const expose = getValue(model, '/spec/admin/expose/default') - if (tls && expose) { - if (hostName) { + function showArchiver() { + // // // // watchDependency('model#/spec/mode') + const dbmode = getValue(model, '/spec/mode') + + if (dbmode === 'Standalone') { commit('wizard/model$update', { - path: '/spec/hostName', - value: hostName, + path: '/spec/admin/archiver/enable/default', + value: false, force: true, }) + return false + } + return checkIfFeatureOn('archiver') + } + + function checkHostnameOrIP() { + const tls = getValue(model, '/spec/admin/tls/default') + const expose = getValue(model, '/spec/admin/expose/default') + if (tls && expose) { + if (hostName) { + commit('wizard/model$update', { + path: '/spec/hostName', + value: hostName, + force: true, + }) + } else { + commit('wizard/model$update', { + path: '/spec/ip', + value: ip, + force: true, + }) + } } else { + commit('wizard/model$update', { + path: '/spec/hostName', + value: '', + force: true, + }) commit('wizard/model$update', { path: '/spec/ip', - value: ip, + value: '', force: true, }) } - } else { - commit('wizard/model$update', { - path: '/spec/hostName', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/ip', - value: '', - force: true, - }) } -} -function showArchiverAlert({ watchDependency, model, getValue, commit }) { - watchDependency('model#/spec/admin/storageClasses/default') + function onArchiverChange() { + const isArchiverOn = getValue(model, '/spec/admin/archiver/enable/default') + const stClass = getValue(model, '/spec/admin/storageClasses/default') + const found = archiverMap.find((item) => item.storageClass === stClass) - const mode = getValue(model, '/spec/mode') - if (mode === 'Standalone') return false + if (isArchiverOn && found?.annotation) + commit('wizard/model$update', { + path: '/spec/archiverName', + value: found.annotation, + force: true, + }) + else + commit('wizard/model$update', { + path: '/spec/archiverName', + value: '', + force: true, + }) + } - const stClass = getValue(model, '/spec/admin/storageClasses/default') - const found = archiverMap.find((item) => item.storageClass === stClass) - const show = !found?.annotation + function showArchiverAlert() { + // // // // watchDependency('model#/spec/admin/storageClasses/default') - // toggle archiver to false when storageClass annotation not found - if (show) - commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, - force: true, - }) - else onArchiverChange({ model, getValue, commit }) + const mode = getValue(model, '/spec/mode') + if (mode === 'Standalone') return false - return show -} + const stClass = getValue(model, '/spec/admin/storageClasses/default') + const found = archiverMap.find((item) => item.storageClass === stClass) + const show = !found?.annotation + + // toggle archiver to false when storageClass annotation not found + if (show) + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + else onArchiverChange() + + return show + } + + + return { + showReferSecretSwitch, + onReferSecretChange, + getDefaultValue, + isRancherManaged, + showSecretDropdown, + showReferSecret, + getReferSecrets, + initBundle, + returnFalse, + setLimits, + setRequests, + toggleTls, + getNamespaces, + updateAlertValue, + getAdminOptions, + isToggleOn, + showAlerts, + getNodeTopology, + clearArbiterHidden, + showHidden, + isConfigDatabaseOn, + notEqualToDatabaseMode, + filterNodeTopology, + onAuthChange, + setMonitoring, + isMachineNotCustom, + isMachineCustom, + showIssuer, + showArbiter, + clearConfiguration, + showStorageSizeField, + onBackupSwitch, + isVariantAvailable, + fetchJsons, + showAuthPasswordField, + isEqualToModelPathValue, + showAuthSecretField, + getResources, + getMySqlVersions, + onCreateAuthSecretChange, + getSecrets, + getMachineListForOptions, + setMachineToCustom, + updateAgentValue, + getCreateNameSpaceUrl, + ifCapiProviderIsNotEmpty, + ifDedicated, + dedicatedOnChange, + ifZones, + zonesOnChange, + getZones, + getSKU, + showMultiselectZone, + showSelectZone, + setStorageClass, + setReplicaNumber, + setRouterNumber, + setBackup, + showAdditionalSettings, + getDefault, + showArchiver, + checkHostnameOrIP, + onArchiverChange, + showArchiverAlert, + } -return { - showReferSecretSwitch, - onReferSecretChange, - getDefaultValue, - isRancherManaged, - showSecretDropdown, - showReferSecret, - getReferSecrets, - isConfigAvailable, - initBundle, - returnFalse, - setLimits, - setRequests, - toggleTls, - getNamespaces, - updateAlertValue, - getAdminOptions, - isToggleOn, - showAlerts, - getNodeTopology, - clearArbiterHidden, - showHidden, - isConfigDatabaseOn, - notEqualToDatabaseMode, - filterNodeTopology, - onAuthChange, - setMonitoring, - isMachineNotCustom, - isMachineCustom, - showIssuer, - showArbiter, - clearConfiguration, - showStorageSizeField, - onBackupSwitch, - isVariantAvailable, - fetchJsons, - showAuthPasswordField, - isEqualToModelPathValue, - showAuthSecretField, - getResources, - getMySqlVersions, - onCreateAuthSecretChange, - getSecrets, - getMachineListForOptions, - setMachineToCustom, - updateAgentValue, - getCreateNameSpaceUrl, - ifCapiProviderIsNotEmpty, - ifDedicated, - dedicatedOnChange, - ifZones, - zonesOnChange, - getZones, - getSKU, - showMultiselectZone, - showSelectZone, - setStorageClass, - setReplicaNumber, - setRouterNumber, - setBackup, - showAdditionalSettings, - getDefault, - showArchiver, - checkHostnameOrIP, - showArchiverAlert, } diff --git a/charts/kubedbcom-perconaxtradb-editor-options/ui/create-ui.yaml b/charts/kubedbcom-perconaxtradb-editor-options/ui/create-ui.yaml index 056666cbab..339f143b76 100644 --- a/charts/kubedbcom-perconaxtradb-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-perconaxtradb-editor-options/ui/create-ui.yaml @@ -1,294 +1,285 @@ -steps: -- form: - discriminator: - bundleApiLoaded: - default: false - type: boolean +step: +- type: single-step-form + loader: initBundle + elements: + - type: label-element + label: '' + subtitle: Select the PerconaXtraDB version you want to deploy on Kubernetes. The chosen version determines the PerconaXtraDB engine features, compatibility, and runtime behavior of your database cluster. + - type: horizontal-layout + showLabels: true elements: - - computed: initBundle - if: returnFalse - type: label-element - - disableUnselect: true - fetch: getAdminOptions|databases/PerconaXtraDB/versions - if: isToggleOn|databases/PerconaXtraDB/versions - label: - text: labels.database.version - schema: - $ref: schema#/properties/spec/properties/admin/properties/databases/properties/PerconaXtraDB/properties/versions/properties/default - type: select - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/replicas - type: input - - elements: - - computed: setMachineToCustom - customClass: mt-10 - fetch: getMachineListForOptions - label: - text: labels.machine - schema: - $ref: schema#/properties/spec/properties/podResources/properties/machine + - disableUnselect: true + loader: getAdminOptions|databases/PerconaXtraDB/versions + if: + type: function + name: isToggleOn|databases/PerconaXtraDB/versions + label: Database Version + schema: schema/properties/spec/properties/admin/properties/databases/properties/PerconaXtraDB/properties/versions/properties/default type: select - - computed: setLimits|cpu - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.cpu - onChange: setRequests|cpu - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - label: Replicaset Number + schema: schema/properties/spec/properties/replicas type: input - - computed: setLimits|memory - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.memory - onChange: setRequests|memory - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - label: - text: labels.machine_profile - show_label: true - type: single-step-form - - fetch: getAdminOptions|storageClasses - if: isToggleOn|storageClasses - label: - text: labels.storage.class - schema: - $ref: schema#/properties/spec/properties/admin/properties/storageClasses/properties/default + - elements: + - type: label-element + label: '' + subtitle: Select a machine profile to allocate CPU and memory resources for your database cluster. Choose 'custom' to manually specify resource requirements or select a predefined profile. + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: CPU + loader: setLimits|cpu + watcher: + func: setRequests|cpu + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: Memory + loader: setLimits|memory + watcher: + func: setRequests|memory + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + label: Machine profile + showLabels: true + type: block-layout + - elements: + - type: horizontal-layout + showLabels: true + elements: + - loader: getAdminOptions|storageClasses + if: + type: function + name: isToggleOn|storageClasses + label: Storage Class + schema: schema/properties/spec/properties/admin/properties/storageClasses/properties/default + type: select + - label: Storage Size + schema: schema/properties/spec/properties/persistence/properties/size + type: input + type: block-layout + - description: Configure Credentials, Deployment Mode etc. + elements: + - elements: + - type: label-element + label: '' + subtitle: Add custom labels and annotations to your database resources for organization, monitoring, and integration with other Kubernetes tools and services. + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/annotations + label: Labels & Annotations + showLabels: true + hideBlock: true + type: block-layout + - init: + type: func + value: getDefault|deletionPolicy + customClass: mt-20 + if: + type: function + name: isToggleOn|deletionPolicy + label: Deletion Policy + watcher: + func: setStorageClass + paths: + - schema/properties/spec/properties/deletionPolicy + options: + - description: options.deletionPolicy.delete.description + text: Delete + value: Delete + - description: options.deletionPolicy.halt.description + text: Halt + value: Halt + - description: options.deletionPolicy.wipeOut.description + text: WipeOut + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: DoNotTerminate + value: DoNotTerminate + schema: schema/properties/spec/properties/deletionPolicy + type: select + - if: + type: function + name: getDefaultValue|spec/admin/authCredential/customize + label: Provide Authentication Credentials? + watcher: + func: onAuthChange + paths: + - temp/createAuthSecret + schema: temp/createAuthSecret + type: switch + - if: + type: function + name: showReferSecretSwitch + label: Refer existing Secret? + watcher: + func: onReferSecretChange + paths: + - temp/referSecret + schema: temp/referSecret + type: switch + - loader: getReferSecrets + if: + type: function + name: showSecretDropdown + label: Secret + schema: schema/properties/spec/properties/authSecret/properties/name + type: select + - if: + type: function + name: showReferSecret + label: Password + schema: schema/properties/spec/properties/authSecret/properties/password + type: input + - if: + type: function + name: getDefaultValue|spec/admin/customConfiguration + label: Configure Database? + watcher: + func: clearConfiguration + paths: + - temp/configDatabase + schema: temp/configDatabase + type: switch + - if: + type: function + name: isConfigDatabaseOn + label: Configuration + schema: schema/properties/spec/properties/configuration + type: textarea + - if: + type: function + name: isToggleOn|deployment + label: Deployment + options: + - description: shared + text: Shared + value: Shared + - description: Dedicated + text: Dedicated + value: Dedicated + schema: schema/properties/spec/properties/admin/properties/deployment/properties/default + type: radio + - if: + type: function + name: isToggleOn|clusterTier + isHorizontal: true + label: ClusterTier + options: + - text: General Purpose + value: GeneralPurpose + - text: Memory Optimized + value: MemoryOptimized + - text: CPU Optimized + value: CPUOptimized + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/default + type: radio + - disableUnselect: true + loader: getAdminOptions|clusterTier/placement + if: + type: function + name: isToggleOn|clusterTier/placement + label: labels.placement + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + type: select + - disableUnselect: true + loader: getNodeTopology + if: + type: function + name: isToggleOn|clusterTier/nodeTopology + label: NodeTopology + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default type: select + hideBlock: true + label: Advanced Configuration + showLabels: true + type: block-layout + - description: Enable Backup, Monitoring, TLS etc. + elements: - elements: - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/persistence/properties/size - type: input - type: single-step-form - - accordion: true - description: - text: Configure Credentials, Deployment Mode etc. - discriminator: - configDatabase: - default: false - type: boolean - createAuthSecret: - default: false - type: boolean - referSecret: - default: false - type: boolean - elements: - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties - type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties - type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - computed: getDefault|deletionPolicy - customClass: mt-20 - if: isToggleOn|deletionPolicy - 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/spec/properties/deletionPolicy - type: select - - if: getDefaultValue|spec/admin/authCredential/customize - label: - text: Provide Authentication Credentials? - onChange: onAuthChange - schema: - $ref: discriminator#/createAuthSecret - type: switch - - if: showReferSecretSwitch - label: - text: Refer existing Secret? - onChange: onReferSecretChange - schema: - $ref: discriminator#/referSecret - type: switch - - fetch: getReferSecrets - if: showSecretDropdown - label: - text: Secret - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/name - type: select - - if: showReferSecret - label: - text: labels.password - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/password - type: input - - computed: isConfigAvailable - if: getDefaultValue|spec/admin/customConfiguration - label: - text: Configure Database? - onChange: clearConfiguration - schema: - $ref: discriminator#/configDatabase + - init: + type: func + value: setMonitoring + label: Enable Monitoring + watcher: + func: updateAlertValue + paths: + - temp/monitoring + schema: temp/monitoring type: switch - - if: isConfigDatabaseOn - label: - text: Configuration - schema: - $ref: schema#/properties/spec/properties/configuration - type: editor - - hasDescription: true - if: isToggleOn|deployment - label: - text: labels.deployment.name + - customClass: mt-10 + if: + type: function + name: showAlerts + label: Alert Options options: - - description: labels.deployment.shared - text: Shared - value: Shared - - description: labels.deployment.dedicated - text: Dedicated - value: Dedicated - schema: - $ref: schema#/properties/spec/properties/admin/properties/deployment/properties/default - type: radio - - if: isToggleOn|clusterTier - isHorizontal: true - label: - text: labels.clusterTier - options: - - text: General Purpose - value: GeneralPurpose - - text: Memory Optimized - value: MemoryOptimized - - text: CPU Optimized - value: CPUOptimized - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/default - type: radio - - disableUnselect: true - fetch: getAdminOptions|clusterTier/placement - if: isToggleOn|clusterTier/placement - label: - text: labels.placement - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + - text: None + value: none + - text: Critical + value: critical + - text: Warning + value: warning + - text: Info + value: info + schema: schema/properties/form/properties/alert/properties/enabled type: select - - disableUnselect: true - fetch: getNodeTopology - if: isToggleOn|clusterTier/nodeTopology - label: - text: labels.nodeTopology - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + if: + type: function + name: isToggleOn|monitoring + type: block-layout + - elements: + - if: + type: function + name: isToggleOn|tls + label: Enable TLS? + schema: schema/properties/spec/properties/admin/properties/tls/properties/default + type: switch + - loader: getAdminOptions|clusterIssuers + if: + type: function + name: showIssuer + label: Cluster Issuers + validation: + type: required + schema: schema/properties/spec/properties/admin/properties/clusterIssuers/properties/default type: select - hideForm: true - label: - text: Advanced Configuration - show_label: true - type: single-step-form - - accordion: true - description: - text: Enable Backup, Monitoring, TLS etc. - discriminator: - backup: - default: false - type: boolean - elements: - - discriminator: - monitoring: - default: false - type: boolean - elements: - - computed: setMonitoring - label: - text: labels.enable_monitoring - onChange: updateAlertValue - schema: - $ref: discriminator#/monitoring - type: switch - - customClass: mt-10 - if: showAlerts - label: - text: labels.alert.options - options: - - text: None - value: none - - text: Critical - value: critical - - text: Warning - value: warning - - text: Info - value: info - schema: - $ref: schema#/properties/form/properties/alert/properties/enabled - sortable: true - type: select - if: isToggleOn|monitoring - type: single-step-form - - elements: - - if: isToggleOn|tls - label: - text: Enable TLS? - schema: - $ref: schema#/properties/spec/properties/admin/properties/tls/properties/default - type: switch - - fetch: getAdminOptions|clusterIssuers - if: showIssuer - label: - text: labels.clusterIssuers - required: true - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterIssuers/properties/default - type: select - type: single-step-form - if: showAdditionalSettings - label: - text: Additional Options - show_label: true - type: single-step-form - type: single-step-form + type: block-layout + if: + type: function + name: showAdditionalSettings + label: Additional Options + showLabels: true + type: block-layout id: options - title: steps.0.label + # title: steps.0.label type: multi-step-form diff --git a/charts/kubedbcom-perconaxtradb-editor-options/ui/functions.js b/charts/kubedbcom-perconaxtradb-editor-options/ui/functions.js index 3c13475433..c787866f30 100644 --- a/charts/kubedbcom-perconaxtradb-editor-options/ui/functions.js +++ b/charts/kubedbcom-perconaxtradb-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -304,1053 +306,1097 @@ const machineList = [ 'db.r.24xlarge', ] -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) + + setDiscriminatorValue('bundleApiLoaded', false) + setDiscriminatorValue('configDatabase', false) + setDiscriminatorValue('createAuthSecret', false) + setDiscriminatorValue('referSecret', false) + setDiscriminatorValue('backup', false) + setDiscriminatorValue('monitoring', false) + + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, }, - }, - ) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] + ) + if (resp.data?.status?.projects) { + const projects = resp.data?.status?.projects + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } + } catch (e) { + console.log(e) } - } catch (e) { - console.log(e) + return [] } - return [] -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } -function getMachineListForOptions({ model, getValue }) { - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') let array = [] + function getMachineListForOptions() { + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') - if (available.length) { - array = available.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - else { - let subText = '', - text = '' - const machineData = machinesFromPreset.find((val) => val.id === machine) - if (machineData) { - subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` - text = machineData.name ? machineData.name : machineData.id - } - return { text, subText, value: machine } - } - }) - } else { - array = machineList - .map((machine) => { + if (available.length) { + array = available.map((machine) => { if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + else { + let subText = '', + text = '' + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + text = machineData.name ? machineData.name : machineData.id + } + return { text, subText, value: machine } + } }) - .filter((val) => !!val) + } else { + array = machineList + .map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { text, subText, value: machine } + }) + .filter((val) => !!val) + } + return array } - return array -} -function setLimits({ model, getValue, commit, watchDependency }, resource, type) { - const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' - watchDependency(`model#${path}`) - const selectedMachine = getValue(model, path) || 'custom' - const reqCommitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - const comparePath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - - const resourceValue = getValue(model, comparePath) - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - - let cpu = '', - memory = '' - if (available.length && selectedMachine !== 'custom') { - const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) - if (machineData) { - cpu = machineData.limits.cpu - memory = machineData.limits.memory + function setLimits(resource, type) { + const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' + // watchDependency(`model#${path}`) + const selectedMachine = getValue(model, path) || 'custom' + const reqCommitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + const comparePath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + + const resourceValue = getValue(model, comparePath) + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + let cpu = '', + memory = '' + if (available.length && selectedMachine !== 'custom') { + const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) + if (machineData) { + cpu = machineData.limits.cpu + memory = machineData.limits.memory + } + } else { + if (selectedMachine === 'custom') { + cpu = resourceValue + memory = resourceValue + } else { + cpu = machines[selectedMachine].resources.limits.cpu + memory = machines[selectedMachine].resources.limits.memory + } } - } else { - if (selectedMachine === 'custom') { - cpu = resourceValue - memory = resourceValue + + if (resource === 'memory') { + commit('wizard/model$update', { + path: reqCommitPath, + value: memory, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: memory, + force: true, + }) + return memory } else { - cpu = machines[selectedMachine].resources.limits.cpu - memory = machines[selectedMachine].resources.limits.memory + commit('wizard/model$update', { + path: reqCommitPath, + value: cpu, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: cpu, + force: true, + }) + return cpu } } - if (resource === 'memory') { + function setRequests(resource, type) { + const modelPath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + + const fullpath = `/spec/podResources/machine` + const modelPathValue = getValue(model, fullpath) + commit('wizard/model$update', { - path: reqCommitPath, - value: memory, + path: commitPath, + value: val, force: true, }) - commit('wizard/model$update', { - path: comparePath, - value: memory, - force: true, + + if (modelPathValue === 'custom') { + return + } + let commitCpuMemory, ModelPathValue + if (resource && type) { + const fullPath = `/spec/${type}/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/${type}/podResources/resources/requests/${resource}` + } else { + const fullPath = `/spec/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/podResources/resources/requests/${resource}` + } + let cpuMemoryValue + array.forEach((item) => { + if (item.value === ModelPathValue) { + // Parse subText like "CPU: 2, Memory: 2Gi" + const subText = item.subText || '' + if (resource === 'cpu') { + // Extract CPU value + const cpuMatch = subText.match(/CPU:\s*([^,]+)/) + cpuMemoryValue = cpuMatch ? cpuMatch[1].trim() : '' + } else if (resource === 'memory') { + // Extract Memory value + const memoryMatch = subText.match(/Memory:\s*(.+)/) + cpuMemoryValue = memoryMatch ? memoryMatch[1].trim() : '' + } + } }) - return memory - } else { commit('wizard/model$update', { - path: reqCommitPath, - value: cpu, + path: commitCpuMemory, + value: cpuMemoryValue, force: true, }) + return cpuMemoryValue + } + + function setRequests(resource) { + const modelPath = `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = `/spec/podResources/resources/limits/${resource}` commit('wizard/model$update', { - path: comparePath, - value: cpu, + path: commitPath, + value: val, force: true, }) - return cpu } -} - -function setRequests({ getValue, model, commit }, resource) { - const modelPath = `/spec/podResources/resources/requests/${resource}` - const val = getValue(model, modelPath) - commitPath = `/spec/podResources/resources/limits/${resource}` - commit('wizard/model$update', { - path: commitPath, - value: val, - force: true, - }) -} -function setMachineToCustom({ getValue, model }) { - const machine = getValue(model, '/spec/admin/machineProfiles/default') - return machine || 'custom' -} + function setMachineToCustom() { + const machine = getValue(model, '/spec/admin/machineProfiles/default') + return machine || 'custom' + } -function isMachineCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue === 'custom' -} + function isMachineCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue === 'custom' + } -function isMachineNotCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue !== 'custom' && !!modelPathValue -} + function isMachineNotCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue !== 'custom' && !!modelPathValue + } -function showMonitoringSection({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/monitoringEnabledStatus') - return !!getValue(discriminator, '/monitoringEnabledStatus') -} + function showMonitoringSection() { + // watchDependency('discriminator#/monitoringEnabledStatus') + return !!getValue(discriminator, '/monitoringEnabledStatus') + } -function setMonitoringStatus({ model, getValue }) { - const status = getValue(model, '/spec/monitoring/agent') - return !!status -} + function setMonitoringStatus() { + const status = getValue(model, '/spec/monitoring/agent') + return !!status + } -function updateAlertValue({ commit, model, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const alert = isMonitorEnabled ? 'warning' : 'none' - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: alert, - force: true, - }) - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} + function updateAlertValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const alert = isMonitorEnabled ? 'warning' : 'none' + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: alert, + force: true, + }) + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: agent, + force: true, + }) + } -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function getCreateNameSpaceUrl() { + 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + const domain = storeGet('/domain') || '' + if (domain.includes('bb.test')) { + return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } } -} -const ifCapiProviderIsNotEmpty = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/provider') - const val = getValue(model, '/form/capi/provider') - if (val) return true -} + const ifCapiProviderIsNotEmpty = () => { + // watchDependency('model#/form/capi/provider') + const val = getValue(model, '/form/capi/provider') + if (val) return true + } -const showMultiselectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') + const showMultiselectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') - if (val === 'capz' && ifDedicated({ model, getValue })) return true -} + if (val === 'capz' && ifDedicated()) return true + } -const showSelectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') - if (val !== 'capz' && ifDedicated({ model, getValue })) return true -} + const showSelectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') + if (val !== 'capz' && ifDedicated()) return true + } -const ifDedicated = ({ model, getValue }) => { - const val = getValue(model, 'form/capi/dedicated') - if (val) return true -} + const ifDedicated = () => { + const val = getValue(model, 'form/capi/dedicated') + if (val) return true + } -const dedicatedOnChange = ({ model, getValue, commit }) => { - const val = getValue(model, 'form/capi/dedicated') - if (!val) { - commit('wizard/model$delete', 'form/capi/zones') - commit('wizard/model$delete', 'form/capi/sku') + const dedicatedOnChange = () => { + const val = getValue(model, 'form/capi/dedicated') + if (!val) { + commit('wizard/model$delete', 'form/capi/zones') + commit('wizard/model$delete', 'form/capi/sku') + } } -} -const ifZones = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/zones') - watchDependency('model#/form/capi/dedicated') - const zones = getValue(model, 'form/capi/zones') || [] - const isDedicated = getValue(model, 'form/capi/dedicated') - if (zones.length && isDedicated) return true -} + const ifZones = () => { + // watchDependency('model#/form/capi/zones') + // watchDependency('model#/form/capi/dedicated') + const zones = getValue(model, 'form/capi/zones') || [] + const isDedicated = getValue(model, 'form/capi/dedicated') + if (zones.length && isDedicated) return true + } -const zonesOnChange = ({ model, getValue, commit }) => { - const zones = getValue(model, 'form/capi/zones') || [] - if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') -} + const zonesOnChange = () => { + const zones = getValue(model, 'form/capi/zones') || [] + if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') + } -async function getZones({ storeGet, axios, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const isDedicated = getValue(model, 'form/capi/dedicated') - if (isDedicated) { - try { - const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) - const val = resp.data.map((item) => { - return { value: item, text: item } - }) - return val - } catch (e) { - console.log(e) - return [] + async function getZones() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const isDedicated = getValue(model, 'form/capi/dedicated') + if (isDedicated) { + try { + const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) + const val = resp.data.map((item) => { + return { value: item, text: item } + }) + return val + } catch (e) { + console.log(e) + return [] + } } } -} -async function getSKU({ storeGet, axios, model, getValue, watchDependency }) { - watchDependency('model#/form/capi/zones') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const zones = getValue(model, 'form/capi/zones') || [] - if (zones.length) { - try { - let url = `clustersv2/${owner}/${cluster}/vms?` - if (typeof zones === 'string') { - url += `zones=${encodeURIComponent(zones)}` - } else { - zones.forEach((item) => { - url += `zones=${encodeURIComponent(item)}&` + async function getSKU() { + // watchDependency('model#/form/capi/zones') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const zones = getValue(model, 'form/capi/zones') || [] + if (zones.length) { + try { + let url = `clustersv2/${owner}/${cluster}/vms?` + if (typeof zones === 'string') { + url += `zones=${encodeURIComponent(zones)}` + } else { + zones.forEach((item) => { + url += `zones=${encodeURIComponent(item)}&` + }) + url = url.slice(0, -1) + } + const resp = await axios.get(url) + const val = resp.data.map((item) => { + return { + value: item.name, + text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, + } }) - url = url.slice(0, -1) + return val + } catch (e) { + console.log(e) + return [] } - const resp = await axios.get(url) - const val = resp.data.map((item) => { - return { - value: item.name, - text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, - } - }) - return val - } catch (e) { - console.log(e) - return [] } } -} - -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} - -function setStorageClass({ model, getValue, commit, discriminator, watchDependency }) { - const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' - let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' - const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] - const suffix = '-retain' - const simpleClassList = storageClassList.filter((item) => { - return !item.endsWith(suffix) - }) + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false + } - const retainClassList = storageClassList.filter((item) => { - return item.endsWith(suffix) - }) + function setStorageClass() { + const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' + let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' + const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] + const suffix = '-retain' - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] - } else { - storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] - } + const simpleClassList = storageClassList.filter((item) => { + return !item.endsWith(suffix) + }) - const isChangeable = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'storageClasses', - ) - if (isChangeable && storageClass) { - commit('wizard/model$update', { - path: '/spec/admin/storageClasses/default', - value: storageClass, - force: true, + const retainClassList = storageClassList.filter((item) => { + return item.endsWith(suffix) }) - } -} -let placement = [] -let versions = [] -let storageClass = [] -let clusterIssuers = [] -let nodetopologiesShared = [] -let nodetopologiesDedicated = [] -let features = [] - -async function initBundle({ commit, model, getValue, axios, storeGet, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - - let db = getValue(model, '/metadata/resource/kind') - db = db.toLowerCase() - let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` - const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - - try { - const resp = await axios.get(url) - features = resp.data.features || [] - placement = resp.data.placementpolicies || [] - versions = resp.data.versions || [] - storageClass = resp.data.storageclasses || [] - clusterIssuers = resp.data.clusterissuers || [] - nodetopologiesDedicated = resp.data.dedicated || [] - nodetopologiesShared = resp.data.shared || [] - - const response = await axios.get(annotationUrl) - const annotations = response.data?.metadata?.annotations || {} - const uidRange = annotations['openshift.io/sa.scc.uid-range'] - if (uidRange) { - const val = uidRange.split('/')[0] + if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { + storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] + } else { + storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + } + + const isChangeable = isToggleOn('storageClasses') + if (isChangeable && storageClass) { commit('wizard/model$update', { - path: '/spec/openshift/securityContext/runAsUser', - value: val, + path: '/spec/admin/storageClasses/default', + value: storageClass, force: true, }) } - } catch (e) { - console.log(e) } - commit('wizard/model$update', { - path: '/spec/deletionPolicy', - value: getDefault({ getValue, model }, 'deletionPolicy'), - force: true, - }) + let placement = [] + let versions = [] + let storageClass = [] + let clusterIssuers = [] + let nodetopologiesShared = [] + let nodetopologiesDedicated = [] + let features = [] + + async function initBundle() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + + let db = getValue(model, '/metadata/resource/kind') + db = db.toLowerCase() + let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` + const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - if (!getValue(model, `/spec/admin/databases/PerconaXtraDB/mode/toggle`)) { - let defMode = getDefault({ getValue, model }, 'databases/PerconaXtraDB/mode') || '' - if (defMode === '') { - const arr = getValue(model, '/spec/databases/PerconaXtraDB/mode/available') || [] - if (arr.length) defMode = arr[0] + try { + const resp = await axios.get(url) + features = resp.data.features || [] + placement = resp.data.placementpolicies || [] + versions = resp.data.versions || [] + storageClass = resp.data.storageclasses || [] + clusterIssuers = resp.data.clusterissuers || [] + nodetopologiesDedicated = resp.data.dedicated || [] + nodetopologiesShared = resp.data.shared || [] + + const response = await axios.get(annotationUrl) + const annotations = response.data?.metadata?.annotations || {} + const uidRange = annotations['openshift.io/sa.scc.uid-range'] + if (uidRange) { + const val = uidRange.split('/')[0] + commit('wizard/model$update', { + path: '/spec/openshift/securityContext/runAsUser', + value: val, + force: true, + }) + } + } catch (e) { + console.log(e) } - commit('wizard/model$update', { - path: '/spec/mode', - value: defMode, - force: true, - }) - } - if (!features.includes('tls')) { commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: false, + path: '/spec/deletionPolicy', + value: getDefault('deletionPolicy'), force: true, }) - } - if (!features.includes('binding')) { - commit('wizard/model$update', { - path: '/spec/admin/expose/default', - value: false, - force: true, - }) - } - if (!features.includes('monitoring')) { - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: 'none', - force: true, - }) - } - if (!features.includes('backup')) { - commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, - force: true, - }) - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: '', - force: true, - }) - } - setDiscriminatorValue('/bundleApiLoaded', true) -} + if (!getValue(model, `/spec/admin/databases/PerconaXtraDB/mode/toggle`)) { + let defMode = getDefault('databases/PerconaXtraDB/mode') || '' + if (defMode === '') { + const arr = getValue(model, '/spec/databases/PerconaXtraDB/mode/available') || [] + if (arr.length) defMode = arr[0] + } + commit('wizard/model$update', { + path: '/spec/mode', + value: defMode, + force: true, + }) + } -function fetchOptions({ model, getValue, commit }, type) { - let kind = getValue(model, '/metadata/resource/kind') + if (!features.includes('tls')) { + commit('wizard/model$update', { + path: '/spec/admin/tls/default', + value: false, + force: true, + }) + } + if (!features.includes('binding')) { + commit('wizard/model$update', { + path: '/spec/admin/expose/default', + value: false, + force: true, + }) + } + if (!features.includes('monitoring')) { + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: 'none', + force: true, + }) + } + if (!features.includes('backup')) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: '', + force: true, + }) + } - let returnArray = [] - if (type === 'clusterTier/placement') { - returnArray = placement - } else if (type === `databases/${kind}/versions`) { - returnArray = versions - } else if (type === 'storageClasses') { - returnArray = storageClass - } else if (type === 'clusterIssuers') { - returnArray = clusterIssuers + setDiscriminatorValue('/bundleApiLoaded', true) } - if (returnArray.length === 1) { - const path = `/spec/admin/${type}/default` - commit('wizard/model$update', { - path: path, - value: returnArray[0], - force: true, - }) - } + function fetchOptions(type) { + let kind = getValue(model, '/metadata/resource/kind') + + let returnArray = [] + if (type === 'clusterTier/placement') { + returnArray = placement + } else if (type === `databases/${kind}/versions`) { + returnArray = versions + } else if (type === 'storageClasses') { + returnArray = storageClass + } else if (type === 'clusterIssuers') { + returnArray = clusterIssuers + } - return returnArray -} + if (returnArray.length === 1) { + const path = `/spec/admin/${type}/default` + commit('wizard/model$update', { + path: path, + value: returnArray[0], + force: true, + }) + } -function getAdminOptions({ getValue, model, watchDependency, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') + return returnArray + } - const options = getValue(model, `/spec/admin/${type}/available`) || [] + function getAdminOptions(type) { + // watchDependency('discriminator#/bundleApiLoaded') - if (options.length === 0) { - return fetchOptions({ model, getValue, commit }, type) - } + const options = getValue(model, `/spec/admin/${type}/available`) || [] - return options -} + if (options.length === 0) { + return fetchOptions(type) + } -function checkIfFeatureOn({ getValue, model }, type) { - let val = getValue(model, `/spec/admin/${type}/toggle`) - if (type === 'backup' || type === 'archiver') { - val = getValue(model, `/spec/admin/${type}/enable/toggle`) + return options } - const backupVal = getValue(model, '/spec/backup/tool') - if (type === 'backup') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } else if (type === 'tls') { - return features.includes('tls') && val - } else if (type === 'expose') { - return features.includes('binding') && val - } else if (type === 'monitoring') { - return features.includes('monitoring') && val - } else if (type === 'archiver') { - return features.includes('backup') && backupVal === 'KubeStash' && val + function checkIfFeatureOn(type) { + let val = getValue(model, `/spec/admin/${type}/toggle`) + if (type === 'backup' || type === 'archiver') { + val = getValue(model, `/spec/admin/${type}/enable/toggle`) + } + const backupVal = getValue(model, '/spec/backup/tool') + + if (type === 'backup') { + return features.includes('backup') && backupVal === 'KubeStash' && val + } else if (type === 'tls') { + return features.includes('tls') && val + } else if (type === 'expose') { + return features.includes('binding') && val + } else if (type === 'monitoring') { + return features.includes('monitoring') && val + } else if (type === 'archiver') { + return features.includes('backup') && backupVal === 'KubeStash' && val + } } -} -function isToggleOn({ getValue, model, discriminator, watchDependency }, type) { - watchDependency('discriminator#/bundleApiLoaded') - watchDependency('model#/spec/admin/deployment/default') - const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') - let deploymentType = getValue(model, `/spec/admin/deployment/default`) - if ( - type === 'tls' || - type === 'backup' || - type === 'expose' || - type === 'monitoring' || - type === 'archiver' - ) { - return checkIfFeatureOn({ getValue, model }, type) - } else if ( - type === 'clusterTier' || - type === 'clusterTier/placement' || - type === 'clusterTier/nodeTopology' - ) { - if (deploymentType === 'Dedicated' && bundleApiLoaded) return true - else return false - } else if (type === 'deployment') { - const deploymentType = getValue(model, '/spec/admin/deployment/default') - if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { - commit('wizard/model$update', { - path: '/spec/admin/deployment/default', - value: 'Shared', - force: true, - }) - } - return ( - getValue(model, `/spec/admin/${type}/toggle`) && - nodetopologiesDedicated.length && - bundleApiLoaded - ) - } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded -} + function isToggleOn(type) { + // watchDependency('discriminator#/bundleApiLoaded') + // watchDependency('model#/spec/admin/deployment/default') + const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') + let deploymentType = getValue(model, `/spec/admin/deployment/default`) + if ( + type === 'tls' || + type === 'backup' || + type === 'expose' || + type === 'monitoring' || + type === 'archiver' + ) { + return checkIfFeatureOn(type) + } else if ( + type === 'clusterTier' || + type === 'clusterTier/placement' || + type === 'clusterTier/nodeTopology' + ) { + if (deploymentType === 'Dedicated' && bundleApiLoaded) return true + else return false + } else if (type === 'deployment') { + const deploymentType = getValue(model, '/spec/admin/deployment/default') + if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + commit('wizard/model$update', { + path: '/spec/admin/deployment/default', + value: 'Shared', + force: true, + }) + } + return ( + getValue(model, `/spec/admin/${type}/toggle`) && + nodetopologiesDedicated.length && + bundleApiLoaded + ) + } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded + } -async function getNodeTopology({ model, getValue, axios, storeGet, watchDependency }) { - watchDependency('model#/spec/admin/deployment/default') - watchDependency('model#/spec/admin/clusterTier/default') - const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' - const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' - let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + async function getNodeTopology() { + // watchDependency('model#/spec/admin/deployment/default') + // watchDependency('model#/spec/admin/clusterTier/default') + const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' + const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' + let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] - const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' - if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared - else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared + else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated - const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) - return filteredList -} + const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) + return filteredList + } -function filterNodeTopology(list, tier, provider) { - // first filter the list from value that exists from the filtered list got from API - const filteredlist = list + function filterNodeTopology(list, tier, provider) { + // first filter the list from value that exists from the filtered list got from API + const filteredlist = list - // filter the list based on clusterTier - if (provider === 'EKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('c') - else if (tier === 'MemoryOptimized') return item.startsWith('r') - else return !item.startsWith('c') && !item.startsWith('r') - }) - } else if (provider === 'AKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - else - return ( - !(item.startsWith('f') || item.startsWith('fx')) && - !( + // filter the list based on clusterTier + if (provider === 'EKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('c') + else if (tier === 'MemoryOptimized') return item.startsWith('r') + else return !item.startsWith('c') && !item.startsWith('r') + }) + } else if (provider === 'AKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('e') || item.startsWith('eb') || item.startsWith('ec') || item.startsWith('m') || item.startsWith('d') ) - ) - }) - } else if (provider === 'GKE') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') - return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - else - return ( - !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && - !( + else + return ( + !(item.startsWith('f') || item.startsWith('fx')) && + !( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + ) + }) + } else if (provider === 'GKE') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') + return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('x4') || item.startsWith('m1') || item.startsWith('m2') || item.startsWith('m3') ) - ) - }) - } else return filteredlist -} + else + return ( + !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && + !( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + ) + }) + } else return filteredlist + } -function returnFalse() { - return false -} + function returnFalse() { + return false + } -function showAlerts({ watchDependency, model, getValue, discriminator }) { - watchDependency('discriminator#/monitoring') - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const isAlertToggleEnabled = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'alert', - ) - return isMonitorEnabled && isAlertToggleEnabled -} + function showAlerts() { + // watchDependency('discriminator#/monitoring') + const isMonitorEnabled = getValue(discriminator, '/monitoring') + return isMonitorEnabled && isToggleOn('alert') + } -function showIssuer({ model, getValue, watchDependency, discriminator }) { - watchDependency('model#/spec/admin/tls/default') - const isTlsEnabled = getValue(model, '/spec/admin/tls/default') - const isIssuerToggleEnabled = isToggleOn( - { getValue, model, watchDependency, discriminator }, - 'clusterIssuers', - ) - return isTlsEnabled && isIssuerToggleEnabled -} + function showIssuer() { + // watchDependency('model#/spec/admin/tls/default') + const isTlsEnabled = getValue(model, '/spec/admin/tls/default') + const isIssuerToggleEnabled = isToggleOn('clusterIssuers') + return isTlsEnabled && isIssuerToggleEnabled + } -function onBackupSwitch({ discriminator, getValue, commit }) { - const isBackupOn = getValue(discriminator, '/backup') - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: isBackupOn ? 'KubeStash' : '', - force: true, - }) -} + function onBackupSwitch() { + const isBackupOn = getValue(discriminator, '/backup') + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: isBackupOn ? 'KubeStash' : '', + force: true, + }) + } -function setMonitoring({ getValue, model }) { - const agent = getValue(model, '/spec/admin/monitoring/agent') || '' - return !!agent -} + function setMonitoring() { + const agent = getValue(model, '/spec/admin/monitoring/agent') || '' + return !!agent + } -function setBackup({ model, getValue }) { - const backup = getValue(model, '/spec/backup/tool') - const val = getValue(model, '/spec/admin/backup/enable/default') - return backup === 'KubeStash' && features.includes('backup') && val -} + function setBackup() { + const backup = getValue(model, '/spec/backup/tool') + const val = getValue(model, '/spec/admin/backup/enable/default') + return backup === 'KubeStash' && features.includes('backup') && val + } -function onAuthChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/authSecret/password', - value: '', - force: true, - }) -} + function onAuthChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/spec/authSecret/password', + value: '', + force: true, + }) + } -function isConfigDatabaseOn({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configDatabase') - return getValue(discriminator, '/configDatabase') -} + function isConfigDatabaseOn() { + // watchDependency('discriminator#/configDatabase') + return getValue(discriminator, '/configDatabase') + } -function clearConfiguration({ discriminator, getValue, commit }) { - const configOn = getValue(discriminator, '/configDatabase') + function clearConfiguration() { + const configOn = getValue(discriminator, '/configDatabase') - if (!configOn) { - commit('wizard/model$delete', '/spec/configuration') + if (!configOn) { + commit('wizard/model$delete', '/spec/configuration') + } } -} -function clearArbiterHidden({ commit }) { - commit('wizard/model$update', { - path: `/spec/arbiter/enabled`, - value: false, - force: true, - }) - - commit('wizard/model$update', { - path: `/spec/hidden/enabled`, - value: false, - force: true, - }) -} + function clearArbiterHidden() { + commit('wizard/model$update', { + path: `/spec/arbiter/enabled`, + value: false, + force: true, + }) -function returnFalse() { - return false -} + commit('wizard/model$update', { + path: `/spec/hidden/enabled`, + value: false, + force: true, + }) + } -function showHidden({ watchDependency, model, getValue }) { - watchDependency('model#/spec/hidden/enabled') - const isHiddenOn = getValue(model, '/spec/hidden/enabled') || '' - const notStandalone = notEqualToDatabaseMode({ model, getValue, watchDependency }, 'Standalone') - return isHiddenOn && notStandalone -} + function showHidden() { + // watchDependency('model#/spec/hidden/enabled') + const isHiddenOn = getValue(model, '/spec/hidden/enabled') || '' + const notStandalone = notEqualToDatabaseMode('Standalone') + return isHiddenOn && notStandalone + } -function showArbiter({ watchDependency, model, getValue }) { - watchDependency('model#/spec/arbiter/enabled') - const isArbiterOn = getValue(model, '/spec/arbiter/enabled') || '' - const notStandalone = notEqualToDatabaseMode({ model, getValue, watchDependency }, 'Standalone') - return isArbiterOn && notStandalone -} + function showArbiter() { + // watchDependency('model#/spec/arbiter/enabled') + const isArbiterOn = getValue(model, '/spec/arbiter/enabled') || '' + const notStandalone = notEqualToDatabaseMode('Standalone') + return isArbiterOn && notStandalone + } -async function fetchJsons({ axios, itemCtx }) { - let ui = {} - let language = {} - let functions = {} - const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart + async function fetchJsons() { + 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) - } + 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, + return { + ui: ui.data || {}, + language: language.data || {}, + functions, + } } -} -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } -function showAuthSecretField({ discriminator, getValue, watchDependency }) { - return !showAuthPasswordField({ - discriminator, - getValue, - watchDependency, - }) -} + function showAuthSecretField() { + return !showAuthPasswordField() + } -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} + function notEqualToDatabaseMode(mode) { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + return modelPathValue && modelPathValue !== mode + } -function showStorageSizeField({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - const validType = [] - return !validType.includes(modelPathValue) -} + function showStorageSizeField() { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + const validType = [] + return !validType.includes(modelPathValue) + } -async function getResources({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + 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) || [] + 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 -} + resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true + }) + return resources + } -async function getMongoDbVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + async function getPerconaXtraDBVersions(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, + const queryParams = { + filter: { + items: { + metadata: { name: null }, + spec: { version: null, deprecated: null }, + }, }, - }, - } - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) + } - const resources = (resp && resp.data && resp.data.items) || [] + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: queryParams, + }, + ) - // keep only non deprecated versions - const filteredMongoDbVersions = resources.filter((item) => item.spec && !item.spec.deprecated) + const resources = (resp && resp.data && resp.data.items) || [] - filteredMongoDbVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredMongoDbVersions -} + // keep only non deprecated versions + const filteredVersions = resources.filter((item) => item.spec && !item.spec.deprecated) -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/spec/authSecret/name') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/spec/authSecret/password') + filteredVersions.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + const specVersion = (item.spec && item.spec.version) || '' + item.text = `${name} (${specVersion})` + item.value = name + return true + }) + return filteredVersions } -} -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + function onCreateAuthSecretChange() { + const createAuthSecret = getValue(discriminator, '/createAuthSecret') + if (createAuthSecret) { + commit('wizard/model$delete', '/spec/authSecret/name') + } else if (createAuthSecret === false) { + commit('wizard/model$delete', '/spec/authSecret/password') + } + } - const secrets = (resp && resp.data && resp.data.items) || [] + 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') - const filteredSecrets = secrets.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }, + ) - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return filteredSecrets -} + const secrets = (resp && resp.data && resp.data.items) || [] -function updateAgentValue({ commit }, val) { - commit('wizard/model$update', { - path: '/spec/monitoring/agent', - value: val ? 'prometheus.io/operator' : '', - force: true, - }) - - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: val ? 'warning' : 'none', - force: true, - }) -} + const filteredSecrets = secrets.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) -function showReplicaField({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - const validType = ['Replicaset'] - return validType.includes(modelPathValue) -} + filteredSecrets.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true + }) + return filteredSecrets + } -function onModeChange({ model, getValue, watchDependency, commit }) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - if (modelPathValue === 'Replicaset') { + function updateAgentValue(val) { commit('wizard/model$update', { - path: '/spec/replicas', - value: 3, + path: '/spec/monitoring/agent', + value: val ? 'prometheus.io/operator' : '', force: true, }) - } else { + + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: '/spec/replicas', - value: 1, + path: '/form/alert/enabled', + value: val ? 'warning' : 'none', force: true, }) } -} -function showAdditionalSettings({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return features.length -} + function showReplicaField() { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + const validType = ['Replicaset'] + return validType.includes(modelPathValue) + } -function getDefault({ getValue, model }, type) { - const val = getValue(model, `/spec/admin/${type}/default`) || '' - return val -} + function onModeChange() { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + if (modelPathValue === 'Replicaset') { + commit('wizard/model$update', { + path: '/spec/replicas', + value: 3, + force: true, + }) + } else { + commit('wizard/model$update', { + path: '/spec/replicas', + value: 1, + force: true, + }) + } + } -function isConfigAvailable({ getValue, model }) { - const val = getValue(model, '/spec/configuration') - return val !== '' -} + function showAdditionalSettings() { + // watchDependency('discriminator#/bundleApiLoaded') + return features.length + } -async function getReferSecrets({ getValue, model, storeGet, axios, discriminator }) { - const referSecret = getValue(discriminator, '/referSecret') - if (!referSecret) { - return [] + function getDefault(type) { + const val = getValue(model, `/spec/admin/${type}/default`) || '' + return val } - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/metadata/release/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` + async function getReferSecrets() { + const referSecret = getValue(discriminator, '/referSecret') + if (!referSecret) { + return [] + } - const options = [] - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) - } catch (e) { - console.log(e) + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/metadata/release/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` + + const options = [] + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + return options } - return options -} -function showAuthPasswordField({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showAuthPasswordField() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !modelPathValue && showReferSecret() + } -function showSecretDropdown({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showSecretDropdown() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !!modelPathValue && showReferSecret() + } -function showReferSecret({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/createAuthSecret') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue -} + function showReferSecret() { + const modelPathValue = getValue(discriminator, '/createAuthSecret') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue + } -function getDefaultValue({ getValue, model }, path) { - const val = getValue(model, `/${path}`) || '' - return val -} + function getDefaultValue(path) { + const val = getValue(model, `/${path}`) || '' + return val + } -function showReferSecretSwitch({ model, getValue, watchDependency, discriminator }) { - const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showReferSecretSwitch() { + const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue && showReferSecret() + } -function onReferSecretChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) -} + function onReferSecretChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + } -return { - showReferSecretSwitch, - onReferSecretChange, - getDefaultValue, - isRancherManaged, - showSecretDropdown, - showReferSecret, - getReferSecrets, - isConfigAvailable, - showAdditionalSettings, - initBundle, - returnFalse, - getNamespaces, - updateAlertValue, - getAdminOptions, - isToggleOn, - showAlerts, - getNodeTopology, - clearArbiterHidden, - returnFalse, - showHidden, - isConfigDatabaseOn, - notEqualToDatabaseMode, - filterNodeTopology, - onAuthChange, - setMonitoring, - isMachineNotCustom, - isMachineCustom, - showIssuer, - showArbiter, - clearConfiguration, - onBackupSwitch, - isVariantAvailable, - fetchJsons, - showAuthPasswordField, - isEqualToModelPathValue, - showAuthSecretField, - showStorageSizeField, - getResources, - getMongoDbVersions, - onCreateAuthSecretChange, - getSecrets, - getMachineListForOptions, - setLimits, - setRequests, - setMachineToCustom, - updateAgentValue, - getCreateNameSpaceUrl, - ifCapiProviderIsNotEmpty, - ifDedicated, - dedicatedOnChange, - ifZones, - zonesOnChange, - getZones, - getSKU, - showMultiselectZone, - showSelectZone, - setStorageClass, - showReplicaField, - onModeChange, - setBackup, - getDefault, + return { + showReferSecretSwitch, + onReferSecretChange, + getDefaultValue, + isRancherManaged, + showSecretDropdown, + showReferSecret, + getReferSecrets, + showAdditionalSettings, + initBundle, + returnFalse, + getNamespaces, + updateAlertValue, + getAdminOptions, + isToggleOn, + showAlerts, + getNodeTopology, + clearArbiterHidden, + showHidden, + isConfigDatabaseOn, + notEqualToDatabaseMode, + filterNodeTopology, + onAuthChange, + setMonitoring, + isMachineNotCustom, + isMachineCustom, + showIssuer, + showArbiter, + clearConfiguration, + onBackupSwitch, + isVariantAvailable, + fetchJsons, + showAuthPasswordField, + isEqualToModelPathValue, + showAuthSecretField, + showStorageSizeField, + getResources, + getPerconaXtraDBVersions, + onCreateAuthSecretChange, + getSecrets, + getMachineListForOptions, + setLimits, + setRequests, + setMachineToCustom, + updateAgentValue, + getCreateNameSpaceUrl, + ifCapiProviderIsNotEmpty, + ifDedicated, + dedicatedOnChange, + ifZones, + zonesOnChange, + getZones, + getSKU, + showMultiselectZone, + showSelectZone, + setStorageClass, + showReplicaField, + onModeChange, + setBackup, + getDefault, + } } diff --git a/charts/kubedbcom-perconaxtradb-editor/ui/edit-ui.yaml b/charts/kubedbcom-perconaxtradb-editor/ui/edit-ui.yaml index 6262b01d2c..2f91897ee9 100644 --- a/charts/kubedbcom-perconaxtradb-editor/ui/edit-ui.yaml +++ b/charts/kubedbcom-perconaxtradb-editor/ui/edit-ui.yaml @@ -1,637 +1,558 @@ -steps: -- form: +type: multi-step-form +step: + - type: single-step-form + id: compute-autoscaler + loader: getDbDetails elements: - - disabled: true - label: - text: labels.database.name - onChange: onNameChange - schema: - $ref: schema#/properties/metadata/properties/release/properties/name - type: input - type: single-step-form - id: basic - title: steps.0.label -- form: - discriminator: - dbDetails: - default: false - type: boolean + - type: block-layout + if: + type: function + name: isConsole + elements: + - type: input + label: Name + schema: schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/metadata/properties/name + - type: select + label: Select Namespace + loader: getNamespaces + if: + type: function + name: isRancherManaged + schema: schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/metadata/properties/namespace + - type: select + label: Select Db + loader: getDbs + validation: + type: required + refresh: true + schema: schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/databaseRef/properties/name + watcher: + func: initMetadata + paths: + - schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/databaseRef/properties/name + + - type: radio + if: + type: function + name: isConsole + label: Select Type + validation: + type: required + schema: temp/properties/autoscalingType + watcher: + func: initMetadata + paths: + - temp/properties/autoscalingType + options: + - text: Compute + value: compute + description: Scale your CPU Memory based on resource usage + - text: Storage + value: storage + description: Expand your database size based on volume usage + + - type: block-layout + showLabels: false + loader: fetchTopologyMachines + elements: + # perconaxtradb mode + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComPerconaXtraDBAutoscaler/spec/compute/perconaxtradb/trigger + schema: temp/properties/compute/properties/perconaxtradb/properties/trigger + watcher: + func: onTriggerChange|compute/perconaxtradb + paths: + - temp/properties/compute/properties/perconaxtradb/properties/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/perconaxtradb/properties/podLifeTimeThreshold + customClass: width-300 + - type: block-layout + label: PerconaXtraDB + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/perconaxtradb + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/perconaxtradb/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-perconaxtradb-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|perconaxtradb|min + loader: + name: getMachines|perconaxtradb|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-perconaxtradb-max + watcher: + func: onMachineChange|perconaxtradb + paths: + - temp/properties/allowedMachine-perconaxtradb-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/perconaxtradb/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/perconaxtradb/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-perconaxtradb-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|perconaxtradb|max + loader: + name: getMachines|perconaxtradb|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-perconaxtradb-min + watcher: + func: onMachineChange|perconaxtradb + paths: + - temp/properties/allowedMachine-perconaxtradb-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/perconaxtradb/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/perconaxtradb/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|compute/perconaxtradb + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/perconaxtradb/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/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/perconaxtradb/properties/containerControlledValues + + - type: block-layout + label: Node Topology + if: + type: function + name: hasNoAnnotations + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology + elements: + - type: select + label: Select NodeTopology + loader: fetchNodeTopology + schema: schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name + - type: threshold-input + label: ScaleUp Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage + - type: threshold-input + label: ScaleDown Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage + + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + # schema: schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/opsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: storage-autoscaler + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: Select Db - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: Select Type - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - discriminator: - topologyMachines: - default: [] - type: array + - type: block-layout + showLabels: false elements: - - fetch: fetchTopologyMachines - if: returnFalse - schema: - $ref: discriminator#/topologyMachines - type: input - - elements: - - computed: setTrigger|autoscalingKubedbComPerconaXtraDBAutoscaler/spec/compute/perconaxtradb/trigger - label: - text: Trigger + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComPerconaXtraDBAutoscaler/spec/storage/perconaxtradb/trigger + schema: temp/properties/storage/properties/perconaxtradb/properties/trigger + watcher: + func: onTriggerChange|storage/perconaxtradb + paths: + - temp/properties/storage/properties/perconaxtradb/properties/trigger + - type: label-element + 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: select + label: Mode + description: Select how the storage expansion should be handled. options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/perconaxtradb/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/perconaxtradb/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/perconaxtradb/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-max: - type: string - allowedMachine-min: - type: string + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/storage/properties/perconaxtradb/properties/expansionMode + - type: block-layout + label: PerconaXtraDB + showLabels: true elements: - - computed: setAllowedMachine|min - disableUnselect: true - fetch: getMachines|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|perconaxtradb - schema: - $ref: discriminator#/properties/allowedMachine-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/perconaxtradb/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/perconaxtradb/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/perconaxtradb/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|max - disableUnselect: true - fetch: getMachines|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|perconaxtradb - schema: - $ref: discriminator#/properties/allowedMachine-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/perconaxtradb/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/perconaxtradb/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/perconaxtradb/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|perconaxtradb - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/perconaxtradb/properties/controlledResources - type: multiselect - label: - text: PerconaXtraDB - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/perconaxtradb - show_label: true - type: single-step-form - - elements: - - fetch: fetchNodeTopology - label: - text: Select Node Topology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name - type: select - - if: isNodeTopologySelected - label: - text: ScaleUp Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage - type: input - - if: isNodeTopologySelected - label: - text: ScaleDown Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage - type: input - if: hasNoAnnotations - label: - text: NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/nodeTopology - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: compute-autoscaler - title: steps.6.label -- form: - discriminator: - dbDetails: - default: false - type: boolean + - type: threshold-input + label: UsageThreshold (%) + subtitle: Set the threshold percentage of storage usage to trigger scaling. + schema: schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/storage/properties/perconaxtradb/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/storage/properties/perconaxtradb/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComPerconaXtraDB/spec/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComPerconaXtraDBAutoscaler/spec/storage/perconaxtradb/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/storage/properties/perconaxtradb/properties/scalingRules + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/storage/properties/perconaxtradb/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComPerconaXtraDBAutoscaler/spec/storage/perconaxtradb/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/storage/properties/perconaxtradb/properties/upperBound + - type: block-layout + label: OpsRequest Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: monitoring + loader: initMonitoring elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - computed: getDbDetails - if: returnFalse - type: input - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: Select Db - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: Select Type - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComPerconaXtraDBAutoscaler/spec/storage/perconaxtradb/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/storage/properties/perconaxtradb/properties/trigger - type: select - - label: - text: Expansion Mode + - type: label-element + label: To update Exporter Resource section click on Create OpsRequest + - type: anchor + label: Create OpsRequest + schema: temp/properties/opsRequestUrl + init: + type: func + value: getOpsRequestUrl|scale-vertically + - type: switch + label: Enable Monitoring + fullwidth: true + schema: temp/properties/enableMonitoring + init: + type: func + value: isValueExistInModel|/resources/kubedbComPerconaXtraDB/spec/monitor + watcher: + func: onEnableMonitoringChange + paths: + - temp/properties/enableMonitoring + - type: block-layout + if: + type: function + name: showMonitoringSection + elements: + - type: radio + label: Select a Monitoring Method + schema: schema/properties/resources/properties/kubedbComPerconaXtraDB/properties/spec/properties/monitor/properties/agent + isHorizontal: true options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/storage/properties/perconaxtradb/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/storage/properties/perconaxtradb/properties/usageThreshold - type: input - - addFormLabel: ScalingRules - element: + - text: Prometheus Operator + value: prometheus.io/operator + description: Inject metric exporter sidecar and creates a ServiceMonitor + - text: Custom ServiceMonitor + value: prometheus.io + description: Injects the metric exporter sidecar and let you customize ServiceMonitor + - text: Custom Scrapper + value: prometheus.io/builtin + description: Inject metric exporter sidecar and add Prometheus annotations to the stats Service + init: + type: static + value: prometheus.io/operator + watcher: + func: onAgentChange + paths: + - schema/properties/resources/properties/kubedbComPerconaXtraDB/properties/spec/properties/monitor/properties/agent + - type: block-layout + label: ServiceMonitor Configuration + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComPerconaXtraDB/spec/monitor/agent + elements: + - label: Scrapping Interval + schema: schema/properties/resources/properties/kubedbComPerconaXtraDB/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval + type: input + - type: block-layout + label: Service Monitor + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComPerconaXtraDB/spec/monitor/agent + elements: + - type: array-object-form + label: Endpoints + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/endpoints elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/storage/properties/perconaxtradb/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/storage/properties/perconaxtradb/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComPerconaXtraDBAutoscaler/spec/storage/perconaxtradb/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/storage/properties/perconaxtradb/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComPerconaXtraDBAutoscaler/spec/storage/perconaxtradb/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/storage/properties/perconaxtradb/properties/upperBound - type: input - label: - text: PerconaXtraDB - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/compute/properties/perconaxtradb - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPerconaXtraDBAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: storage-autoscaler - title: steps.7.label -- form: - discriminator: - enableMonitoring: - default: true - type: boolean - elements: - - label: - text: labels.to_update_exporter_resources - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - function: getOpsRequestUrl|VerticalScaling - - computed: isValueExistInModel|/resources/kubedbComPerconaXtraDB/spec/monitor - 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/kubedbComPerconaXtraDB/properties/spec/properties/monitor/properties/agent - type: radio - - elements: - - label: - text: labels.scrapping_interval - schema: - $ref: schema#/properties/resources/properties/kubedbComPerconaXtraDB/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval - type: input - if: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComPerconaXtraDB/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: switch + label: Honor labels + fullwidth: true + schema: honorLabels + - type: input + label: Interval + schema: interval + validation: + type: required + - type: input + label: Path + schema: path + validation: + type: required + - type: input + label: Port + schema: port + validation: + type: required + - type: select + multiple: true + label: Match Namespaces + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/namespaceSelector/properties/matchNames + loader: getResources|core|v1|namespaces + if: + type: function + name: returnFalse + - type: block-layout + showLabels: false + # schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector + if: + type: function + name: returnFalse + elements: + - type: object-item + label: Labels + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector/properties/matchLabels + - type: object-item + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/metadata/properties/labels + label : Labels + buttonClass: is-light is-outlined + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComPerconaXtraDB/spec/monitor/agent + # individualItemDisabilityCheck: disableLableChecker + - type: label-element + label: Exporter Configuration + schema: '' + - type: switch + label: Customize Exporter Sidecar + fullwidth: true + schema: temp/properties/customizeExporter + init: + type: static + value: true + watcher: + func: onCustomizeExporterChange + paths: + - temp/properties/customizeExporter + - type: block-layout + label: Customer Exporter Section + showLabels: false + if: + type: function + name: showCustomizeExporterSection + elements: + - type: machine-compare + label: Resources + schema: schema/properties/resources/properties/kubedbComPerconaXtraDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/resources + if: + type: function + name: returnFalse + - type: label-element + label: Security Context + schema: '' + - type: input + schema: schema/properties/resources/properties/kubedbComPerconaXtraDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsUser + label: Run as User + - type: input + schema: schema/properties/resources/properties/kubedbComPerconaXtraDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup + label: Run as Group + - type: input + schema: schema/properties/resources/properties/kubedbComPerconaXtraDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/port + label: Port + - type: array-item-form + label: Args + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/kubedbComPerconaXtraDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args + init: + type: static + value: ['--compatible-mode'] + element: 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/kubedbComPerconaXtraDB/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/kubedbComPerconaXtraDB/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: - - if: returnFalse - label: - text: labels.resources - schema: - $ref: schema#/properties/resources/properties/kubedbComPerconaXtraDB/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/kubedbComPerconaXtraDB/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/kubedbComPerconaXtraDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup - type: input - - label: - text: labels.port - schema: - $ref: schema#/properties/resources/properties/kubedbComPerconaXtraDB/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/kubedbComPerconaXtraDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args/items - type: input - label: - text: labels.args - schema: - $ref: schema#/properties/resources/properties/kubedbComPerconaXtraDB/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args - type: list-input-form - - alias: reusable_env - chart: - name: uibytebuildersdev-component-env - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComPerconaXtraDB/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 -type: multi-step-form + label: Args + # isSubsection: true + - type: block-layout + label: Metadata + showLabels: false + elements: + - type: array-object-form + init: + type: func + value: initEnvArray + label: Environment Variables + buttonClass: is-light is-outlined + watcher: + func: onEnvArrayChange + paths: + - temp/properties/env + schema: temp/properties/env + elements: + - type: input + label: Name + schema: name + validation: + type: required + - type: radio + label: Value From + schema: temp/properties/valueFromType + validation: + type: required + init: + type: func + value: setValueFrom + options: + - text: Input + value: input + - text: Secret + value: secret + - text: ConfigMap + value: configMap + watcher: + func: onValueFromChange + paths: + - temp/properties/valueFromType + - type: input + label: Value + schema: value + validation: + type: required + if: + name: isEqualToTemp|input + type: function + - type: select + if: + type: function + name: isEqualToTemp|configMap + label: ConfigMap Name + schema: valueFrom/properties/configMapKeyRef/properties/name + loader: + name: resourceNames|core|v1|configmaps + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: ConfigMap Key + schema: valueFrom/properties/configMapKeyRef/properties/key + if: + type: function + name: isEqualToTemp|configMap + loader: + name: getConfigMapKeys + watchPaths: + - schema/resources/kubedbComPerconaXtraDB/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/configMapKeyRef/name + - schema/metadata/release/namespace + - type: select + label: Secret Name + schema: valueFrom/properties/secretKeyRef/properties/name + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecrets + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: Secret Key + schema: valueFrom/properties/secretKeyRef/properties/key + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecretKeys + watchPaths: + - schema/resources/kubedbComPerconaXtraDB/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/secretKeyRef/name + - schema/metadata/release/namespace diff --git a/charts/kubedbcom-perconaxtradb-editor/ui/functions.js b/charts/kubedbcom-perconaxtradb-editor/ui/functions.js index cb31d41c9a..3e41689c9c 100644 --- a/charts/kubedbcom-perconaxtradb-editor/ui/functions.js +++ b/charts/kubedbcom-perconaxtradb-editor/ui/functions.js @@ -1,3109 +1,982 @@ -// ************************* common functions ******************************************** -// eslint-disable-next-line no-empty-pattern -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 disableLableChecker({ itemCtx }) { - const { key } = itemCtx - if (key.startsWith('app.kubernetes.io') || key.includes('helm')) return true - else return false -} - -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} - -async function getResources({ axios, storeGet }, 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 [] - } -} - -function isEqualToDiscriminatorPath( - { discriminator, getValue, watchDependency }, - value, - discriminatorPath, -) { - watchDependency('discriminator#' + discriminatorPath) - const discriminatorValue = getValue(discriminator, discriminatorPath) - return discriminatorValue === value -} - -function setValueFromModel({ getValue, model }, path) { - return getValue(model, path) -} - -function isNotShardModeSelected({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComPerconaXtraDB/spec') - const hasShardTopology = getValue(model, '/resources/kubedbComPerconaXtraDB/spec/shardTopology') - return !hasShardTopology -} - -function isShardModeSelected({ model, getValue, watchDependency, commit }) { - const resp = !isNotShardModeSelected({ model, getValue, watchDependency }) - if (resp) { - commit('wizard/model$delete', '/resources/kubedbComPerconaXtraDB/spec/configSecret') - commit('wizard/model$delete', '/resources/secret_config') - } - return resp -} - -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 -} - -async function getResourceList(axios, storeGet, { 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( - { axios, getValue, model, watchDependency, storeGet }, - 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 unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - 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, - } - }) -} - -function returnTrue() { - return true -} - -function returnStringYes() { - return 'yes' -} - -// ************************* Basic Info ********************************************** -async function getMongoDbVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, - }, - }, - } - - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) - - const resources = (resp && resp.data && resp.data.items) || [] - - // keep only non deprecated versions - const filteredMongoDbVersions = resources.filter((item) => item.spec && !item.spec.deprecated) - - filteredMongoDbVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredMongoDbVersions - } catch (e) { - console.log(e) - return [] - } -} - -// ************************* Auth Secret Field ****************************************** -function showAuthPasswordField({ model, getValue, watchDependency }) { - watchDependency('model#/resources') - const modelPathValue = getValue(model, '/resources') - return !!( - modelPathValue && - modelPathValue.secret && - modelPathValue.secret.metadata && - modelPathValue.secret.metadata.name && - !showAuthSecretField({ model, getValue, watchDependency }) - ) -} - -function showAuthSecretField({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComPerconaXtraDB/spec') - const modelPathValue = getValue(model, '/resources/kubedbComPerconaXtraDB/spec') - return !!(modelPathValue && modelPathValue.authSecret && modelPathValue.authSecret.name) -} - -function showNewSecretCreateField({ model, getValue, watchDependency, commit }) { - const resp = - !showAuthSecretField({ model, getValue, watchDependency }) && - !showAuthPasswordField({ model, getValue, watchDependency }) - const secret = getValue(model, '/resources/secret_auth') - if (resp && !secret) { - commit('wizard/model$update', { - path: '/resources/secret_auth', - value: { - data: { - password: '', - }, - }, - force: true, - }) - } - return resp -} - -// ********************* Database Mode *********************** -function isNotStandaloneMode({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - return mode !== 'Standalone' -} - -function showCommonStorageClassAndSizeField({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - const validType = ['Standalone', 'Replicaset'] - return validType.includes(mode) -} -function setDatabaseMode({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/resources/kubedbComPerconaXtraDB/spec') - - watchDependency('model#/resources/kubedbComPerconaXtraDB/spec') - if (modelPathValue.shardTopology) { - return 'Sharded' - } else if (modelPathValue.replicaSet) { - return 'Replicaset' - } else { - return 'Standalone' - } -} - -let storageClassList = [] -async function getStorageClassNames( - { axios, storeGet, commit, model, getValue, watchDependency, discriminator }, - mode, -) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const databaseModeShard = getValue(discriminator, '/activeDatabaseMode') === 'Sharded' - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/storage.k8s.io/v1/storageclasses`, - { - params: { - filter: { items: { metadata: { name: null, annotations: 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 - }) - storageClassList = resources - const path = - mode === 'shard' - ? '/resources/kubedbComPerconaXtraDB/spec/shardTopology/shard/storage/storageClassName' - : '/resources/kubedbComPerconaXtraDB/spec/storage/storageClassName' - const initialStorageClass = getValue(model, path) - if (!initialStorageClass) setStorageClass({ getValue, commit, model, discriminator }) - return resources -} - -function setStorageClass({ getValue, commit, model, discriminator }) { - const deletionPolicy = - getValue(model, 'resources/kubedbComPerconaXtraDB/spec/deletionPolicy') || '' - const suffix = '-retain' - let storageClass = '' - - const simpleClassList = storageClassList.filter((item) => { - return !item.metadata?.name?.endsWith(suffix) - }) - - const retainClassList = storageClassList.filter((item) => { - return item.metadata?.name?.endsWith(suffix) - }) - - const defaultSimpleList = simpleClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] - ) - }) - - const defaultRetainList = retainClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] - ) - }) - - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - if (simpleClassList.length > 1) { - const found = defaultSimpleList.length ? defaultSimpleList[0] : simpleClassList[0] - storageClass = found.value - } else if (simpleClassList.length === 1) { - storageClass = simpleClassList[0]?.value - } else { - const found = defaultRetainList.length - ? defaultRetainList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found - } - } else { - if (retainClassList.length > 1) { - const found = defaultRetainList.length ? defaultRetainList[0] : retainClassList[0] - storageClass = found.value - } else if (retainClassList.length === 1) { - storageClass = retainClassList[0]?.value - } else { - const found = defaultSimpleList.length - ? defaultSimpleList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found - } - } - - const mode = getValue(discriminator, '/activeDatabaseMode') - - if (mode === 'Sharded') { - commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/spec/shardTopology/shard/storage/storageClassName', - value: storageClass, - force: true, - }) - commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/spec/shardTopology/configServer/storage/storageClassName', - value: storageClass, - force: true, - }) - commit('wizard/model$delete', '/resources/kubedbComPerconaXtraDB/spec/storage') - } else { - commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/spec/storage/storageClassName', - value: storageClass, - force: true, - }) - } -} - -function updateConfigServerStorageClass({ getValue, model, commit }) { - const storageClass = - getValue( - model, - '/resources/kubedbComPerconaXtraDB/spec/shardTopology/shard/storage/storageClassName', - ) || '' - commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/spec/shardTopology/configServer/storage/storageClassName', - value: storageClass, - force: true, - }) -} - -function deleteDatabaseModePath({ discriminator, getValue, commit, model }) { - const mode = getValue(discriminator, '/activeDatabaseMode') - const modelSpec = getValue(model, '/resources/kubedbComPerconaXtraDB/spec') - if (mode === 'Sharded') { - commit('wizard/model$delete', '/resources/kubedbComPerconaXtraDB/spec/replicaSet') - commit('wizard/model$delete', '/resources/kubedbComPerconaXtraDB/spec/replicas') - commit('wizard/model$delete', '/resources/kubedbComPerconaXtraDB/spec/storage') - commit('wizard/model$delete', '/resources/kubedbComPerconaXtraDB/spec/podTemplate') - commit('wizard/model$delete', '/resources/kubedbComPerconaXtraDB/spec/configSecret') - - commit('wizard/model$delete', '/resources/secret_config') - - if (!modelSpec.shardTopology) { - commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/spec/shardTopology', - value: { - configServer: { - replicas: 3, - storage: { - resources: { - requests: { - storage: '', - }, - }, - }, - }, - mongos: { - replicas: 2, - }, - shard: { - replicas: 3, - shards: 3, - storage: { - resources: { - requests: { - storage: '', - }, - }, - }, - }, - }, - force: true, - }) - } - } else if (mode === 'Replicaset') { - commit('wizard/model$delete', '/resources/kubedbComPerconaXtraDB/spec/shardTopology') - - commit('wizard/model$delete', '/resources/secret_shard_config') - commit('wizard/model$delete', '/resources/secret_configserver_config') - commit('wizard/model$delete', '/resources/secret_mongos_config') - - if (!modelSpec.replicaSet) { - commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/spec/replicaSet', - value: { name: '' }, - force: true, - }) - commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/spec/replicas', - value: 3, - force: true, - }) - } - } else if (mode === 'Standalone') { - commit('wizard/model$delete', '/resources/kubedbComPerconaXtraDB/spec/shardTopology') - - commit('wizard/model$delete', '/resources/kubedbComPerconaXtraDB/spec/replicaSet') - commit('wizard/model$delete', '/resources/kubedbComPerconaXtraDB/spec/replicas') - - commit('wizard/model$delete', '/resources/secret_shard_config') - commit('wizard/model$delete', '/resources/secret_configserver_config') - commit('wizard/model$delete', '/resources/secret_mongos_config') - } -} - -function isEqualToDatabaseMode({ getValue, watchDependency, discriminator }, value) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - return mode === value -} - -// ************************** TLS ******************************88 - -function setApiGroup() { - return 'cert-manager.io' -} - -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - watchDependency('model#/resources/kubedbComPerconaXtraDB/spec/tls/issuerRef/apiGroup') - watchDependency('model#/resources/kubedbComPerconaXtraDB/spec/tls/issuerRef/kind') - watchDependency('model#/metadata/release/namespace') - const apiGroup = getValue(model, '/resources/kubedbComPerconaXtraDB/spec/tls/issuerRef/apiGroup') - const kind = getValue(model, '/resources/kubedbComPerconaXtraDB/spec/tls/issuerRef/kind') - const namespace = getValue(model, '/metadata/release/namespace') - - let url - if (kind === 'Issuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/namespaces/${namespace}/issuers` - } else if (kind === 'ClusterIssuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/clusterissuers` - } - - if (!url) return [] - - 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 [] - } -} - -async function hasIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await getIssuerRefsName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !!(resp && resp.length) -} - -async function hasNoIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await hasIssuerRefName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !resp -} - -function setClusterAuthMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComPerconaXtraDB/spec/clusterAuthMode') - return val || 'x509' -} - -function setSSLMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComPerconaXtraDB/spec/sslMode') - return val || 'requireSSL' -} - -function showTlsConfigureSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configureTLS') - const configureStatus = getValue(discriminator, '/configureTLS') - return configureStatus -} - -function onTlsConfigureChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/configureTLS') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/spec/tls', - value: { issuerRef: {}, certificates: [] }, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComPerconaXtraDB/spec/tls') - commit('wizard/model$delete', '/resources/kubedbComPerconaXtraDB/spec/clusterAuthMode') - commit('wizard/model$delete', '/resources/kubedbComPerconaXtraDB/spec/sslMode') - } -} - -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} - -/****** Monitoring *********/ - -function showMonitoringSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/enableMonitoring') - const configureStatus = getValue(discriminator, '/enableMonitoring') - return configureStatus -} - -function onEnableMonitoringChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/enableMonitoring') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/spec/monitor', - value: {}, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComPerconaXtraDB/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, getValue }) { - watchDependency('discriminator#/customizeExporter') - const configureStatus = getValue(discriminator, '/customizeExporter') - return configureStatus -} - -function onCustomizeExporterChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/customizeExporter') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/spec/monitor/prometheus/exporter', - value: {}, - force: true, - }) - } else { - commit( - 'wizard/model$delete', - '/resources/kubedbComPerconaXtraDB/spec/monitor/prometheus/exporter', - ) - } -} - -// ********************************* Initialization & Backup ************************************* -const stashAppscodeComRestoreSession_init = { - spec: { - repository: { - name: '', - }, - rules: [ - { - snapshots: ['latest'], - }, - ], - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} -const initScript = { - scriptPath: '', - secret: { - secretName: '', - }, -} -const stashAppscodeComRepository_init_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const stashAppscodeComRepository_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const restoreSessionInitRunTimeSettings = { - container: { - resources: { - requests: { - cpu: '', - memory: '', - }, - limits: { - cpu: '', - memory: '', - }, - }, - nice: { - adjustment: null, - }, - ionice: { - class: null, - classData: null, - }, - securityContext: { - privileged: false, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - env: [], - envFrom: [], - }, - pod: { - serviceAccountName: '', - imagePullSecrets: [], - securityContext: { - fsGroup: null, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - }, -} - -const stashAppscodeComBackupConfiguration = { - spec: { - repository: { - name: '', - }, - retentionPolicy: { - keepLast: 5, - name: 'keep-last-5', - prune: true, - }, - schedule: '*/5 * * * *', - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} - -function disableInitializationSection({ model, getValue, watchDependency }) { - const initialized = getValue(model, '/resources/kubedbComPerconaXtraDB/spec/init/initialized') - watchDependency('model#/resources/kubedbComPerconaXtraDB/spec/init/initialized') - return !!initialized -} - -function valueExists(value, getValue, path) { - const val = getValue(value, path) - if (val) return true - else return false -} - -function initPrePopulateDatabase({ getValue, model }) { - const waitForInitialRestore = getValue( - model, - '/resources/kubedbComPerconaXtraDB/spec/init/waitForInitialRestore', - ) - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - const script = getValue(model, '/resources/kubedbComPerconaXtraDB/spec/init/script') - - return waitForInitialRestore || !!stashAppscodeComRestoreSession_init || !!script ? 'yes' : 'no' -} - -function onPrePopulateDatabaseChange({ commit, getValue, discriminator, model }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - if (prePopulateDatabase === 'no') { - // delete related properties - commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/spec/init/waitForInitialRestore', - value: false, - }) - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - commit('wizard/model$delete', '/resources/kubedbComPerconaXtraDB/spec/init/script') - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else { - const dbName = getValue(model, '/metadata/release/name') - // set stashAppscodeComRestoreSession_init if it doesn't exist - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - force: true, - }) - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - } - } -} - -function initDataSource({ getValue, model }) { - const script = getValue(model, '/resources/kubedbComPerconaXtraDB/spec/init/script') - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - - if (script) return 'script' - else if (stashAppscodeComRestoreSession_init) return 'stashBackup' - else return undefined -} - -function onDataSourceChange({ commit, getValue, discriminator, model }) { - const dataSource = getValue(discriminator, '/dataSource') - - commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/spec/init/waitForInitialRestore', - value: dataSource === 'stashBackup', - force: true, - }) - - if (dataSource === 'script') { - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - - // create a new script if there is no script property - if (!valueExists(model, getValue, '/resources/kubedbComPerconaXtraDB/spec/init/script')) - commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/spec/init/script', - value: initScript, - }) - } else if (dataSource === 'stashBackup') { - commit('wizard/model$delete', '/resources/kubedbComPerconaXtraDB/spec/init/script') - - // create a new stashAppscodeComRestoreSession_init if there is no stashAppscodeComRestoreSession_init property - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - const dbName = getValue(model, '/metadata/release/name') - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - }) - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - } - } -} - -// // for script -function initVolumeType({ getValue, model }) { - const configMap = getValue( - model, - '/resources/kubedbComPerconaXtraDB/spec/init/script/configMap/name', - ) - const secret = getValue( - model, - '/resources/kubedbComPerconaXtraDB/spec/init/script/secret/secretName', - ) - - if (configMap) return 'configMap' - else if (secret) return 'secret' - else return undefined -} - -function onVolumeTypeChange({ commit, getValue, discriminator, model }) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - if (sourceVolumeType === 'configMap') { - // add configMap object and delete secret object - commit('wizard/model$delete', '/resources/kubedbComPerconaXtraDB/spec/init/script/secret') - - if ( - !valueExists(model, getValue, '/resources/kubedbComPerconaXtraDB/spec/init/script/configMap') - ) { - commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/spec/init/script/configMap', - value: { - name: '', - }, - }) - } - } else if (sourceVolumeType === 'secret') { - // delete configMap object and add secret object - commit('wizard/model$delete', '/resources/kubedbComPerconaXtraDB/spec/init/script/configMap') - - if ( - !valueExists(model, getValue, '/resources/kubedbComPerconaXtraDB/spec/init/script/secret') - ) { - commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/spec/init/script/secret', - value: { - secretName: '', - }, - }) - } - } -} - -function showInitializationForm({ getValue, discriminator, watchDependency }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - watchDependency('discriminator#/prePopulateDatabase') - return prePopulateDatabase === 'yes' -} - -function showScriptOrStashForm({ getValue, discriminator, watchDependency }, value) { - const dataSource = getValue(discriminator, '/dataSource') - watchDependency('discriminator#/dataSource') - return dataSource === value -} - -function showConfigMapOrSecretName({ getValue, discriminator, watchDependency }, value) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - watchDependency('discriminator#/sourceVolumeType') - return sourceVolumeType === value -} - -// for stash backup -function initializeNamespace({ getValue, model }) { - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} - -function showRepositorySelectOrCreate({ getValue, discriminator, watchDependency }, value) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - return repositoryChoise === value -} - -function onInitRepositoryChoiseChange({ getValue, discriminator, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - if (repositoryChoise === 'select') { - // delete stashAppscodeComRepository_init_repo from model - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else if (repositoryChoise === 'create') { - // add stashAppscodeComRepository_init_repo to model - commit('wizard/model$update', { - path: 'resources/stashAppscodeComRepository_init_repo', - value: stashAppscodeComRepository_init_repo, - }) - - const repositoryName = `${getValue(model, '/metadata/release/name')}-init-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: repositoryName, - }) - } -} - -function initCustomizeRestoreJobRuntimeSettings({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function initCustomizeRestoreJobRuntimeSettingsForBackup({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function onCustomizeRestoreJobRuntimeSettingsChange({ commit, getValue, discriminator, model }) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - value: restoreSessionInitRunTimeSettings, - }) - } - } -} - -function onCustomizeRestoreJobRuntimeSettingsChangeForBackup({ - commit, - getValue, - discriminator, - model, -}) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - value: {}, - force: true, - }) - } - } -} - -function showRuntimeForm({ discriminator, getValue, watchDependency }, value) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - watchDependency('discriminator#/customizeRestoreJobRuntimeSettings') - return customizeRestoreJobRuntimeSettings === value -} - -async function getImagePullSecrets({ getValue, model, watchDependency, axios, storeGet }) { - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - - let resources = await getNamespacedResourceList(axios, storeGet, { - namespace, - group: 'core', - version: 'v1', - resource: 'secrets', - }) - - resources = resources.filter((item) => { - const validType = ['kubernetes.io/dockerconfigjson'] - return validType.includes(item.type) - }) - - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: { name: name }, - } - }) -} - -function showBackupOptions({ discriminator, getValue, watchDependency }, backup) { - const backupEnabled = getValue(discriminator, '/backupEnabled') - if (backupEnabled) { - if (backup === 'alert') return true - else return false - } else { - if (backup === 'alert') return false - else return true - } -} - -function isBlueprintOption({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/blueprintOptions') - const blueprintOptions = getValue(discriminator, '/blueprintOptions') - return blueprintOptions === value -} - -function ifUsagePolicy({ discriminator, getValue, watchDependency, model }, value) { - watchDependency( - 'model#/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', - ) - const usagePolicy = getValue( - model, - '/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', - ) - return usagePolicy === value -} - -async function getBlueprints({ getValue, model, setDiscriminatorValue, axios, storeGet }, backup) { - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const url = `clusters/${username}/${clusterName}/proxy/core.kubestash.com/v1alpha1/backupblueprints` - - try { - const resp = await axios.get(url) - let data = resp.data.items - return data - } catch (e) { - console.log(e) - } -} - -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} - -async function fetchNamespaces({ axios, storeGet }) { - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const group = storeGet('/route/params/group') - const version = storeGet('/route/params/version') - const resource = storeGet('/route/params/resource') - - const url = `clusters/${username}/${clusterName}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews` - - try { - const resp = await axios.post(url, { - _recurringCall: false, - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], - }, - }) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] - } - } catch (e) { - console.log(e) - } - return [] -} - -async function fetchNames( - { getValue, axios, storeGet, watchDependency, discriminator }, - version, - type, - discriminatorName, -) { - watchDependency(`discriminator#/${discriminatorName}`) - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const namespace = getValue(discriminator, `${discriminatorName}`) - const url = - type !== 'secrets' - ? `clusters/${username}/${clusterName}/proxy/storage.kubestash.com/${version}/namespaces/${namespace}/${type}` - : `clusters/${username}/${clusterName}/proxy/core/${version}/namespaces/${namespace}/${type}` - try { - if (namespace) { - const resp = await axios.get(url) - let data = resp.data.items - data = data.map((ele) => ele.metadata.name) - return data - } - } catch (e) { - console.log(e) - } - return [] -} - -// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// FOR Backup Configuration - -// schedule backup - -function getBackupConfigsAndAnnotations(getValue, model) { - const stashAppscodeComBackupConfiguration = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration', - ) - - const coreKubestashComBackupConfiguration = getValue( - model, - '/resources/coreKubestashComBackupConfiguration', - ) - const kubeStashTarget = coreKubestashComBackupConfiguration?.spec?.target - - const mongoDB = getValue(model, '/resources/kubedbComPerconaXtraDB') - const mongoDbKind = mongoDB?.apiVersion?.split('/')?.at(0) - - let isKubeStash = false - if ( - mongoDB?.kind === kubeStashTarget.kind && - mongoDB?.metadata?.name === kubeStashTarget?.name && - mongoDB?.metadata?.namespace === kubeStashTarget?.namespace && - mongoDbKind === kubeStashTarget?.apiGroup - ) { - isKubeStash = true - } - - const kubedbComPerconaXtraDBAnnotations = - getValue(model, '/resources/kubedbComPerconaXtraDB/metadata/annotations') || {} - - const isBluePrint = Object.keys(kubedbComPerconaXtraDBAnnotations).some( - (k) => - k === 'stash.appscode.com/backup-blueprint' || - k === 'stash.appscode.com/schedule' || - k.startsWith('params.stash.appscode.com/'), - ) - - return { - stashAppscodeComBackupConfiguration, - isBluePrint, - isKubeStash, - } -} - -function deleteKubeDbComMongDbAnnotation(getValue, model, commit) { - const annotations = - getValue(model, '/resources/kubedbComPerconaXtraDB/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/kubedbComPerconaXtraDB/metadata/annotations', - value: filteredAnnotations, - }) -} - -function addKubeDbComMongDbAnnotation(getValue, model, commit, key, value, force) { - const annotations = - getValue(model, '/resources/kubedbComPerconaXtraDB/metadata/annotations') || {} - - if (annotations[key] === undefined) { - annotations[key] = value - } else if (force) { - annotations[key] = value - } - - commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/metadata/annotations', - value: annotations, - force: true, - }) -} - -function initScheduleBackupForEdit({ getValue, model, setDiscriminatorValue }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function initScheduleBackup({ getValue, model }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function onScheduleBackupChange({ commit, getValue, discriminator, model }) { - 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 kubedbComPerconaXtraDB annotation - deleteKubeDbComMongDbAnnotation(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, - }) - } - } -} - -// backup form -function showBackupForm({ getValue, discriminator, watchDependency }) { - const scheduleBackup = getValue(discriminator, '/scheduleBackup') - watchDependency('discriminator#/scheduleBackup') - - if (scheduleBackup === 'yes') return true - else return false -} - -// invoker form -async function initBackupInvoker({ getValue, model, storeGet, commit, axios }) { - const { stashAppscodeComBackupConfiguration, isBluePrint, isKubeStash } = - getBackupConfigsAndAnnotations(getValue, model) - - const apiGroup = getValue(model, '/metadata/resource/group') - let kind = getValue(model, '/metadata/resource/kind') - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const name = storeGet('/route/params/name') - const namespace = storeGet('/route/query/namespace') - const group = storeGet('/route/params/group') - const version = storeGet('/route/params/version') - const resource = storeGet('/route/params/resource') - let labels = {} - - const sessions = getValue(model, '/resources/coreKubestashComBackupConfiguration/spec/sessions') - sessions[0].repositories[0].name = name - sessions[0].repositories[0].directory = `/${name}` - - commit('wizard/model$update', { - path: '/resources/coreKubestashComBackupConfiguration/spec/sessions', - value: sessions, - force: true, - }) - - const url = `clusters/${username}/${clusterName}/proxy/${group}/${version}/namespaces/${namespace}/${resource}/${name}` - - try { - const resp = await axios.get(url) - labels = resp.data.metadata.labels - kind = resp.data.kind - } catch (e) { - console.log(e) - } - - commit('wizard/model$update', { - path: '/metadata/release', - value: { - labels: labels, - name: name, - namespace: namespace, - }, - force: true, - }) - - commit('wizard/model$update', { - path: '/resources/coreKubestashComBackupConfiguration/metadata', - value: { - labels: labels, - name: name, - namespace: namespace, - }, - force: true, - }) - - commit('wizard/model$update', { - path: '/resources/coreKubestashComBackupConfiguration/spec/target', - value: { - apiGroup: apiGroup, - kind: kind, - name: name, - namespace: namespace, - }, - force: true, - }) - - let isStashPresetEnable = false - try { - const url = `/clusters/${username}/${clusterName}/proxy/ui.k8s.appscode.com/v1alpha1/features` - const resp = await axios.get(url) - const stashFeature = resp.data.items.filter((item) => { - return item.metadata.name === 'stash-presets' - }) - if (stashFeature[0].status?.enabled) { - isStashPresetEnable = true - } - } catch (e) { - console.log(e) - } - let schedule = '' - let storageRefName = '' - let storageRefNamespace = '' - let retentionPolicyName = '' - let retentionPolicyNamespace = '' - let encryptionSecretName = '' - let encryptionSecretNamespace = '' - - if (isStashPresetEnable) { - try { - const url = `clusters/${username}/${clusterName}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/stash-presets` - const resp = await axios.get(url) - schedule = resp.data.spec.values.spec.backup.kubestash.schedule - storageRefName = resp.data.spec.values.spec.backup.kubestash.storageRef.name - storageRefNamespace = resp.data.spec.values.spec.backup.kubestash.storageRef.namespace - retentionPolicyName = resp.data.spec.values.spec.backup.kubestash.retentionPolicy.name - retentionPolicyNamespace = - resp.data.spec.values.spec.backup.kubestash.retentionPolicy.namespace - encryptionSecretName = resp.data.spec.values.spec.backup.kubestash.encryptionSecret.name - encryptionSecretNamespace = - resp.data.spec.values.spec.backup.kubestash.encryptionSecret.namespace - } catch (e) { - console.log(e) - } - } - setInitSchedule( - { getValue, commit, model }, - 'resources/coreKubestashComBackupConfiguration/spec/sessions/', - schedule, - ) - setFileValueFromStash( - { getValue, commit, model }, - 'resources/coreKubestashComBackupConfiguration/spec/backends', - 'storageRef', - 'namespace', - storageRefNamespace, - ) - setFileValueFromStash( - { getValue, commit, model }, - 'resources/coreKubestashComBackupConfiguration/spec/backends', - 'storageRef', - 'name', - storageRefName, - ) - setFileValueFromStash( - { getValue, commit, model }, - 'resources/coreKubestashComBackupConfiguration/spec/backends', - 'retentionPolicy', - 'namespace', - retentionPolicyNamespace, - ) - setFileValueFromStash( - { getValue, commit, model }, - 'resources/coreKubestashComBackupConfiguration/spec/backends', - 'retentionPolicy', - 'name', - retentionPolicyName, - ) - setFileValueFromStash( - { getValue, commit, model }, - 'resources/coreKubestashComBackupConfiguration/spec/sessions', - 'encryptionSecret', - 'namespace', - encryptionSecretNamespace, - ) - setFileValueFromStash( - { getValue, commit, model }, - 'resources/coreKubestashComBackupConfiguration/spec/sessions', - 'encryptionSecret', - 'name', - encryptionSecretName, - ) - - if (isKubeStash) return 'backupConfiguration' - else if (stashAppscodeComBackupConfiguration) return 'legacyBackupConfiguration' - else if (isBluePrint) return 'backupBlueprint' - else return 'backupConfiguration' -} - -function initBlueprint() { - return 'create' -} -function initUsagePolicy() { - return 'Same' -} - -function onBackupInvokerChange({ getValue, discriminator, commit, model }) { - const backupInvoker = getValue(discriminator, '/backupInvoker') - - if (backupInvoker === 'backupConfiguration') { - // delete annotation and create backup config object - deleteKubeDbComMongDbAnnotation(getValue, model, commit) - const dbName = getValue(model, '/metadata/release/name') - - if (!valueExists(model, getValue, '/resources/stashAppscodeComBackupConfiguration')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration', - value: stashAppscodeComBackupConfiguration, - }) - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, - force: true, - }) - } - } else if (backupInvoker === 'backupBlueprint') { - // delete backup configuration object and create the annotation - commit('wizard/model$delete', '/resources/stashAppscodeComBackupConfiguration') - addKubeDbComMongDbAnnotation(getValue, model, commit, 'stash.appscode.com/backup-blueprint', '') - } -} - -function showInvokerForm({ getValue, discriminator, watchDependency }, value) { - const backupInvoker = getValue(discriminator, '/backupInvoker') - watchDependency('discriminator#/backupInvoker') - - return backupInvoker === value -} - -// backup configuration form -function initalizeTargetReferenceName({ getValue, model, watchDependency }) { - const databaseName = getValue(model, '/metadata/release/name') - watchDependency('model#/metadata/release/name') - - return databaseName -} - -// restore session repository -function setInitialRestoreSessionRepo({ getValue, model }) { - const value = getValue(model, 'resources/stashAppscodeComRepository_init_repo') - return value ? 'create' : 'select' -} - -// backup config repository -function initRepositoryChoise({ getValue, model }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - - if (stashAppscodeComRepository_repo) return 'create' - else return 'select' -} +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} -function initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) { - const stashAppscodeComRepository_repo = getValue( +// ************************* common functions ******************************************** +// eslint-disable-next-line no-empty-pattern +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( model, - '/resources/stashAppscodeComRepository_repo', - ) - const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' - setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) - - return repoInitialSelectionStatus -} - -function onRepositoryChoiseChange({ getValue, discriminator, watchDependency, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - if (repositoryChoise === 'select') { - // delete the stashAppscodeComRepository_repo - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') - } else if (repositoryChoise === 'create') { - // create new stashAppscodeComRepository_repo - if (!valueExists(model, getValue, '/resources/stashAppscodeComRepository_repo')) { + store.state, + ) + + /********** Initialize Discriminator **************/ + + 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 autoscaleType = '' + let dbDetails = {} + let instance = {} + + function isConsole() { + const isKube = isKubedb() + + if (isKube) { + const dbName = storeGet('/route/params/name') || '' commit('wizard/model$update', { - path: '/resources/stashAppscodeComRepository_repo', - value: stashAppscodeComRepository_repo, + path: '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/databaseRef/name', + value: dbName, + force: true, }) - const repositoryName = `${getValue(model, '/metadata/release/name')}-repo` - // set this name in stashAppscodeComRestoreSession_init + 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/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, + path: '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/metadata/name', + value: modifiedName, + force: true, }) + const namespace = storeGet('/route/query/namespace') || '' + if (namespace) { + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/metadata/namespace', + value: namespace, + force: true, + }) + } } - } -} - -function onRepositoryNameChange({ getValue, model, commit }) { - const repositoryName = getValue(model, 'resources/stashAppscodeComRepository_repo/metadata/name') - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) -} - -function onInputChange( - { getValue, discriminator, commit, model }, - modelPath, - field, - subfield, - discriminatorName, -) { - const value = getValue(discriminator, `/${discriminatorName}`) - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') backends[0][field][subfield] = value - else backends[0]['repositories'][0][field][subfield] = value - commit('wizard/model$update', { - path: modelPath, - value: backends, - }) -} -function setFileValueFromStash({ getValue, commit, model }, modelPath, field, subfield, value) { - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') backends[0][field][subfield] = value - else backends[0]['repositories'][0][field][subfield] = value - commit('wizard/model$update', { - path: modelPath, - value: backends, - }) -} - -function onInputChangeSchedule( - { getValue, discriminator, watchDependency, commit, model }, - modelPath, - discriminatorName, -) { - watchDependency(`discriminator#/${discriminatorName}`) - const value = getValue(discriminator, `/${discriminatorName}`) - const session = getValue(model, modelPath) - session[0].scheduler.schedule = value - commit('wizard/model$update', { - path: modelPath, - value: session, - }) -} - -function setInitSchedule( - { getValue, discriminator, watchDependency, commit, model }, - modelPath, - value, -) { - const session = getValue(model, modelPath) - session[0].scheduler.schedule = value - commit('wizard/model$update', { - path: modelPath, - value: session, - }) -} - -function getDefault({ getValue, model }, modelPath, field, subfield) { - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') return backends[0][field][subfield] - else { - return backends[0]['repositories'][0][field][subfield] - } -} - -function getDefaultSchedule( - { getValue, discriminator, watchDependency, commit, model }, - modelPath, - discriminatorName, -) { - watchDependency(`model#/${modelPath}`) - const session = getValue(model, modelPath) - return session[0].scheduler.schedule -} - -// backup blueprint form -function getMongoAnnotations(getValue, model) { - const annotations = getValue(model, '/resources/kubedbComPerconaXtraDB/metadata/annotations') - return { ...annotations } || {} -} - -function initFromAnnotationValue({ getValue, model }, key) { - const annotations = getMongoAnnotations(getValue, model) - return annotations[key] -} - -function onBackupBlueprintNameChange({ getValue, discriminator, commit, model }) { - const backupBlueprintName = getValue(discriminator, '/backupBlueprintName') - addKubeDbComMongDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/backup-blueprint', - backupBlueprintName, - true, - ) -} - -function onBackupBlueprintScheduleChange({ getValue, discriminator, commit, model }) { - const backupBlueprintSchedule = getValue(discriminator, '/schedule') - addKubeDbComMongDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/schedule', - backupBlueprintSchedule, - true, - ) -} - -function initFromAnnotationKeyValue({ getValue, model }, prefix) { - const annotations = getMongoAnnotations(getValue, model) - const newOb = {} - Object.keys(annotations).forEach((key) => { - if (key.startsWith(prefix)) { - const newKey = key.replace(prefix, '') - newOb[newKey] = annotations[key] - } - }) - return newOb -} - -function onTaskParametersChange({ getValue, discriminator, model, commit }) { - const taskParameters = getValue(discriminator, '/taskParameters') - - const taskParamterKeys = Object.keys(taskParameters).map( - (tp) => `params.stash.appscode.com/${tp}`, - ) - const oldAnnotations = - getValue(model, '/resources/kubedbComPerconaXtraDB/metadata/annotations') || {} - const newAnnotations = {} - const filteredAnnotationKeys = Object.keys(oldAnnotations).filter( - (key) => !taskParamterKeys.includes(key) && !key.startsWith('params.stash.appscode.com/'), - ) - - filteredAnnotationKeys.forEach((key) => { - newAnnotations[key] = oldAnnotations[key] - }) - - Object.keys(taskParameters).forEach((tpk) => { - newAnnotations[`params.stash.appscode.com/${tpk}`] = taskParameters[tpk] - }) - - commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/metadata/annotations', - value: newAnnotations, - }) -} - -function isValueExistInModel({ model, getValue }, path) { - const modelValue = getValue(model, path) - return !!modelValue -} - -function onNamespaceChange({ commit, model, getValue }) { - const namespace = getValue(model, '/metadata/release/namespace') - const agent = getValue(model, '/resources/kubedbComPerconaXtraDB/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', - value: [namespace], - force: true, - }) - } -} - -function onLabelChange({ commit, model, getValue }) { - const labels = getValue(model, '/resources/kubedbComPerconaXtraDB/spec/metadata/labels') - - const agent = getValue(model, '/resources/kubedbComPerconaXtraDB/spec/monitor/agent') - - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) - } -} - -function onNameChange({ commit, model, getValue }) { - const dbName = getValue(model, '/metadata/release/name') - - const agent = getValue(model, '/resources/kubedbComPerconaXtraDB/spec/monitor/agent') - - const labels = getValue(model, '/resources/kubedbComPerconaXtraDB/spec/metadata/labels') - - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) + return !isKube } - const scheduleBackup = getValue(model, '/resources/stashAppscodeComBackupConfiguration') - - if (scheduleBackup) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_repo') - if (creatingNewRepo) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: `${dbName}-repo`, - force: true, - }) - } + function isKubedb() { + return !!storeGet('/route/params/actions') } - const prePopulateDatabase = getValue(model, '/resources/stashAppscodeComRestoreSession_init') - - if (prePopulateDatabase) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_init_repo') - if (creatingNewRepo) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: `${dbName}-init-repo`, - force: true, - }) + async function getDbDetails() { + const annotations = + getValue( + model, + '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/metadata/annotations', + ) || {} + instance = annotations['kubernetes.io/instance-type'] + const owner = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + const namespace = + storeGet('/route/query/namespace') || + getValue( + model, + '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/metadata/namespace', + ) || + '' + const name = + storeGet('/route/params/name') || + getValue( + model, + '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/databaseRef/name', + ) || + '' + + if (namespace && name) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/perconaxtradbs/${name}`, + ) + dbDetails = resp.data || {} + setDiscriminatorValue('/dbDetails', true) + } catch (e) { + console.log(e) + } } - } - // to reset configSecret name field - const hasSecretConfig = getValue(model, '/resources/secret_config') - if (hasSecretConfig) { commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/spec/configSecret/name', - value: `${dbName}-config`, + path: `/metadata/release/name`, + value: name, force: true, }) - } - - // to reset shard configSecret name field - const hasSecretShardConfig = getValue(model, '/resources/secret_shard_config') - if (hasSecretShardConfig) { commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/spec/shardTopology/shard/configSecret/name', - value: `${dbName}-shard-config`, + path: `/metadata/release/namespace`, + value: namespace, force: true, }) - } - - // to reset shard configSecret name field - const hasSecretConfigServerConfig = getValue(model, '/resources/secret_configserver_config') - if (hasSecretConfigServerConfig) { commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/spec/shardTopology/configServer/configSecret/name', - value: `${dbName}-configserver-config`, + path: `/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/databaseRef/name`, + value: name, force: true, }) - } - - // to reset mongos configSecret name field - const hasSecretMongosConfig = getValue(model, '/resources/secret_mongos_config') - if (hasSecretMongosConfig) { commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/spec/shardTopology/mongos/configSecret/name', - value: `${dbName}-mongos-config`, + path: `/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/metadata/labels`, + value: dbDetails.metadata.labels, force: true, }) } -} -function returnFalse() { - return false -} + async function getNamespaces() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function onAgentChange({ commit, model, getValue }) { - const agent = getValue(model, '/resources/kubedbComPerconaXtraDB/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', - value: [], - force: true, + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, }) - onNamespaceChange({ commit, model, getValue }) - onLabelChange({ commit, model, getValue }) - } else { - commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') - } -} - -/************************************* Database Secret Section ********************************************/ - -function getCreateAuthSecret({ model, getValue }) { - const authSecret = getValue(model, '/resources/kubedbComPerconaXtraDB/spec/authSecret') - - return !authSecret -} - -function showExistingSecretSection({ getValue, watchDependency, discriminator }) { - watchDependency('discriminator#/createAuthSecret') - - const hasAuthSecretName = getValue(discriminator, '/createAuthSecret') - return !hasAuthSecretName -} - -function showPasswordSection({ getValue, watchDependency, discriminator }) { - return !showExistingSecretSection({ - getValue, - watchDependency, - discriminator, - }) -} - -function setAuthSecretPassword({ model, getValue }) { - const encodedPassword = getValue(model, '/resources/secret_auth/data/password') - return encodedPassword ? decodePassword({}, encodedPassword) : '' -} - -function onAuthSecretPasswordChange({ getValue, discriminator, commit }) { - const stringPassword = getValue(discriminator, '/password') + const resources = (resp && resp.data && resp.data.items) || [] - if (stringPassword) { - commit('wizard/model$update', { - path: '/resources/secret_auth/data/password', - value: encodePassword({}, stringPassword), - force: true, - }) - commit('wizard/model$update', { - path: '/resources/secret_auth/data/username', - value: encodePassword({}, 'root'), - force: true, + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } }) - } else { - commit('wizard/model$delete', '/resources/secret_auth') } -} -// eslint-disable-next-line no-empty-pattern -function encodePassword({}, value) { - return btoa(value) -} + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } -// eslint-disable-next-line no-empty-pattern -function decodePassword({}, value) { - return atob(value) -} + // function onNamespaceChange() { + // const namespace = getValue(model, '/metadata/release/namespace') + // const agent = getValue(model, '/resources/kubedbComPerconaXtraDB/spec/monitor/agent') + // if (agent === 'prometheus.io') { + // commit('wizard/model$update', { + // path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + // value: [namespace], + // force: true, + // }) + // } + // } -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/resources/kubedbComPerconaXtraDB/spec/authSecret') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/resources/secret_auth') + function onNamespaceChange() { + const namespace = getValue( + model, + '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/metadata/namespace', + ) + if (!namespace) { + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/databaseRef/name', + ) + } } -} -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') + async function getDbs() { + // watchDependency('model#/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/metadata/namespace') + const namespace = getValue( + model, + '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/metadata/namespace', + ) + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - try { const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises`, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, + params: { filter: { items: { metadata: { name: 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) - }) + const resources = (resp && resp.data && resp.data.items) || [] - filteredSecrets.map((item) => { + return resources.map((item) => { const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + return { + text: name, + value: name, + } }) - return filteredSecrets - } catch (e) { - console.log(e) - return [] } -} - -//////////////////////////////////////// Service Monitor ////////////////////////////////////////////////////// -//////////////////// service monitor /////////////////// - -function isEqualToServiceMonitorType({ rootModel, watchDependency }, value) { - watchDependency('rootModel#/spec/type') - return rootModel && rootModel.spec && rootModel.spec.type === value -} - -//////////////////// custom config ///////////////// -function onConfigurationSourceChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSource') - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_config') - } else { - const value = getValue(model, '/resources/secret_config') - if (!value) { + function initMetadata() { + const dbName = + getValue( + model, + '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/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/secret_config', - value: {}, + path: '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/metadata/name', + value: modifiedName, force: true, }) - } - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/spec/configSecret/name', - value: configSecretName, - force: true, - }) - } -} - -function onConfigurationChange({ getValue, commit, discriminator, model }) { - const value = getValue(discriminator, '/configuration') - commit('wizard/model$update', { - path: '/resources/secret_config/stringData/mongod.conf', - value: value, - force: true, - }) - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/spec/configSecret/name', - value: configSecretName, - force: true, - }) -} - -function setConfigurationSource({ model, getValue }) { - const modelValue = getValue(model, '/resources/secret_config') - if (modelValue) { - return 'create-new-config' - } - return 'use-existing-config' -} - -function setSecretConfigNamespace({ getValue, model, watchDependency }) { - watchDependency('model#/metadata/release/namespace') - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} - -//////////////////// custom config for sharded topology ///////////////// -function setConfigurationSourceShard({ model, getValue, discriminator }) { - const src = getValue(discriminator, '/configurationSourceShard') - if (src) return src - const value = getValue(model, '/resources/secret_shard_config') - return value ? 'create-new-config' : 'use-existing-config' -} - -function setConfigurationSourceConfigServer({ model, getValue, discriminator }) { - const src = getValue(discriminator, '/configurationSourceConfigServer') - if (src) return src - const value = getValue(model, '/resources/secret_configserver_config') - return value ? 'create-new-config' : 'use-existing-config' -} - -function setConfigurationSourceMongos({ model, getValue, discriminator }) { - const src = getValue(discriminator, '/configurationSourceMongos') - if (src) return src - const value = getValue(model, '/resources/secret_mongos_config') - return value ? 'create-new-config' : 'use-existing-config' -} - -function isSchemaOf(schema) { - if (schema === 'discriminator#/configurationSourceShard') { - return 'shard' - } else if (schema === 'discriminator#/configurationSourceConfigServer') { - return 'configserver' - } else { - return 'mongos' + // delete the other type object from model + if (type === 'compute') + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/storage', + ) + if (type === 'storage') + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/compute', + ) } -} -function disableConfigSourceOption({ - itemCtx, - discriminator, - getValue, - watchDependency, - elementUi, -}) { - watchDependency('discriminator#/configurationSourceShard') - watchDependency('discriminator#/configurationSourceConfigServer') - watchDependency('discriminator#/configurationSourceMongos') - const configSrcShard = getValue(discriminator, '/configurationSourceShard') - const configSrcConfigServer = getValue(discriminator, '/configurationSourceConfigServer') - const configSrcMongos = getValue(discriminator, '/configurationSourceMongos') - if ( - itemCtx.value !== 'use-existing-config' && - itemCtx.value !== 'create-new-config' && - (configSrcShard === `same-as-${isSchemaOf(elementUi.schema.$ref)}-config-secret` || - configSrcConfigServer === `same-as-${isSchemaOf(elementUi.schema.$ref)}-config-secret` || - configSrcMongos === `same-as-${isSchemaOf(elementUi.schema.$ref)}-config-secret`) - ) { - return true - } - if ( - itemCtx.value === 'same-as-shard-config-secret' && - configSrcShard !== 'use-existing-config' && - configSrcShard !== 'create-new-config' - ) { - return true - } - if ( - itemCtx.value === 'same-as-configserver-config-secret' && - configSrcConfigServer !== 'use-existing-config' && - configSrcConfigServer !== 'create-new-config' - ) { - return true - } - if ( - itemCtx.value === 'same-as-mongos-config-secret' && - configSrcMongos !== 'use-existing-config' && - configSrcMongos !== 'create-new-config' - ) { - return true - } - return false -} + async function fetchTopologyMachines() { + const instance = hasAnnotations() -function onConfigurationSourceMongosChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSourceMongos') - const configSecretName = `${getValue(model, '/metadata/release/name')}-mongos-config` - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_mongos_config') - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'mongos', - configurationSource, - '/configurationMongos', - ) - } else if (configurationSource === 'create-new-config') { - const value = getValue(model, '/resources/secret_mongos_config') - if (!value) { - commit('wizard/model$update', { - path: '/resources/secret_mongos_config', - value: {}, - force: true, - }) - } - commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/spec/shardTopology/mongos/configSecret/name', - value: configSecretName, - force: true, - }) - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'mongos', - configurationSource, - '/configurationMongos', - ) - } else if (configurationSource === 'same-as-shard-config-secret') { - transferConfigSecret({ commit, model, getValue }, 'shard', 'mongos') - } else if (configurationSource === 'same-as-configserver-config-secret') { - transferConfigSecret({ commit, model, getValue }, 'configserver', 'mongos') - } -} + 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) -function onConfigurationSourceShardChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSourceShard') - const configSecretName = `${getValue(model, '/metadata/release/name')}-shard-config` - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_shard_config') - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'shard', - configurationSource, - '/configurationShard', - ) - } else if (configurationSource === 'create-new-config') { - const value = getValue(model, '/resources/secret_shard_config') - if (!value) { - commit('wizard/model$update', { - path: '/resources/secret_shard_config', - value: {}, - force: true, - }) + const nodeGroups = resp.data?.spec?.nodeGroups || [] + setDiscriminatorValue('/topologyMachines', nodeGroups) + return nodeGroups + } catch (e) { + console.log(e) + return [] + } } - commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/spec/shardTopology/shard/configSecret/name', - value: configSecretName, - force: true, - }) - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'shard', - configurationSource, - '/configurationShard', - ) - } else if (configurationSource === 'same-as-configserver-config-secret') { - transferConfigSecret({ commit, model, getValue }, 'configserver', 'shard') - } else if (configurationSource === 'same-as-mongos-config-secret') { - transferConfigSecret({ commit, model, getValue }, 'mongos', 'shard') } -} -function onConfigurationSourceConfigServerChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSourceConfigServer') - const configSecretName = `${getValue(model, '/metadata/release/name')}-configserver-config` - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_configserver_config') - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'configserver', - configurationSource, - '/configurationConfigServer', - ) - } else if (configurationSource === 'create-new-config') { - const value = getValue(model, '/resources/secret_configserver_config') - if (!value) { - commit('wizard/model$update', { - path: '/resources/secret_configserver_config', - value: {}, - force: true, - }) - } - commit('wizard/model$update', { - path: '/resources/kubedbComPerconaXtraDB/spec/shardTopology/configServer/configSecret/name', - value: configSecretName, - force: true, - }) - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'configserver', - configurationSource, - '/configurationConfigServer', - ) - } else if (configurationSource === 'same-as-shard-config-secret') { - const configurationSourceReference = getValue(discriminator, '/configurationSourceShard') - transferConfigSecret( - { commit, model, getValue }, - 'shard', - 'configserver', - configurationSourceReference, - ) - } else if (configurationSource === 'same-as-mongos-config-secret') { - const configurationSourceReference = getValue(discriminator, '/configurationSourceMongos') - transferConfigSecret( - { commit, model, getValue }, - 'mongos', - 'configserver', - configurationSourceReference, - ) + function setTrigger(path) { + let value = getValue(model, `/resources/${path}`) + if (value) return value + return 'On' } -} - -function transferConfigSecret({ commit, model, getValue }, src, des) { - const isShardedMode = getValue(model, '/resources/kubedbComPerconaXtraDB/spec/shardTopology') - if (isShardedMode) { - commit('wizard/model$update', { - path: `/resources/kubedbComPerconaXtraDB/spec/shardTopology/${ - des === 'configserver' ? 'configServer' : des - }/configSecret/name`, - value: getValue( - model, - `/resources/kubedbComPerconaXtraDB/spec/shardTopology/${ - src === 'configserver' ? 'configServer' : src - }/configSecret/name`, - ), - force: true, - }) - commit('wizard/model$delete', `/resources/secret_${des}_config`) - } -} + function onTriggerChange(type) { + const trigger = getValue(discriminator, `/${type}/trigger`) + const commitPath = `/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/${type}/trigger` -function onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - configType, - configSrc, - discriminatorPath, -) { - if (configSrc === 'create-new-config') { - const value = getValue(discriminator, discriminatorPath) commit('wizard/model$update', { - path: `/resources/secret_${configType}_config/stringData/mongod.conf`, - value: value, + path: commitPath, + value: trigger ? 'On' : 'Off', force: true, }) } - const configSrcShard = getValue(discriminator, '/configurationSourceShard') - const configSrcConfigServer = getValue(discriminator, '/configurationSourceConfigServer') - const configSrcMongos = getValue(discriminator, '/configurationSourceMongos') - - if (configSrcShard === `same-as-${configType}-config-secret`) { - transferConfigSecret({ commit, model, getValue }, configType, 'shard') - } - if (configSrcConfigServer === `same-as-${configType}-config-secret`) { - transferConfigSecret({ commit, model, getValue }, configType, 'configserver') - } - if (configSrcMongos === `same-as-${configType}-config-secret`) { - transferConfigSecret({ commit, model, getValue }, configType, 'mongos') + + function setApplyToIfReady() { + return 'IfReady' } -} -function setConfiguration({ model, getValue }) { - return getValue(model, '/resources/secret_config/stringData/mongod.conf') -} + function hasAnnotations() { + const annotations = + getValue( + model, + '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/metadata/annotations', + ) || {} + const instance = annotations['kubernetes.io/instance-type'] -function setConfigurationShard({ model, getValue }) { - const value = getValue(model, '/resources/secret_shard_config/stringData/mongod.conf') - return value -} + return !!instance + } -function setConfigurationConfigServer({ model, getValue }) { - const value = getValue(model, '/resources/secret_configserver_config/stringData/mongod.conf') - return value -} + function hasNoAnnotations() { + return !hasAnnotations() + } -function setConfigurationMongos({ model, getValue }) { - const value = getValue(model, '/resources/secret_mongos_config/stringData/mongod.conf') - return value -} + function setAllowedMachine(minmax) { + const mx = instance?.includes(',') ? instance.split(',')[1] : '' + const mn = instance?.includes(',') ? instance.split(',')[0] : '' + const machineName = minmax === 'min' ? mn : mx -function setConfigurationFiles({ model, getValue }) { - const value = getValue(model, '/resources/secret_config/data/mongod.conf') - return atob(value) -} + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] + const machineData = nodeGroups.find((item) => item.topologyValue === machineName) + if (machineData) { + return { + machine: machineName, + cpu: machineData.allocatable?.cpu, + memory: machineData.allocatable?.memory, + } + } + return { machine: machineName || '', cpu: '', memory: '' } + } -function setConfigurationFilesShard({ model, getValue }) { - const value = getValue(model, '/resources/secret_shard_config/data/mongod.conf') - return atob(value) -} + async function getMachines(minmax) { + // watchDependency('discriminator#/topologyMachines') + const depends = minmax === 'min' ? 'max' : 'min' + const dependantPath = `/allowedMachine-${depends}` -function setConfigurationFilesConfigServer({ model, getValue }) { - const value = getValue(model, '/resources/secret_configserver_config/data/mongod.conf') - return atob(value) -} + // watchDependency(`discriminator#${dependantPath}`) + const dependantMachineObj = getValue(discriminator, dependantPath) + const dependantMachine = dependantMachineObj?.machine || '' -function setConfigurationFilesMongos({ model, getValue }) { - const value = getValue(model, '/resources/secret_mongos_config/data/mongod.conf') - return atob(value) -} + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] -function onSetCustomConfigChange({ discriminator, getValue, commit }) { - const value = getValue(discriminator, '/setCustomConfig') + const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) - if (value === 'no') { - commit('wizard/model$delete', '/resources/kubedbComPerconaXtraDB/spec/configSecret') - commit( - 'wizard/model$delete', - '/resources/kubedbComPerconaXtraDB/spec/shardTopology/shard/configSecret', - ) - commit( - 'wizard/model$delete', - '/resources/kubedbComPerconaXtraDB/spec/shardTopology/configServer/configSecret', - ) - commit( - 'wizard/model$delete', - '/resources/kubedbComPerconaXtraDB/spec/shardTopology/mongos/configSecret', - ) - commit('wizard/model$delete', '/resources/secret_config') - commit('wizard/model$delete', '/resources/secret_shard_config') - commit('wizard/model$delete', '/resources/secret_configserver_config') - commit('wizard/model$delete', '/resources/secret_mongos_config') - } -} + 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, + }, + } + }) -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + const filteredMachine = machines?.filter((item, ind) => + minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, + ) - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + return dependantIndex === -1 ? machines : filteredMachine } -} - -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} -function showScheduleBackup({ storeGet }) { - const operationQuery = storeGet('/route/params/actions') || '' - const isBackupOperation = operationQuery === 'edit-self-backupconfiguration' ? true : false - return !isBackupOperation -} + function onMachineChange(type) { + const annoPath = '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/metadata/annotations' + const annotations = getValue(model, annoPath) || {} + const instance = annotations['kubernetes.io/instance-type'] -///////////////////////// Autoscaler /////////////////// -let autoscaleType = '' -let dbDetails = {} + 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 -function isConsole({ storeGet, commit }) { - const isKube = isKubedb({ storeGet }) + const minMachineAllocatable = minMachineObj + ? { cpu: minMachineObj.cpu, memory: minMachineObj.memory } + : null + const maxMachineAllocatable = maxMachineObj + ? { cpu: maxMachineObj.cpu, memory: maxMachineObj.memory } + : null + const allowedPath = `/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/compute/${type}` - if (isKube) { - const dbName = storeGet('/route/params/name') || '' - commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/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] + 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, + }) } - const date = Math.floor(Date.now() / 1000) - const modifiedName = `${dbName}-${date}-autoscaling-${autoscaleType}` + } + + function setControlledResources(type) { + const list = ['cpu', 'memory'] + const path = `/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/compute/${type}/controlledResources` commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/metadata/name', - value: modifiedName, + path: path, + value: list, force: true, }) - const namespace = storeGet('/route/query/namespace') || '' - if (namespace) { - commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/metadata/namespace', - value: namespace, - 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 [] } - return !isKube -} - -function isKubedb({ storeGet }) { - return !!storeGet('/route/params/actions') -} - -function showOpsRequestOptions({ model, getValue, watchDependency, storeGet, discriminator }) { - if (isKubedb({ storeGet }) === true) return true - watchDependency( - 'model#/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/databaseRef/name', - ) - watchDependency('discriminator#/autoscalingType') - return ( - !!getValue( - model, - '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/databaseRef/name', - ) && !!getValue(discriminator, '/autoscalingType') - ) -} - -async function getNamespaces({ axios, storeGet }) { - 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 } } } }, - }) + function isNodeTopologySelected() { + // watchDependency( + // 'model#/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/compute/nodeTopology/name', + // ) + const nodeTopologyName = + getValue( + model, + '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/compute/nodeTopology/name', + ) || '' + return !!nodeTopologyName.length + } - const resources = (resp && resp.data && resp.data.items) || [] + function showOpsRequestOptions() { + if (isKubedb() === true) return true + // watchDependency( + // 'model#/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/databaseRef/name', + // ) + // watchDependency('discriminator#/autoscalingType') + return ( + !!getValue( + model, + '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/databaseRef/name', + ) && !!getValue(discriminator, '/autoscalingType') + ) + } - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, + 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, + }) + } } - }) -} - -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - watchDependency('model#/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/metadata/namespace') - const namespace = getValue( - model, - '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/metadata/namespace', - ) - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises`, - { - 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 isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } -async function getDbDetails({ commit, setDiscriminatorValue, axios, storeGet, getValue, model }) { - const owner = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - const namespace = - storeGet('/route/query/namespace') || - getValue(model, '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/metadata/namespace') || - '' - const name = - storeGet('/route/params/name') || - getValue( - model, - '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/databaseRef/name', - ) || - '' + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - if (namespace && name) { try { const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/perconaxtradbs/${name}`, + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, ) - dbDetails = resp.data || {} - setDiscriminatorValue('/dbDetails', true) + + 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 [] } } - commit('wizard/model$update', { - path: `/metadata/release/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/metadata/release/namespace`, - value: namespace, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/databaseRef/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/metadata/labels`, - value: dbDetails.metadata.labels, - force: true, - }) -} + 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 } }, + }, + }) -async function dbTypeEqualsTo({ watchDependency, commit }, type) { - watchDependency('discriminator#/dbDetails') + const items = (resp && resp.data && resp.data.items) || [] + ans = items + } catch (e) { + console.log(e) + } - const { spec } = dbDetails || {} - const { topology } = spec || {} - let verd = '' - if (topology) verd = 'topology' - else { - verd = 'combined' + return ans } - clearSpecModel({ commit }, verd) - return type === verd && spec -} -function clearSpecModel({ commit }, dbtype) { - if (dbtype === 'standalone') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/${autoscaleType}/cluster`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/${autoscaleType}/sentinel`, - ) - } else if (dbtype === 'cluster') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/${autoscaleType}/sentinel`, - ) - } else if (dbtype === 'sentinel') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/${autoscaleType}/cluster`, - ) + /****** Monitoring *********/ + + function showMonitoringSection() { + // watchDependency('discriminator#/enableMonitoring') + const configureStatus = getValue(discriminator, '/enableMonitoring') + return configureStatus } -} -function initMetadata({ getValue, discriminator, model, commit, storeGet }) { - const dbName = - getValue( - model, - '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/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) + function onEnableMonitoringChange() { + const configureStatus = getValue(discriminator, '/enableMonitoring') + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComPerconaXtraDB/spec/monitor', + value: {}, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/kubedbComPerconaXtraDB/spec/monitor') + } + + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/metadata/name', - value: modifiedName, + path: '/form/alert/enabled', + value: configureStatus ? 'warning' : 'none', force: true, }) - - // delete the other type object from model - if (type === 'compute') - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/storage', - ) - if (type === 'storage') - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/compute', - ) -} - -function onNamespaceChange({ model, getValue, commit }) { - const namespace = getValue( - model, - '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/metadata/namespace', - ) - if (!namespace) { - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/databaseRef/name', - ) } -} - -function ifScalingTypeEqualsTo( - { storeGet, watchDependency, getValue, discriminator, model }, - type, -) { - watchDependency('discriminator#/autoscalingType') - watchDependency( - 'model#/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/databaseRef/name', - ) - const operation = storeGet('/route/params/actions') || '' - if (operation.length) { - const splitOp = operation.split('-') - if (splitOp.length > 2) autoscaleType = splitOp[2] - } else autoscaleType = getValue(discriminator, '/autoscalingType') || '' - const isDatabaseSelected = !!getValue( - model, - '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/databaseRef/name', - ) - return autoscaleType === type && isDatabaseSelected -} + function showCustomizeExporterSection() { + // watchDependency('discriminator#/customizeExporter') + const configureStatus = getValue(discriminator, '/customizeExporter') + return configureStatus + } -async function fetchNodeTopology({ axios, storeGet }) { - 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) + function onCustomizeExporterChange() { + const configureStatus = getValue(discriminator, '/customizeExporter') + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComPerconaXtraDB/spec/monitor/prometheus/exporter', + value: {}, + force: true, + }) + } else { + commit( + 'wizard/model$delete', + '/resources/kubedbComPerconaXtraDB/spec/monitor/prometheus/exporter', + ) + } } - return [] -} -function isNodeTopologySelected({ watchDependency, model, getValue }) { - watchDependency( - 'model#/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/compute/nodeTopology/name', - ) - const nodeTopologyName = - getValue( - model, - '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/compute/nodeTopology/name', - ) || '' - return !!nodeTopologyName.length -} + function isValueExistInModel(path) { + const modelValue = getValue(model, path) || null + return !!modelValue + } -function setControlledResources({ commit }, type) { - const list = ['cpu', 'memory'] - const path = `/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/compute/${type}/controlledResources` - commit('wizard/model$update', { - path: path, - value: list, - force: true, - }) - return list -} + // function onNamespaceChange() { + // const namespace = getValue(model, '/metadata/release/namespace') + // const agent = getValue(model, '/resources/kubedbComPerconaXtraDB/spec/monitor/agent') + // if (agent === 'prometheus.io') { + // commit('wizard/model$update', { + // path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + // value: [namespace], + // force: true, + // }) + // } + // } -function setTrigger({ model, getValue }, path) { - let value = getValue(model, `/resources/${path}`) - if (value) return value - return 'On' -} + function onLabelChange() { + const labels = getValue(model, '/resources/kubedbComPerconaXtraDB/spec/metadata/labels') -function setApplyToIfReady() { - return 'IfReady' -} + const agent = getValue(model, '/resources/kubedbComPerconaXtraDB/spec/monitor/agent') -function handleUnit({ commit, model, getValue }, 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)) { + if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: `/resources/${path}`, - value: updatedValue, + path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', + value: labels, force: true, }) } - } else { - if (!isNaN(value)) { - value += 'Gi' + } + + function onAgentChange() { + const agent = getValue(model, '/resources/kubedbComPerconaXtraDB/spec/monitor/agent') + if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: `/resources/${path}`, - value: value, + path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', + value: [], force: true, }) + + onNamespaceChange() + onLabelChange() + } else { + commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') } } -} -function setMetadata({ storeGet, mode, commit }) { - const dbname = storeGet('/route/params/name') || '' - const namespace = storeGet('/route/query/namespace') || '' - if (mode === 'standalone-step') { - commit('wizard/model$update', { - path: '/metadata/release/name', - value: dbname, - force: true, - }) - commit('wizard/model$update', { - path: '/metadata/release/namespace', - value: namespace, - force: true, + function onNamespaceChange() { + const namespace = getValue( + model, + '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/metadata/namespace', + ) + if (!namespace) { + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/databaseRef/name', + ) + } + } + + 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/perconaxtradbopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` + } + + 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, + } }) } -} -function getOpsRequestUrl({ storeGet, model, getValue, mode }, 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 + `/create-opsrequest-${reqType.toLowerCase()}?namespace=${namespace}` - - if (mode === 'standalone-step') return pathConstructedForKubedb - else - return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/perconaxtradbopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` -} + 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/kubedbComPerconaXtraDB/spec/monitor/prometheus/exporter/env/${index}/valueFrom/configMapKeyRef/name`, + ) + + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/configMapKeyRef/name') -async function fetchTopologyMachines({ axios, getValue, storeGet, model, setDiscriminatorValue }) { - const instance = hasAnnotations({ model, getValue }) + if (!configMapName) return [] - 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 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, + })) - const nodeGroups = resp.data?.spec?.nodeGroups || [] - setDiscriminatorValue('/topologyMachines', nodeGroups) - return nodeGroups + return configMapKeys } catch (e) { console.log(e) return [] } } -} - -function setAllowedMachine({ model, getValue }, minmax) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - const mx = instance?.includes(',') ? instance.split(',')[1] : '' - const mn = instance?.includes(',') ? instance.split(',')[0] : '' - if (minmax === 'min') return mn - else return mx -} + 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') -async function getMachines({ getValue, watchDependency, discriminator }, minmax) { - watchDependency('discriminator#/topologyMachines') - const depends = minmax === 'min' ? 'max' : 'min' - const dependantPath = `/allowedMachine-${depends}` + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }, + ) - watchDependency(`discriminator#${dependantPath}`) - const dependantMachine = getValue(discriminator, dependantPath) + const secrets = (resp && resp.data && resp.data.items) || [] - const nodeGroups = getValue(discriminator, '/topologyMachines') || [] + const filteredSecrets = secrets.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) - const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) + 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 [] + } + } - const machines = nodeGroups?.map((item) => { - const subText = `CPU: ${item.allocatable.cpu}, Memory: ${item.allocatable.memory}` - const text = item.topologyValue - return { text, subText, value: item.topologyValue } - }) + 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/kubedbComPerconaXtraDB/spec/monitor/prometheus/exporter/env/${index}/valueFrom/secretKeyRef/name`, + ) - const filteredMachine = machines?.filter((item, ind) => - minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, - ) + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/secretKeyRef/name') - return dependantIndex === -1 ? machines : filteredMachine -} + if (!secretName) return [] -function hasAnnotations({ model, getValue }) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets/${secretName}`, + ) - return !!instance -} + const secret = (resp && resp.data && resp.data.data) || {} -function hasNoAnnotations({ model, getValue }) { - return !hasAnnotations({ model, getValue }) -} + const secretKeys = Object.keys(secret).map((item) => ({ + text: item, + value: item, + })) -function onMachineChange({ model, getValue, discriminator, commit }, type) { - const annoPath = '/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/metadata/annotations' - const annotations = getValue(model, annoPath) - const instance = annotations['kubernetes.io/instance-type'] + return secretKeys + } catch (e) { + console.log(e) + return [] + } + } - const minMachine = getValue(discriminator, '/allowedMachine-min') - const maxMachine = getValue(discriminator, '/allowedMachine-max') - const minMaxMachine = `${minMachine},${maxMachine}` - annotations['kubernetes.io/instance-type'] = minMaxMachine + function returnFalse() { + return false + } - const machines = getValue(discriminator, `/topologyMachines`) || [] - const minMachineObj = machines.find((item) => item.topologyValue === minMachine) - const maxMachineObj = machines.find((item) => item.topologyValue === maxMachine) - const minMachineAllocatable = minMachineObj?.allocatable - const maxMachineAllocatable = maxMachineObj?.allocatable - const allowedPath = `/resources/autoscalingKubedbComPerconaXtraDBAutoscaler/spec/compute/${type}` + function setValueFromDbDetails(path) { + const value = getValue(model, path) + return value + } - 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, + 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 }) - commit('wizard/model$update', { - path: annoPath, - value: annotations, - force: true, + + if (filteredEnv.length) + commit('wizard/model$update', { + path: '/resources/kubedbComPerconaXtraDB/spec/monitor/prometheus/exporter/env', + value: filteredEnv, + force: true, + }) + } + + function initEnvArray() { + const env = getValue( + model, + '/resources/kubedbComPerconaXtraDB/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/kubedbComPerconaXtraDB/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 { - getOpsRequestUrl, - setMetadata, - handleUnit, - isConsole, - getNamespaces, - getDbs, - isKubedb, - getDbDetails, - dbTypeEqualsTo, - clearSpecModel, - initMetadata, - onNamespaceChange, - ifScalingTypeEqualsTo, - fetchNodeTopology, - isNodeTopologySelected, - setControlledResources, - setTrigger, - setApplyToIfReady, - showOpsRequestOptions, - setInitSchedule, - fetchNames, - fetchNamespaces, - isRancherManaged, - onInputChangeSchedule, - getDefaultSchedule, - getBlueprints, - ifUsagePolicy, - initUsagePolicy, - isBlueprintOption, - initBlueprint, - getDefault, - onInputChange, - showBackupOptions, - showScheduleBackup, - isVariantAvailable, - fetchJsons, - disableLableChecker, - isEqualToModelPathValue, - getResources, - isEqualToDiscriminatorPath, - setValueFromModel, - isNotShardModeSelected, - isShardModeSelected, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - returnTrue, - returnStringYes, - getMongoDbVersions, - showAuthPasswordField, - showAuthSecretField, - showNewSecretCreateField, - isNotStandaloneMode, - showCommonStorageClassAndSizeField, - setDatabaseMode, - getStorageClassNames, - setStorageClass, - deleteDatabaseModePath, - isEqualToDatabaseMode, - setApiGroup, - getIssuerRefsName, - hasIssuerRefName, - hasNoIssuerRefName, - setClusterAuthMode, - setSSLMode, - showTlsConfigureSection, - onTlsConfigureChange, - getAliasOptions, - showMonitoringSection, - onEnableMonitoringChange, - showCustomizeExporterSection, - onCustomizeExporterChange, - disableInitializationSection, - valueExists, - initPrePopulateDatabase, - onPrePopulateDatabaseChange, - initDataSource, - onDataSourceChange, - initVolumeType, - onVolumeTypeChange, - showInitializationForm, - showScriptOrStashForm, - showConfigMapOrSecretName, - initializeNamespace, - showRepositorySelectOrCreate, - onInitRepositoryChoiseChange, - initCustomizeRestoreJobRuntimeSettings, - initCustomizeRestoreJobRuntimeSettingsForBackup, - onCustomizeRestoreJobRuntimeSettingsChange, - onCustomizeRestoreJobRuntimeSettingsChangeForBackup, - showRuntimeForm, - getImagePullSecrets, - getBackupConfigsAndAnnotations, - deleteKubeDbComMongDbAnnotation, - addKubeDbComMongDbAnnotation, - initScheduleBackup, - initScheduleBackupForEdit, - onScheduleBackupChange, - showBackupForm, - initBackupInvoker, - onBackupInvokerChange, - showInvokerForm, - initalizeTargetReferenceName, - setInitialRestoreSessionRepo, - initRepositoryChoise, - initRepositoryChoiseForEdit, - onRepositoryChoiseChange, - onRepositoryNameChange, - getMongoAnnotations, - initFromAnnotationValue, - onBackupBlueprintNameChange, - onBackupBlueprintScheduleChange, - initFromAnnotationKeyValue, - onTaskParametersChange, - isValueExistInModel, - onNamespaceChange, - onLabelChange, - onNameChange, - returnFalse, - onAgentChange, - getCreateAuthSecret, - showExistingSecretSection, - showPasswordSection, - setAuthSecretPassword, - onAuthSecretPasswordChange, - encodePassword, - decodePassword, - onCreateAuthSecretChange, - getSecrets, - isEqualToServiceMonitorType, - onConfigurationSourceChange, - onConfigurationChange, - setConfigurationSource, - setSecretConfigNamespace, - setConfigurationSourceShard, - setConfigurationSourceConfigServer, - setConfigurationSourceMongos, - isSchemaOf, - disableConfigSourceOption, - onConfigurationSourceMongosChange, - onConfigurationSourceShardChange, - onConfigurationSourceConfigServerChange, - transferConfigSecret, - onConfigSecretModelChange, - setConfiguration, - setConfigurationShard, - setConfigurationConfigServer, - setConfigurationMongos, - setConfigurationFiles, - setConfigurationFilesShard, - setConfigurationFilesConfigServer, - setConfigurationFilesMongos, - onSetCustomConfigChange, - getCreateNameSpaceUrl, - updateConfigServerStorageClass, - getMachines, - setAllowedMachine, - hasAnnotations, - hasNoAnnotations, - fetchTopologyMachines, - onMachineChange, + return { + isConsole, + isKubedb, + getDbDetails, + getNamespaces, + isRancherManaged, + onNamespaceChange, + getDbs, + initMetadata, + fetchTopologyMachines, + setTrigger, + onTriggerChange, + setApplyToIfReady, + hasAnnotations, + hasNoAnnotations, + setAllowedMachine, + getMachines, + onMachineChange, + setControlledResources, + fetchNodeTopology, + isNodeTopologySelected, + showOpsRequestOptions, + handleUnit, + + getOpsRequestUrl, + isValueExistInModel, + onEnableMonitoringChange, + showMonitoringSection, + onAgentChange, + getResources, + isEqualToModelPathValue, + onCustomizeExporterChange, + showCustomizeExporterSection, + onLabelChange, + setValueFrom, + onValueFromChange, + resourceNames, + getConfigMapKeys, + getSecrets, + getSecretKeys, + isConfigMapTypeValueFrom, + isSecretTypeValueFrom, + getNamespacedResourceList, + returnFalse, + onEnvArrayChange, + initEnvArray, + isEqualToTemp, + initMonitoring, + + setValueFromDbDetails, + } } diff --git a/charts/kubedbcom-pgbouncer-editor-options/ui/create-ui.yaml b/charts/kubedbcom-pgbouncer-editor-options/ui/create-ui.yaml index 238304dcce..443365664b 100644 --- a/charts/kubedbcom-pgbouncer-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-pgbouncer-editor-options/ui/create-ui.yaml @@ -1,308 +1,300 @@ -steps: -- form: - discriminator: - bundleApiLoaded: - default: false - type: boolean +step: +- type: single-step-form + loader: initBundle + elements: + - type: label-element + label: '' + subtitle: Select the PgBouncer version you want to deploy on Kubernetes. The chosen version determines the PgBouncer engine features, compatibility, and runtime behavior of your connection pooler. + - disableUnselect: true + loader: getAdminOptions|databases/PgBouncer/versions + if: + type: function + name: isToggleOn|databases/PgBouncer/versions + label: Database Version + schema: schema/properties/spec/properties/admin/properties/databases/properties/PgBouncer/properties/versions/properties/default + type: select + - init: + type: func + value: getDefault|databases/PgBouncer/mode + loader: getAdminOptions|databases/PgBouncer/mode + isHorizontal: true + if: + type: function + name: isToggleOn|databases/PgBouncer/mode + label: Database Mode + watcher: + func: onDatabaseModeChange + paths: + - schema/properties/spec/properties/mode + schema: schema/properties/spec/properties/mode + type: radio + - if: + type: function + name: isEqualToModelPathValue|Replicaset|/spec/mode + label: Replica number + schema: schema/properties/spec/properties/replicas + type: input + - elements: + - type: label-element + label: '' + subtitle: Select a machine profile to allocate CPU and memory resources for your connection pooler. Choose 'custom' to manually specify resource requirements or select a predefined profile. + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu + disable: isMachineNotCustom + label: CPU + loader: setLimits|cpu + if: + type: function + name: isMachineCustom + watcher: + func: setRequests|cpu + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: Memory + loader: setLimits|memory + watcher: + func: setRequests|memory + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + label: Machine Profile + showLabels: true + type: block-layout + - elements: + - type: horizontal-layout + showLabels: true + elements: + - label: Database Reference Name + schema: schema/properties/spec/properties/database/properties/databaseName + type: input + - loader: getAppBindings|postgres + label: Select Database Reference + watcher: + func: onRefChange + paths: + - temp/pgRef + refresh: true + validation: + type: required + schema: temp/pgRef + type: select + type: block-layout + - description: Configure Credentials, Deployment Mode etc. elements: - - computed: initBundle - if: returnFalse - type: label-element - - disableUnselect: true - fetch: getAdminOptions|databases/PgBouncer/versions - if: isToggleOn|databases/PgBouncer/versions - label: - text: labels.database.version - schema: - $ref: schema#/properties/spec/properties/admin/properties/databases/properties/PgBouncer/properties/versions/properties/default - type: select - - computed: getDefault|databases/PgBouncer/mode - fetch: getAdminOptions|databases/PgBouncer/mode - hasDescription: true - if: isToggleOn|databases/PgBouncer/mode - label: - text: labels.database.mode - onChange: onDatabaseModeChange - schema: - $ref: schema#/properties/spec/properties/mode - type: radio - - if: isEqualToModelPathValue|Replicaset|/spec/mode - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/replicas - type: input - elements: - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.cpu - onChange: setRequests|cpu - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.memory - onChange: setRequests|memory - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - label: - text: labels.machine_profile - show_label: true - type: single-step-form - - label: - text: labels.databaseref.name - schema: - $ref: schema#/properties/spec/properties/database/properties/databaseName + - type: label-element + label: '' + subtitle: Add custom labels and annotations to your database resources for organization, monitoring, and integration with other Kubernetes tools and services. + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/annotations + label: Labels & Annotations + showLabels: true + hideBlock: true + type: block-layout + - init: + type: func + value: getDefault|deletionPolicy + customClass: mt-20 + if: + type: function + name: isToggleOn|deletionPolicy + label: Deletion Policy + options: + - description: options.deletionPolicy.delete.description + text: Delete + value: Delete + - description: options.deletionPolicy.wipeOut.description + text: WipeOut + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: DoNotTerminate + value: DoNotTerminate + schema: schema/properties/spec/properties/deletionPolicy + type: select + - if: + type: function + name: getDefaultValue|spec/admin/authCredential/customize + label: Provide Authentication Credentials? + watcher: + func: onAuthChange + paths: + - temp/createAuthSecret + schema: temp/createAuthSecret + type: switch + - if: + type: function + name: showReferSecretSwitch + label: Refer existing Secret? + watcher: + func: onReferSecretChange + paths: + - temp/referSecret + schema: temp/referSecret + type: switch + - loader: getReferSecrets + if: + type: function + name: showSecretDropdown + label: Secret + schema: schema/properties/spec/properties/authSecret/properties/name + type: select + - if: + type: function + name: showReferSecret + label: Password + schema: schema/properties/spec/properties/authSecret/properties/password type: input - - fetch: getAppBindings|postgres - label: - text: labels.databaseref.select - onChange: onRefChange - refresh: true - required: true - schema: - $ref: discriminator#/pgRef + - if: + type: function + name: getDefaultValue|spec/admin/customConfiguration + label: Configure Database? + watcher: + func: clearConfiguration + paths: + - temp/configDatabase + schema: temp/configDatabase + type: switch + - if: + type: function + name: isConfigDatabaseOn + label: Configuration + schema: schema/properties/spec/properties/configuration + type: textarea + - label: Sync Users + schema: schema/properties/spec/properties/database/properties/syncUsers + type: switch + - isHorizontal: true + if: + type: function + name: isToggleOn|deployment + label: Deployment Mode + options: + - description: Shared + text: Shared + value: Shared + - description: Dedicated + text: Dedicated + value: Dedicated + schema: schema/properties/spec/properties/admin/properties/deployment/properties/default + type: radio + - if: + type: function + name: isToggleOn|clusterTier + isHorizontal: true + label: Cluster Tier + options: + - text: General Purpose + value: GeneralPurpose + - text: Memory Optimized + value: MemoryOptimized + - text: CPU Optimized + value: CPUOptimized + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/default + type: radio + - disableUnselect: true + loader: getAdminOptions|clusterTier/placement + if: + type: function + name: isToggleOn|clusterTier/placement + label: Placement Policy + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default type: select - - accordion: true - description: - text: Configure Credentials, Deployment Mode etc. - discriminator: - configDatabase: - default: false - type: boolean - createAuthSecret: - default: false - type: boolean - pgRef: - default: {} - type: object - referSecret: - default: false - type: boolean - elements: - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties - type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties - type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - computed: getDefault|deletionPolicy - customClass: mt-20 - if: isToggleOn|deletionPolicy - label: - text: labels.deletionPolicy - options: - - description: options.deletionPolicy.delete.description - text: options.deletionPolicy.delete.label - value: Delete - - 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/spec/properties/deletionPolicy - type: select - - if: getDefaultValue|spec/admin/authCredential/customize - label: - text: Provide Authentication Credentials? - onChange: onAuthChange - schema: - $ref: discriminator#/createAuthSecret - type: switch - - if: showReferSecretSwitch - label: - text: Refer existing Secret? - onChange: onReferSecretChange - schema: - $ref: discriminator#/referSecret - type: switch - - fetch: getReferSecrets - if: showSecretDropdown - label: - text: Secret - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/name - type: select - - if: showReferSecret - label: - text: labels.password - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/password - type: input - - computed: isConfigAvailable - if: getDefaultValue|spec/admin/customConfiguration - label: - text: Configure Database? - onChange: clearConfiguration - schema: - $ref: discriminator#/configDatabase - type: switch - - if: isConfigDatabaseOn - label: - text: Configuration - schema: - $ref: schema#/properties/spec/properties/configuration - type: editor - - label: - text: labels.sync_users_question - schema: - $ref: schema#/properties/spec/properties/database/properties/syncUsers + - disableUnselect: true + loader: getNodeTopology + if: + type: function + name: isToggleOn|clusterTier/nodeTopology + label: Node Topology + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + type: select + label: Advanced Configuration + showLabels: true + type: block-layout + - description: Enable Backup, Monitoring, TLS etc. + elements: + - elements: + - init: + type: func + value: setMonitoring + label: Enable Monitoring + watcher: + func: updateAlertValue + paths: + - temp/monitoring + schema: temp/monitoring type: switch - - hasDescription: true - if: isToggleOn|deployment - label: - text: labels.deployment.name - options: - - description: labels.deployment.shared - text: Shared - value: Shared - - description: labels.deployment.dedicated - text: Dedicated - value: Dedicated - schema: - $ref: schema#/properties/spec/properties/admin/properties/deployment/properties/default - type: radio - - if: isToggleOn|clusterTier - isHorizontal: true - label: - text: labels.clusterTier + - customClass: mt-10 + if: + type: function + name: showAlerts + label: Alert Options options: - - text: General Purpose - value: GeneralPurpose - - text: Memory Optimized - value: MemoryOptimized - - text: CPU Optimized - value: CPUOptimized - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/default - type: radio - - disableUnselect: true - fetch: getAdminOptions|clusterTier/placement - if: isToggleOn|clusterTier/placement - label: - text: labels.placement - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + - text: None + value: none + - text: Critical + value: critical + - text: Warning + value: warning + - text: Info + value: info + schema: schema/properties/form/properties/alert/properties/enabled + # sortable: true type: select - - disableUnselect: true - fetch: getNodeTopology - if: isToggleOn|clusterTier/nodeTopology - label: - text: labels.nodeTopology - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + if: + type: function + name: isToggleOn|monitoring + type: block-layout + - elements: + - if: + type: function + name: isToggleOn|tls + label: Enable TLS? + schema: schema/properties/spec/properties/admin/properties/tls/properties/default + type: switch + - loader: getAdminOptions|clusterIssuers + if: + type: function + name: showIssuer + label: Cluster Issuers + validation: + type: required + schema: schema/properties/spec/properties/admin/properties/clusterIssuers/properties/default type: select - hideForm: true - label: - text: Advanced Configuration - show_label: true - type: single-step-form - - accordion: true - description: - text: Enable Backup, Monitoring, TLS etc. - discriminator: - backup: - default: false - type: boolean - elements: - - discriminator: - monitoring: - default: false - type: boolean - elements: - - computed: setMonitoring - label: - text: labels.enable_monitoring - onChange: updateAlertValue - schema: - $ref: discriminator#/monitoring - type: switch - - customClass: mt-10 - if: showAlerts - label: - text: labels.alert.options - options: - - text: None - value: none - - text: Critical - value: critical - - text: Warning - value: warning - - text: Info - value: info - schema: - $ref: schema#/properties/form/properties/alert/properties/enabled - sortable: true - type: select - if: isToggleOn|monitoring - type: single-step-form - - elements: - - if: isToggleOn|tls - label: - text: Enable TLS? - schema: - $ref: schema#/properties/spec/properties/admin/properties/tls/properties/default - type: switch - - fetch: getAdminOptions|clusterIssuers - if: showIssuer - label: - text: labels.clusterIssuers - required: true - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterIssuers/properties/default - type: select - type: single-step-form - if: showAdditionalSettings - label: - text: Additional Options - show_label: true - type: single-step-form - type: single-step-form + type: block-layout + if: + type: function + name: showAdditionalSettings + label: Additional Options + showLabels: true + type: block-layout id: options - title: steps.0.label type: multi-step-form diff --git a/charts/kubedbcom-pgbouncer-editor-options/ui/functions.js b/charts/kubedbcom-pgbouncer-editor-options/ui/functions.js index 094c8412e3..2aa6e55bf1 100644 --- a/charts/kubedbcom-pgbouncer-editor-options/ui/functions.js +++ b/charts/kubedbcom-pgbouncer-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -315,727 +317,791 @@ const modeDetails = { }, } -async function getAppBindings({ axios, storeGet }, type) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const queryParams = { - filter: { - items: { - metadata: { name: null, namespace: null }, - spec: { type: null }, - }, - }, - } - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/appcatalog.appscode.com/v1alpha1/appbindings`, - queryParams, - ) - const resources = (resp && resp.data && resp.data.items) || [] - - const fileredResources = resources - .filter((item) => item.spec?.type === `kubedb.com/${type}`) - .map((item) => { - const name = item.metadata?.name || '' - const namespace = item.metadata?.namespace || '' - return { - text: `${namespace}/${name}`, - value: { - name: name, - namespace: namespace, - }, - } - }) - return fileredResources - } catch (e) { - console.log(e) - return [] - } -} - -function onRefChange({ discriminator, getValue, commit }) { - const ref = getValue(discriminator, '/pgRef') || {} - commit('wizard/model$update', { - path: `/spec/database/databaseRef/name`, - value: ref.name || '', - force: true, - }) - commit('wizard/model$update', { - path: `/spec/database/databaseRef/namespace`, - value: ref.namespace || '', - force: true, - }) -} -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} -const onDatabaseModeChange = ({ model, getValue, commit }) => { - const databaseMode = getValue(model, '/spec/mode') - commit('wizard/model$update', { - path: '/spec/replicas', - value: databaseMode === 'Standalone' ? 1 : 3, - force: true, - }) -} +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], + setDiscriminatorValue('bundleApiLoaded', false) + setDiscriminatorValue('configDatabase', false) + setDiscriminatorValue('createAuthSecret', false) + setDiscriminatorValue('pgRef', {}) + setDiscriminatorValue('referSecret', false) + setDiscriminatorValue('backup', false) + setDiscriminatorValue('monitoring', false) + + async function getAppBindings(type) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const queryParams = { + filter: { + items: { + metadata: { name: null, namespace: null }, + spec: { type: null }, }, }, - ) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] } - } catch (e) { - console.log(e) - } - return [] -} - -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} - -function getMachineListForOptions({ model, getValue }) { - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - let array = [] - - if (available.length) { - array = available.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - else { - let subText = '', - text = '' - const machineData = machinesFromPreset.find((val) => val.id === machine) - if (machineData) { - subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` - text = machineData.name ? machineData.name : machineData.id - } - return { text, subText, value: machine } - } - }) - } else { - array = machineList - .map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } - }) - .filter((val) => !!val) - } - return array -} - -function setLimits({ model, getValue, commit, watchDependency }, resource, type) { - const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' - watchDependency(`model#${path}`) - const selectedMachine = getValue(model, path) || 'custom' - const reqCommitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - const comparePath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - - const resourceValue = getValue(model, comparePath) - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - - let cpu = '', - memory = '' - if (available.length && selectedMachine !== 'custom') { - const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) - if (machineData) { - cpu = machineData.limits.cpu - memory = machineData.limits.memory - } - } else { - if (selectedMachine === 'custom') { - cpu = resourceValue - memory = resourceValue - } else { - cpu = machines[selectedMachine].resources.limits.cpu - memory = machines[selectedMachine].resources.limits.memory + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/appcatalog.appscode.com/v1alpha1/appbindings`, + queryParams, + ) + const resources = (resp && resp.data && resp.data.items) || [] + + const fileredResources = resources + .filter((item) => item.spec?.type === `kubedb.com/${type}`) + .map((item) => { + const name = item.metadata?.name || '' + const namespace = item.metadata?.namespace || '' + return { + text: `${namespace}/${name}`, + value: { + name: name, + namespace: namespace, + }, + } + }) + return fileredResources + } catch (e) { + console.log(e) + return [] } } - if (resource === 'memory') { + function onRefChange() { + const ref = getValue(discriminator, '/pgRef') || {} commit('wizard/model$update', { - path: reqCommitPath, - value: memory, + path: `/spec/database/databaseRef/name`, + value: ref.name || '', force: true, }) commit('wizard/model$update', { - path: comparePath, - value: memory, - force: true, - }) - return memory - } else { - commit('wizard/model$update', { - path: reqCommitPath, - value: cpu, + path: `/spec/database/databaseRef/namespace`, + value: ref.namespace || '', force: true, }) + } + + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } + + const onDatabaseModeChange = () => { + const databaseMode = getValue(model, '/spec/mode') commit('wizard/model$update', { - path: comparePath, - value: cpu, + path: '/spec/replicas', + value: databaseMode === 'Standalone' ? 1 : 3, force: true, }) - return cpu } -} - -function setRequests({ getValue, model, commit }, resource) { - const modelPath = `/spec/podResources/resources/requests/${resource}` - const val = getValue(model, modelPath) - commitPath = `/spec/podResources/resources/limits/${resource}` - commit('wizard/model$update', { - path: commitPath, - value: val, - force: true, - }) -} -function setMachineToCustom({ getValue, model }) { - const machine = getValue(model, '/spec/admin/machineProfiles/default') - return machine || 'custom' -} + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, + }, + ) + if (resp.data?.status?.projects) { + const projects = resp.data?.status?.projects + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } + } catch (e) { + console.log(e) + } + return [] + } -function isMachineCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue === 'custom' -} + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } -function isMachineNotCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue !== 'custom' && !!modelPathValue -} + let array = [] + function getMachineListForOptions() { + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') -function updateAlertValue({ commit, model, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const alert = isMonitorEnabled ? 'warning' : 'none' - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: alert, - force: true, - }) - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} + if (available.length) { + array = available.map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + else { + let subText = '', + text = '' + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + text = machineData.name ? machineData.name : machineData.id + } + return { text, subText, value: machine } + } + }) + } else { + array = machineList + .map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { text, subText, value: machine } + }) + .filter((val) => !!val) + } + return array + } -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} + function setLimits(resource, type) { + const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' + // watchDependency(`model#${path}`) + const selectedMachine = getValue(model, path) || 'custom' + const reqCommitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + const comparePath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + + const resourceValue = getValue(model, comparePath) + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + let cpu = '', + memory = '' + if (available.length && selectedMachine !== 'custom') { + const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) + if (machineData) { + cpu = machineData.limits.cpu + memory = machineData.limits.memory + } + } else { + if (selectedMachine === 'custom') { + cpu = resourceValue + memory = resourceValue + } else { + cpu = machines[selectedMachine].resources.limits.cpu + memory = machines[selectedMachine].resources.limits.memory + } + } -let placement = [] -let versions = [] -let storageClass = [] -let clusterIssuers = [] -let nodetopologiesShared = [] -let nodetopologiesDedicated = [] -let features = [] -async function initBundle({ commit, model, getValue, axios, storeGet, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - - let db = getValue(model, '/metadata/resource/kind') - db = db.toLowerCase() - let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` - const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - - try { - const resp = await axios.get(url) - features = resp.data.features || [] - placement = resp.data.placementpolicies || [] - versions = resp.data.versions || [] - storageClass = resp.data.storageclasses || [] - clusterIssuers = resp.data.clusterissuers || [] - nodetopologiesDedicated = resp.data.dedicated || [] - nodetopologiesShared = resp.data.shared || [] - - const response = await axios.get(annotationUrl) - const annotations = response.data?.metadata?.annotations || {} - const uidRange = annotations['openshift.io/sa.scc.uid-range'] - if (uidRange) { - const val = uidRange.split('/')[0] + if (resource === 'memory') { + commit('wizard/model$update', { + path: reqCommitPath, + value: memory, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: memory, + force: true, + }) + return memory + } else { commit('wizard/model$update', { - path: '/spec/openshift/securityContext/runAsUser', - value: val, + path: reqCommitPath, + value: cpu, force: true, }) + commit('wizard/model$update', { + path: comparePath, + value: cpu, + force: true, + }) + return cpu } - } catch (e) { - console.log(e) } - commit('wizard/model$update', { - path: '/spec/deletionPolicy', - value: getDefault({ getValue, model }, 'deletionPolicy'), - force: true, - }) - - if (!getValue(model, `/spec/admin/databases/PgBouncer/mode/toggle`)) { - let defMode = getDefault({ getValue, model }, 'databases/PgBouncer/mode') || '' - if (defMode === '') { - const arr = getValue(model, '/spec/databases/PgBouncer/mode/available') || [] - if (arr.length) defMode = arr[0] - } + function setRequests(resource, type) { + const modelPath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + + const fullpath = `/spec/podResources/machine` + const modelPathValue = getValue(model, fullpath) + commit('wizard/model$update', { - path: '/spec/mode', - value: defMode, + path: commitPath, + value: val, force: true, }) - } - if (!features.includes('tls')) { - commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: false, - force: true, + if (modelPathValue === 'custom') { + return + } + let commitCpuMemory, ModelPathValue + if (resource && type) { + const fullPath = `/spec/${type}/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/${type}/podResources/resources/requests/${resource}` + } else { + const fullPath = `/spec/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/podResources/resources/requests/${resource}` + } + let cpuMemoryValue + array.forEach((item) => { + if (item.value === ModelPathValue) { + // Parse subText like "CPU: 2, Memory: 2Gi" + const subText = item.subText || '' + if (resource === 'cpu') { + // Extract CPU value + const cpuMatch = subText.match(/CPU:\s*([^,]+)/) + cpuMemoryValue = cpuMatch ? cpuMatch[1].trim() : '' + } else if (resource === 'memory') { + // Extract Memory value + const memoryMatch = subText.match(/Memory:\s*(.+)/) + cpuMemoryValue = memoryMatch ? memoryMatch[1].trim() : '' + } + } }) - } - if (!features.includes('binding')) { commit('wizard/model$update', { - path: '/spec/admin/expose/default', - value: false, + path: commitCpuMemory, + value: cpuMemoryValue, force: true, }) + return cpuMemoryValue } - if (!features.includes('monitoring')) { - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: '', - force: true, - }) + + function setRequests(resource) { + const modelPath = `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + commitPath = `/spec/podResources/resources/limits/${resource}` commit('wizard/model$update', { - path: '/form/alert/enabled', - value: 'none', + path: commitPath, + value: val, force: true, }) } - if (!features.includes('backup')) { + + function setMachineToCustom() { + const machine = getValue(model, '/spec/admin/machineProfiles/default') + return machine || 'custom' + } + + function isMachineCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue === 'custom' + } + + function isMachineNotCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue !== 'custom' && !!modelPathValue + } + + function updateAlertValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const alert = isMonitorEnabled ? 'warning' : 'none' + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, + path: '/form/alert/enabled', + value: alert, force: true, }) + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' commit('wizard/model$update', { - path: '/spec/backup/tool', - value: '', + path: '/spec/admin/monitoring/agent', + value: agent, force: true, }) } - setDiscriminatorValue('/bundleApiLoaded', true) -} - -function fetchOptions({ model, getValue, commit }, type) { - let kind = getValue(model, '/metadata/resource/kind') - - let returnArray = [] - if (type === 'clusterTier/placement') { - returnArray = placement - } else if (type === `databases/${kind}/versions`) { - returnArray = versions - } else if (type === 'storageClasses') { - returnArray = storageClass - } else if (type === 'clusterIssuers') { - returnArray = clusterIssuers + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false } - if (returnArray.length === 1) { - const path = `/spec/admin/${type}/default` + let placement = [] + let versions = [] + let storageClass = [] + let clusterIssuers = [] + let nodetopologiesShared = [] + let nodetopologiesDedicated = [] + let features = [] + async function initBundle() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + + let db = getValue(model, '/metadata/resource/kind') + db = db.toLowerCase() + let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` + const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` + + try { + const resp = await axios.get(url) + features = resp.data.features || [] + placement = resp.data.placementpolicies || [] + versions = resp.data.versions || [] + storageClass = resp.data.storageclasses || [] + clusterIssuers = resp.data.clusterissuers || [] + nodetopologiesDedicated = resp.data.dedicated || [] + nodetopologiesShared = resp.data.shared || [] + + const response = await axios.get(annotationUrl) + const annotations = response.data?.metadata?.annotations || {} + const uidRange = annotations['openshift.io/sa.scc.uid-range'] + if (uidRange) { + const val = uidRange.split('/')[0] + commit('wizard/model$update', { + path: '/spec/openshift/securityContext/runAsUser', + value: val, + force: true, + }) + } + } catch (e) { + console.log(e) + } + commit('wizard/model$update', { - path: path, - value: returnArray[0], + path: '/spec/deletionPolicy', + value: getDefault('deletionPolicy'), force: true, }) - } - - return returnArray -} -function getAdminOptions({ getValue, model, watchDependency, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') + if (!getValue(model, `/spec/admin/databases/PgBouncer/mode/toggle`)) { + let defMode = getDefault('databases/PgBouncer/mode') || '' + if (defMode === '') { + const arr = getValue(model, '/spec/databases/PgBouncer/mode/available') || [] + if (arr.length) defMode = arr[0] + } + commit('wizard/model$update', { + path: '/spec/mode', + value: defMode, + force: true, + }) + } - const options = getValue(model, `/spec/admin/${type}/available`) || [] + if (!features.includes('tls')) { + commit('wizard/model$update', { + path: '/spec/admin/tls/default', + value: false, + force: true, + }) + } + if (!features.includes('binding')) { + commit('wizard/model$update', { + path: '/spec/admin/expose/default', + value: false, + force: true, + }) + } + if (!features.includes('monitoring')) { + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: 'none', + force: true, + }) + } + if (!features.includes('backup')) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: '', + force: true, + }) + } - if (options.length === 0) { - return fetchOptions({ model, getValue, commit }, type) + setDiscriminatorValue('/bundleApiLoaded', true) } - if (type.endsWith('/mode')) { - return ( - options?.map((item) => ({ - description: modeDetails[item]?.description || '', - text: modeDetails[item]?.text || '', - value: item, - })) || [] - ) - } - return options -} -function checkIfFeatureOn({ getValue, model }, type) { - let val = getValue(model, `/spec/admin/${type}/toggle`) - if (type === 'backup' || type === 'archiver') { - val = getValue(model, `/spec/admin/${type}/enable/toggle`) - } - const backupVal = getValue(model, '/spec/backup/tool') - - if (type === 'backup') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } else if (type === 'tls') { - return features.includes('tls') && val - } else if (type === 'expose') { - return features.includes('binding') && val - } else if (type === 'monitoring') { - return features.includes('monitoring') && val - } else if (type === 'archiver') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } -} + function fetchOptions(type) { + let kind = getValue(model, '/metadata/resource/kind') + + let returnArray = [] + if (type === 'clusterTier/placement') { + returnArray = placement + } else if (type === `databases/${kind}/versions`) { + returnArray = versions + } else if (type === 'storageClasses') { + returnArray = storageClass + } else if (type === 'clusterIssuers') { + returnArray = clusterIssuers + } -function isToggleOn({ getValue, model, discriminator, watchDependency }, type) { - watchDependency('discriminator#/bundleApiLoaded') - watchDependency('model#/spec/admin/deployment/default') - const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') - let deploymentType = getValue(model, `/spec/admin/deployment/default`) - if ( - type === 'tls' || - type === 'backup' || - type === 'expose' || - type === 'monitoring' || - type === 'archiver' - ) { - return checkIfFeatureOn({ getValue, model }, type) - } else if ( - type === 'clusterTier' || - type === 'clusterTier/placement' || - type === 'clusterTier/nodeTopology' - ) { - if (deploymentType === 'Dedicated' && bundleApiLoaded) return true - else return false - } else if (type === 'deployment') { - const deploymentType = getValue(model, '/spec/admin/deployment/default') - if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + if (returnArray.length === 1) { + const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: '/spec/admin/deployment/default', - value: 'Shared', + path: path, + value: returnArray[0], force: true, }) } - return ( - getValue(model, `/spec/admin/${type}/toggle`) && - nodetopologiesDedicated.length && - bundleApiLoaded - ) - } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded -} -async function getNodeTopology({ model, getValue, axios, storeGet, watchDependency }) { - watchDependency('model#/spec/admin/deployment/default') - watchDependency('model#/spec/admin/clusterTier/default') - const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' - const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' - let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + return returnArray + } - const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + function getAdminOptions(type) { + // watchDependency('discriminator#/bundleApiLoaded') - if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared - else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + const options = getValue(model, `/spec/admin/${type}/available`) || [] - const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) - return filteredList -} + if (options.length === 0) { + return fetchOptions(type) + } + if (type.endsWith('/mode')) { + return ( + options?.map((item) => ({ + description: modeDetails[item]?.description || '', + text: modeDetails[item]?.text || '', + value: item, + })) || [] + ) + } + return options + } -function filterNodeTopology(list, tier, provider) { - // first filter the list from value that exists from the filtered list got from API - const filteredlist = list + function checkIfFeatureOn(type) { + let val = getValue(model, `/spec/admin/${type}/toggle`) + if (type === 'backup' || type === 'archiver') { + val = getValue(model, `/spec/admin/${type}/enable/toggle`) + } + const backupVal = getValue(model, '/spec/backup/tool') + + if (type === 'backup') { + return features.includes('backup') && backupVal === 'KubeStash' && val + } else if (type === 'tls') { + return features.includes('tls') && val + } else if (type === 'expose') { + return features.includes('binding') && val + } else if (type === 'monitoring') { + return features.includes('monitoring') && val + } else if (type === 'archiver') { + return features.includes('backup') && backupVal === 'KubeStash' && val + } + } - // filter the list based on clusterTier - if (provider === 'EKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('c') - else if (tier === 'MemoryOptimized') return item.startsWith('r') - else return !item.startsWith('c') && !item.startsWith('r') - }) - } else if (provider === 'AKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - else - return ( - !(item.startsWith('f') || item.startsWith('fx')) && - !( + function isToggleOn(type) { + // watchDependency('discriminator#/bundleApiLoaded') + // watchDependency('model#/spec/admin/deployment/default') + const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') + let deploymentType = getValue(model, `/spec/admin/deployment/default`) + if ( + type === 'tls' || + type === 'backup' || + type === 'expose' || + type === 'monitoring' || + type === 'archiver' + ) { + return checkIfFeatureOn(type) + } else if ( + type === 'clusterTier' || + type === 'clusterTier/placement' || + type === 'clusterTier/nodeTopology' + ) { + if (deploymentType === 'Dedicated' && bundleApiLoaded) return true + else return false + } else if (type === 'deployment') { + const deploymentType = getValue(model, '/spec/admin/deployment/default') + if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + commit('wizard/model$update', { + path: '/spec/admin/deployment/default', + value: 'Shared', + force: true, + }) + } + return ( + getValue(model, `/spec/admin/${type}/toggle`) && + nodetopologiesDedicated.length && + bundleApiLoaded + ) + } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded + } + + async function getNodeTopology() { + // watchDependency('model#/spec/admin/deployment/default') + // watchDependency('model#/spec/admin/clusterTier/default') + const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' + const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' + let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + + const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + + if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared + else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + + const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) + return filteredList + } + + function filterNodeTopology(list, tier, provider) { + // first filter the list from value that exists from the filtered list got from API + const filteredlist = list + + // filter the list based on clusterTier + if (provider === 'EKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('c') + else if (tier === 'MemoryOptimized') return item.startsWith('r') + else return !item.startsWith('c') && !item.startsWith('r') + }) + } else if (provider === 'AKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('e') || item.startsWith('eb') || item.startsWith('ec') || item.startsWith('m') || item.startsWith('d') ) - ) - }) - } else if (provider === 'GKE') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') - return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - else - return ( - !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && - !( + else + return ( + !(item.startsWith('f') || item.startsWith('fx')) && + !( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + ) + }) + } else if (provider === 'GKE') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') + return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('x4') || item.startsWith('m1') || item.startsWith('m2') || item.startsWith('m3') ) - ) - }) - } else return filteredlist -} + else + return ( + !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && + !( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + ) + }) + } else return filteredlist + } -function returnFalse() { - return false -} + function returnFalse() { + return false + } -function showAlerts({ watchDependency, model, getValue, discriminator }) { - watchDependency('discriminator#/monitoring') - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const isAlertToggleEnabled = isToggleOn( - { getValue, model, watchDependency, discriminator }, - 'alert', - ) - return isMonitorEnabled && isAlertToggleEnabled -} + function showAlerts() { + // watchDependency('discriminator#/monitoring') + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const isAlertToggleEnabled = isToggleOn('alert', + ) + return isMonitorEnabled && isAlertToggleEnabled + } -function showIssuer({ model, getValue, watchDependency, discriminator }) { - watchDependency('model#/spec/admin/tls/default') - const isTlsEnabled = getValue(model, '/spec/admin/tls/default') - const isIssuerToggleEnabled = isToggleOn( - { getValue, model, watchDependency, discriminator }, - 'clusterIssuers', - ) - return isTlsEnabled && isIssuerToggleEnabled -} + function showIssuer() { + // watchDependency('model#/spec/admin/tls/default') + const isTlsEnabled = getValue(model, '/spec/admin/tls/default') + const isIssuerToggleEnabled = isToggleOn('clusterIssuers', + ) + return isTlsEnabled && isIssuerToggleEnabled + } -function onBackupSwitch({ discriminator, getValue, commit }) { - const isBackupOn = getValue(discriminator, '/backup') - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: isBackupOn ? 'KubeStash' : '', - force: true, - }) -} + function onBackupSwitch() { + const isBackupOn = getValue(discriminator, '/backup') + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: isBackupOn ? 'KubeStash' : '', + force: true, + }) + } -function setMonitoring({ getValue, model }) { - const agent = getValue(model, '/spec/admin/monitoring/agent') || '' - return !!agent -} + function setMonitoring() { + const agent = getValue(model, '/spec/admin/monitoring/agent') || '' + return !!agent + } -function setBackup({ model, getValue }) { - const backup = getValue(model, '/spec/backup/tool') - const val = getValue(model, '/spec/admin/backup/enable/default') - return backup === 'KubeStash' && features.includes('backup') && val -} + function setBackup() { + const backup = getValue(model, '/spec/backup/tool') + const val = getValue(model, '/spec/admin/backup/enable/default') + return backup === 'KubeStash' && features.includes('backup') && val + } -function onAuthChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/authSecret/password', - value: '', - force: true, - }) -} + function onAuthChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/spec/authSecret/password', + value: '', + force: true, + }) + } -function isConfigDatabaseOn({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configDatabase') - return getValue(discriminator, '/configDatabase') -} + function isConfigDatabaseOn() { + // watchDependency('discriminator#/configDatabase') + return getValue(discriminator, '/configDatabase') + } -function clearConfiguration({ discriminator, getValue, commit }) { - const configOn = getValue(discriminator, '/configDatabase') + function clearConfiguration() { + const configOn = getValue(discriminator, '/configDatabase') - if (!configOn) { - commit('wizard/model$delete', '/spec/configuration') + if (!configOn) { + commit('wizard/model$delete', '/spec/configuration') + } } -} -function showAdditionalSettings({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return features.length -} + function showAdditionalSettings() { + // watchDependency('discriminator#/bundleApiLoaded') + return features.length + } -function getDefault({ getValue, model }, type) { - const val = getValue(model, `/spec/admin/${type}/default`) || '' - return val -} + function getDefault(type) { + const val = getValue(model, `/spec/admin/${type}/default`) || '' + return val + } -function isConfigAvailable({ getValue, model }) { - const val = getValue(model, '/spec/configuration') - return val !== '' -} + async function getReferSecrets() { + const referSecret = getValue(discriminator, '/referSecret') + if (!referSecret) { + return [] + } -async function getReferSecrets({ getValue, model, storeGet, axios, discriminator }) { - const referSecret = getValue(discriminator, '/referSecret') - if (!referSecret) { - return [] + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/metadata/release/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` + + const options = [] + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + return options } - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/metadata/release/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - - const options = [] - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) - } catch (e) { - console.log(e) + function showAuthPasswordField() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !modelPathValue && showReferSecret() } - return options -} -function showAuthPasswordField({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showSecretDropdown() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !!modelPathValue && showReferSecret() + } -function showSecretDropdown({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showReferSecret() { + const modelPathValue = getValue(discriminator, '/createAuthSecret') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue + } -function showReferSecret({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/createAuthSecret') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue -} + function getDefaultValue(path) { + const val = getValue(model, `/${path}`) || '' + return val + } -function getDefaultValue({ getValue, model }, path) { - const val = getValue(model, `/${path}`) || '' - return val -} + function showReferSecretSwitch() { + const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue && showReferSecret() + } -function showReferSecretSwitch({ model, getValue, watchDependency, discriminator }) { - const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function onReferSecretChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + } + + return { + showReferSecretSwitch, + onReferSecretChange, + getDefaultValue, + isRancherManaged, + showSecretDropdown, + showReferSecret, + getReferSecrets, + showAdditionalSettings, + initBundle, + returnFalse, + getAppBindings, + onRefChange, + isVariantAvailable, + isEqualToModelPathValue, + showAuthPasswordField, + getNamespaces, + getMachineListForOptions, + setLimits, + setRequests, + setMachineToCustom, + isMachineNotCustom, + isMachineCustom, + updateAlertValue, + onDatabaseModeChange, + getNodeTopology, + filterNodeTopology, + getAdminOptions, + isToggleOn, + showAlerts, + showIssuer, + onBackupSwitch, + setMonitoring, + onAuthChange, + isConfigDatabaseOn, + clearConfiguration, + setBackup, + getDefault, + } -function onReferSecretChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) -} -return { - showReferSecretSwitch, - onReferSecretChange, - getDefaultValue, - isRancherManaged, - showSecretDropdown, - showReferSecret, - getReferSecrets, - isConfigAvailable, - showAdditionalSettings, - initBundle, - returnFalse, - getAppBindings, - onRefChange, - isVariantAvailable, - isEqualToModelPathValue, - showAuthPasswordField, - getNamespaces, - getMachineListForOptions, - setLimits, - setRequests, - setMachineToCustom, - isMachineNotCustom, - isMachineCustom, - updateAlertValue, - onDatabaseModeChange, - getNodeTopology, - filterNodeTopology, - getAdminOptions, - isToggleOn, - showAlerts, - showIssuer, - onBackupSwitch, - setMonitoring, - onAuthChange, - isConfigDatabaseOn, - clearConfiguration, - setBackup, - getDefault, } diff --git a/charts/kubedbcom-pgbouncer-editor/ui/edit-ui.yaml b/charts/kubedbcom-pgbouncer-editor/ui/edit-ui.yaml index 3770b0b57e..95c9c4b554 100644 --- a/charts/kubedbcom-pgbouncer-editor/ui/edit-ui.yaml +++ b/charts/kubedbcom-pgbouncer-editor/ui/edit-ui.yaml @@ -1,871 +1,481 @@ -steps: -- form: - discriminator: - createAuthSecret: - type: boolean - password: - type: string - pgRef: - default: {} - type: object - elements: - - disabled: true - label: - text: labels.database.name - onChange: onNameChange - schema: - $ref: schema#/properties/metadata/properties/release/properties/name - type: input - - disabled: true - fetch: getResources|core|v1|namespaces - label: - text: labels.namespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/metadata/properties/release/properties/namespace - type: select - - disableUnselect: true - disabled: true - fetch: getPgBouncerVersions|catalog.kubedb.com|v1alpha1|pgbouncerversions - label: - text: labels.database.version - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/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/kubedbComPgBouncer/properties/metadata/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/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/kubedbComPgBouncer/properties/metadata/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/metadata/properties/annotations/additionalProperties - type: input - - hasDescription: true - label: - text: labels.deletionPolicy - options: - - description: options.deletionPolicy.delete.description - text: options.deletionPolicy.delete.label - value: Delete - - 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/kubedbComPgBouncer/properties/spec/properties/deletionPolicy - type: radio - - label: - text: labels.sync_users_question - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/database/properties/syncUsers - type: switch - - label: - text: labels.databaseref.name - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/database/properties/databaseName - type: input - - fetch: getAppBindings|postgres - label: - text: labels.databaseref.select - onChange: onRefChange - refresh: true - required: true - schema: - $ref: discriminator#/pgRef - type: select - - label: - text: labels.database.secret - type: label-element - - disabled: true - label: - text: labels.secret - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/authSecret/properties/name - type: input - - label: - text: labels.autoops - type: label-element - - label: - text: labels.disable_autoops - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/autoOps/properties/disabled - type: switch - type: single-step-form - id: basic - title: steps.0.label -- form: - elements: - - label: - text: labels.connection_pool.authType - options: - - text: md5 - value: md5 - - text: scram - value: scram - - text: cert - value: cert - - text: any - value: trust - - text: hba - value: hba - - text: pam - value: pam - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/connectionPool/properties/authType - type: select - - label: - text: labels.connection_pool.poolMode - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/connectionPool/properties/poolMode - type: input - - label: - text: labels.connection_pool.defaultPoolSize - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/connectionPool/properties/defaultPoolSize - type: input - - label: - text: labels.connection_pool.minPoolSize - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/connectionPool/properties/minPoolSize - type: input - - label: - text: labels.connection_pool.reservePoolSize - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/connectionPool/properties/reservePoolSize - type: input - - label: - text: labels.connection_pool.reservePoolTimeoutSeconds - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/connectionPool/properties/reservePoolTimeoutSeconds - type: input - - label: - text: labels.connection_pool.ignoreStartupParameters - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/connectionPool/properties/ignoreStartupParameters - type: input - - label: - text: labels.connection_pool.maxClientConnections - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/connectionPool/properties/maxClientConnections - type: input - - label: - text: labels.connection_pool.maxDBConnections - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/connectionPool/properties/maxDBConnections - type: input - - label: - text: labels.connection_pool.maxUserConnections - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/connectionPool/properties/maxUserConnections - type: input - - label: - text: labels.connection_pool.port - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/connectionPool/properties/port - type: input - - label: - text: labels.connection_pool.statsPeriodSeconds - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/connectionPool/properties/statsPeriodSeconds - type: input - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/connectionPool - type: single-step-form - id: connection-pool - title: steps.1.label -- form: - discriminator: - activeDatabaseMode: - default: Standalone - type: string - elements: - - computed: setDatabaseMode - hasDescription: true - label: - text: labels.database.mode - onChange: onDatabaseModeChange - options: - - description: options.database.mode.Standalone.description - text: options.database.mode.Standalone.label - value: Standalone - - description: options.database.mode.Cluster.description - text: options.database.mode.Cluster.label - value: Cluster - schema: - $ref: discriminator#/activeDatabaseMode - type: radio - - if: isEqualToDatabaseMode|Cluster - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/replicas - type: input - type: single-step-form - id: topology - title: steps.2.label -- form: - elements: - - alias: reusable_health_checker - chart: - name: uibytebuildersdev-component-health-checker - version: v0.29.0 - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/healthChecker - type: reusable-element - type: single-step-form - id: health-checker - title: steps.3.label -- form: - discriminator: - configureTLS: - default: true - type: boolean - elements: - - computed: isValueExistInModel|/resources/kubedbComPgBouncer/spec/tls - disabled: true - label: - text: labels.enable_tls - onChange: onTlsConfigureChange - schema: - $ref: discriminator#/configureTLS - type: switch - - disabled: true - elements: - - computed: setSSLMode - label: - text: labels.ssl_mode - options: - - text: allow - value: allow - - text: prefer - value: prefer - - text: require - value: require - - text: verify-ca - value: verify-ca - - text: verify-full - value: verify-full - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/sslMode - type: select - - elements: - - computed: setApiGroup - disabled: true - label: - text: labels.api_group - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/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/kubedbComPgBouncer/properties/spec/properties/tls/properties/issuerRef/properties/kind - type: select - - allowUserDefinedOption: true - fetch: getIssuerRefsName - label: - text: labels.name - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/tls/properties/issuerRef/properties/name - type: select - label: - text: labels.issuer_ref - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/tls/properties/issuerRef - type: single-step-form - - alias: reusable_certificates - chart: - name: uibytebuildersdev-component-certificates - version: v0.29.0 - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/tls/properties/certificates - type: reusable-element - if: showTlsConfigureSection - type: single-step-form - type: single-step-form - id: tls - title: steps.4.label -- form: - discriminator: - enableMonitoring: - default: true - type: boolean - elements: - - label: - text: labels.to_update_exporter_resources - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - function: getOpsRequestUrl|VerticalScaling - - computed: isValueExistInModel|/resources/kubedbComPgBouncer/spec/monitor - 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/kubedbComPgBouncer/properties/spec/properties/monitor/properties/agent - type: radio - - elements: - - label: - text: labels.scrapping_interval - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval - type: input - if: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComPgBouncer/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/kubedbComPgBouncer/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/kubedbComPgBouncer/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: - - if: returnFalse - label: - text: labels.resources - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/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/kubedbComPgBouncer/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/kubedbComPgBouncer/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup - type: input - - label: - text: labels.port - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/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/kubedbComPgBouncer/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args/items - type: input - label: - text: labels.args - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args - type: list-input-form - - alias: reusable_env - chart: - name: uibytebuildersdev-component-env - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/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.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - functionCallbacks: - isEditWizard: - $ref: functions#/returnTrue - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/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.29.0 - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/serviceTemplates - type: reusable-element - type: single-step-form - id: networking - title: steps.7.label -- form: +type: multi-step-form +step: + - type: single-step-form + id: compute-autoscaler + loader: getDbDetails elements: - - discriminator: - setCustomConfig: - type: string - elements: - - computed: returnStringYes - disabled: true - label: - text: labels.setCustomConfig - onChange: onSetCustomConfigChange + - type: block-layout + if: + type: function + name: isConsole + elements: + - type: input + label: Name + schema: schema/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/metadata/properties/name + - type: select + label: Select Namespace + loader: getNamespaces + if: + type: function + name: isRancherManaged + schema: schema/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/metadata/properties/namespace + - type: select + label: Select Db + loader: getDbs + validation: + type: required + refresh: true + schema: schema/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/databaseRef/properties/name + watcher: + func: initMetadata + paths: + - schema/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/databaseRef/properties/name + + - type: radio + if: + type: function + name: isConsole + label: Select Type + validation: + type: required + schema: temp/properties/autoscalingType + watcher: + func: initMetadata + paths: + - temp/properties/autoscalingType 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: - type: string + - text: Compute + value: compute + description: Scale your CPU Memory based on resource usage + - text: Storage + value: storage + description: Expand your database size based on volume usage + + - type: block-layout + showLabels: false + loader: fetchTopologyMachines elements: - - computed: setConfigurationSource - disabled: true - 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#/properties/configurationSource - type: radio - - allowUserDefinedOption: true - fetch: getSecrets - if: isEqualToDiscriminatorPath|use-existing-config|/configurationSource - label: - text: labels.name - schema: - $ref: schema#/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/configSecret/properties/name - type: select - - computed: setConfigurationForEdit - if: isEqualToDiscriminatorPath|create-new-config|/configurationSource - label: - text: labels.user_conf - onChange: onConfigurationChangeEdit - 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 -- form: - discriminator: - dbDetails: - default: false - type: boolean + # pgbouncer mode - Trigger OUTSIDE block-layout + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComPgBouncerAutoscaler/spec/compute/pgbouncer/trigger + schema: temp/properties/compute/properties/pgbouncer/properties/trigger + watcher: + func: onTriggerChange|compute/pgbouncer + paths: + - temp/properties/compute/properties/pgbouncer/properties/trigger + + # Pod LifeTime label OUTSIDE block-layout + - type: label-element + label: Pod lifetime threshold + subtitle: Specifies the duration a pod can exist before using considered for scaling decisions, ensuring resource optimization and workload stability + + # Pod LifeTime input OUTSIDE block-layout + - type: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/pgbouncer/properties/podLifeTimeThreshold + customClass: width-300 + + # NOW the pgbouncer block-layout + - type: block-layout + label: PgBouncer + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/pgbouncer + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/pgbouncer/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|min + loader: + name: getMachines|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-max + watcher: + func: onMachineChange|pgbouncer + paths: + - temp/properties/allowedMachine-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/pgbouncer/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/pgbouncer/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|max + loader: + name: getMachines|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-min + watcher: + func: onMachineChange|pgbouncer + paths: + - temp/properties/allowedMachine-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/pgbouncer/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/pgbouncer/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|pgbouncer + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/pgbouncer/properties/controlledResources + + - type: block-layout + label: Node Topology + if: + type: function + name: hasNoAnnotations + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/nodeTopology + elements: + - type: select + label: Select Node Topology + loader: fetchNodeTopology + schema: schema/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name + - type: threshold-input + label: ScaleUp Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage + - type: threshold-input + label: ScaleDown Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage + + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + # schema: schema/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/opsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: monitoring + loader: initMonitoring elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: Select Db - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: Select Type - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - discriminator: - topologyMachines: - default: [] - type: array + - type: label-element + label: To update Exporter Resource section click on Create OpsRequest + - type: anchor + label: Create OpsRequest + schema: temp/properties/opsRequestUrl + init: + type: func + value: getOpsRequestUrl|scale-vertically + - type: switch + label: Enable Monitoring + fullwidth: true + schema: temp/properties/enableMonitoring + init: + type: func + value: isValueExistInModel|/resources/kubedbComPgBouncer/spec/monitor + watcher: + func: onEnableMonitoringChange + paths: + - temp/properties/enableMonitoring + - type: block-layout + if: + type: function + name: showMonitoringSection elements: - - fetch: fetchTopologyMachines - if: returnFalse - schema: - $ref: discriminator#/topologyMachines - type: input - - elements: - - computed: setTrigger|autoscalingKubedbComPgBouncerAutoscaler/spec/compute/pgbouncer/trigger - label: - text: Trigger + - type: radio + label: Select a Monitoring Method + schema: schema/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/monitor/properties/agent + isHorizontal: true options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/pgbouncer/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/pgbouncer/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/pgbouncer/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-max: - type: string - allowedMachine-min: - type: string + - text: Prometheus Operator + value: prometheus.io/operator + description: Inject metric exporter sidecar and creates a ServiceMonitor + - text: Custom ServiceMonitor + value: prometheus.io + description: Injects the metric exporter sidecar and let you customize ServiceMonitor + - text: Custom Scrapper + value: prometheus.io/builtin + description: Inject metric exporter sidecar and add Prometheus annotations to the stats Service + init: + type: static + value: prometheus.io/operator + watcher: + func: onAgentChange + paths: + - schema/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/monitor/properties/agent + - type: block-layout + label: ServiceMonitor Configuration + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComPgBouncer/spec/monitor/agent elements: - - computed: setAllowedMachine|min - disableUnselect: true - fetch: getMachines|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|pgbouncer - schema: - $ref: discriminator#/properties/allowedMachine-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/pgbouncer/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/pgbouncer/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/pgbouncer/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|max - disableUnselect: true - fetch: getMachines|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|pgbouncer - schema: - $ref: discriminator#/properties/allowedMachine-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/pgbouncer/properties/maxAllowed/properties/cpu + - label: Scrapping Interval + schema: schema/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/pgbouncer/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/pgbouncer/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|pgbouncer - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/pgbouncer/properties/controlledResources - type: multiselect - label: - text: pgbouncer - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/pgbouncer - show_label: true - type: single-step-form - - elements: - - fetch: fetchNodeTopology - label: - text: Select Node Topology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name - type: select - - if: isNodeTopologySelected - label: - text: ScaleUp Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage - type: input - - if: isNodeTopologySelected - label: - text: ScaleDown Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage - type: input - if: hasNoAnnotations - label: - text: NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/compute/properties/nodeTopology - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgBouncerAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: compute-autoscaler - title: steps.6.label -type: multi-step-form + - type: block-layout + label: Service Monitor + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComPgBouncer/spec/monitor/agent + elements: + - type: array-object-form + label: Endpoints + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/endpoints + elements: + - type: switch + label: Honor labels + fullwidth: true + schema: honorLabels + - type: input + label: Interval + schema: interval + validation: + type: required + - type: input + label: Path + schema: path + validation: + type: required + - type: input + label: Port + schema: port + validation: + type: required + - type: select + multiple: true + label: Match Namespaces + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/namespaceSelector/properties/matchNames + loader: getResources|core|v1|namespaces + if: + type: function + name: returnFalse + - type: block-layout + showLabels: false + # schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector + if: + type: function + name: returnFalse + elements: + - type: object-item + label: Labels + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector/properties/matchLabels + - type: object-item + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/metadata/properties/labels + label : Labels + buttonClass: is-light is-outlined + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComPgBouncer/spec/monitor/agent + # individualItemDisabilityCheck: disableLableChecker + - type: label-element + label: Exporter Configuration + schema: '' + - type: switch + label: Customize Exporter Sidecar + fullwidth: true + schema: temp/properties/customizeExporter + init: + type: static + value: true + watcher: + func: onCustomizeExporterChange + paths: + - temp/properties/customizeExporter + - type: block-layout + label: Customer Exporter Section + showLabels: false + if: + type: function + name: showCustomizeExporterSection + elements: + - type: machine-compare + label: Resources + schema: schema/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/resources + if: + type: function + name: returnFalse + - type: label-element + label: Security Context + schema: '' + - type: input + schema: schema/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsUser + label: Run as User + - type: input + schema: schema/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup + label: Run as Group + - type: input + schema: schema/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/port + label: Port + - type: array-item-form + label: Args + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/kubedbComPgBouncer/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args + init: + type: static + value: ['--compatible-mode'] + element: + type: input + label: Args + # isSubsection: true + - type: block-layout + label: Metadata + showLabels: false + elements: + - type: array-object-form + init: + type: func + value: initEnvArray + label: Environment Variables + buttonClass: is-light is-outlined + watcher: + func: onEnvArrayChange + paths: + - temp/properties/env + schema: temp/properties/env + elements: + - type: input + label: Name + schema: name + validation: + type: required + - type: radio + label: Value From + schema: temp/properties/valueFromType + validation: + type: required + init: + type: func + value: setValueFrom + options: + - text: Input + value: input + - text: Secret + value: secret + - text: ConfigMap + value: configMap + watcher: + func: onValueFromChange + paths: + - temp/properties/valueFromType + - type: input + label: Value + schema: value + validation: + type: required + if: + name: isEqualToTemp|input + type: function + - type: select + if: + type: function + name: isEqualToTemp|configMap + label: ConfigMap Name + schema: valueFrom/properties/configMapKeyRef/properties/name + loader: + name: resourceNames|core|v1|configmaps + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: ConfigMap Key + schema: valueFrom/properties/configMapKeyRef/properties/key + if: + type: function + name: isEqualToTemp|configMap + loader: + name: getConfigMapKeys + watchPaths: + - schema/resources/kubedbComPgBouncer/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/configMapKeyRef/name + - schema/metadata/release/namespace + - type: select + label: Secret Name + schema: valueFrom/properties/secretKeyRef/properties/name + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecrets + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: Secret Key + schema: valueFrom/properties/secretKeyRef/properties/key + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecretKeys + watchPaths: + - schema/resources/kubedbComPgBouncer/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/secretKeyRef/name + - schema/metadata/release/namespace \ No newline at end of file diff --git a/charts/kubedbcom-pgbouncer-editor/ui/functions.js b/charts/kubedbcom-pgbouncer-editor/ui/functions.js index 70287e11e4..fe7cd5e101 100644 --- a/charts/kubedbcom-pgbouncer-editor/ui/functions.js +++ b/charts/kubedbcom-pgbouncer-editor/ui/functions.js @@ -1,2190 +1,903 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + // ************************* common functions ******************************************** // eslint-disable-next-line no-empty-pattern -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 disableLableChecker({ itemCtx }) { - const { key } = itemCtx - if (key.startsWith('app.kubernetes.io') || key.includes('helm')) return true - else return false -} - -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} - -async function getResources({ axios, storeGet }, 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 [] - } -} - -function isEqualToDiscriminatorPath( - { discriminator, getValue, watchDependency }, - value, - discriminatorPath, -) { - watchDependency('discriminator#' + discriminatorPath) - const discriminatorValue = getValue(discriminator, discriminatorPath) - return discriminatorValue === value -} - -function setValueFromModel({ getValue, model }, path) { - return getValue(model, path) -} - -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 -} - -async function getResourceList(axios, storeGet, { 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( - { axios, getValue, model, watchDependency, storeGet }, - 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 unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) - - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) - } +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + /********** Initialize Discriminator **************/ + + 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 autoscaleType = '' + let dbDetails = {} + let instance = '' + + function isConsole() { + const isKube = isKubedb() + + if (isKube) { + const dbName = storeGet('/route/params/name') || '' + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComPgBouncerAutoscaler/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/autoscalingKubedbComPgBouncerAutoscaler/metadata/name', + value: modifiedName, + force: true, + }) + const namespace = storeGet('/route/query/namespace') || '' + if (namespace) { + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComPgBouncerAutoscaler/metadata/namespace', + value: namespace, + force: true, + }) + } } - }) -} - -function returnTrue() { - return true -} - -function returnStringYes() { - return 'yes' -} -function setAddressType({ model, getValue }) { - const value = getValue(model, '/resources/kubedbComPgBouncer/spec/useAddressType') - if (!value) { - return 'DNS' + return !isKube } - return value -} - -// ************************* Basic Info ********************************************** -async function getPgBouncerVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, - }, - }, + function isKubedb() { + return !!storeGet('/route/params/actions') } - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, + async function getDbDetails() { + const annotations = getValue( + model, + '/resources/autoscalingKubedbComPgBouncerAutoscaler/metadata/annotations', ) + instance = annotations?.['kubernetes.io/instance-type'] + + const owner = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + const namespace = + storeGet('/route/query/namespace') || + getValue(model, '/resources/autoscalingKubedbComPgBouncerAutoscaler/metadata/namespace') || + '' + const name = + storeGet('/route/params/name') || + getValue(model, '/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/databaseRef/name') || + '' + + if (namespace && name) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/pgbouncers/${name}`, + ) + dbDetails = resp.data || {} + setDiscriminatorValue('/dbDetails', true) + } catch (e) { + console.log(e) + } + } - const resources = (resp && resp.data && resp.data.items) || [] - - // keep only non deprecated versions - const filteredMongoDbVersions = resources.filter((item) => item.spec && !item.spec.deprecated) - - filteredMongoDbVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredMongoDbVersions - } catch (e) { - console.log(e) - return [] - } -} - -// ********************* Database Mode *********************** -function setDatabaseMode({ model, getValue }) { - const replicas = getValue(model, '/resources/kubedbComPgBouncer/spec/replicas') - - return replicas === 1 ? 'Standalone' : 'Cluster' -} - -function isEqualToDatabaseMode({ getValue, watchDependency, discriminator }, value) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - return mode === value -} - -const onDatabaseModeChange = ({ discriminator, getValue, commit }) => { - const databaseMode = getValue(discriminator, '/activeDatabaseMode') - - commit('wizard/model$update', { - path: '/resources/kubedbComPgBouncer/spec/replicas', - value: databaseMode === 'Standalone' ? 1 : 3, - force: true, - }) -} - -// ************************** TLS ******************************88 - -function setApiGroup() { - return 'cert-manager.io' -} - -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - watchDependency('model#/resources/kubedbComPgBouncer/spec/tls/issuerRef/apiGroup') - watchDependency('model#/resources/kubedbComPgBouncer/spec/tls/issuerRef/kind') - watchDependency('model#/metadata/release/namespace') - const apiGroup = getValue(model, '/resources/kubedbComPgBouncer/spec/tls/issuerRef/apiGroup') - const kind = getValue(model, '/resources/kubedbComPgBouncer/spec/tls/issuerRef/kind') - const namespace = getValue(model, '/metadata/release/namespace') - - let url - if (kind === 'Issuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/namespaces/${namespace}/issuers` - } else if (kind === 'ClusterIssuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/clusterissuers` - } - - if (!url) return [] - - 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 + commit('wizard/model$update', { + path: `/metadata/release/name`, + value: name, + force: true, }) - return resources - } catch (e) { - console.log(e) - return [] - } -} - -async function hasIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await getIssuerRefsName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !!(resp && resp.length) -} - -async function hasNoIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await hasIssuerRefName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !resp -} - -function setSSLMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComPgBouncer/spec/sslMode') - return val || 'require' -} - -function showTlsConfigureSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configureTLS') - const configureStatus = getValue(discriminator, '/configureTLS') - return configureStatus -} - -function onTlsConfigureChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/configureTLS') - if (configureStatus) { commit('wizard/model$update', { - path: '/resources/kubedbComPgBouncer/spec/tls', - value: { issuerRef: {}, certificates: [] }, + path: `/metadata/release/namespace`, + value: namespace, force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComPgBouncer/spec/tls') - commit('wizard/model$delete', '/resources/kubedbComPgBouncer/spec/sslMode') - } -} - -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} - -/****** Monitoring *********/ - -function showMonitoringSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/enableMonitoring') - const configureStatus = getValue(discriminator, '/enableMonitoring') - return configureStatus -} - -function onEnableMonitoringChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/enableMonitoring') - if (configureStatus) { commit('wizard/model$update', { - path: '/resources/kubedbComPgBouncer/spec/monitor', - value: {}, + path: `/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/databaseRef/name`, + value: name, force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComPgBouncer/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, getValue }) { - watchDependency('discriminator#/customizeExporter') - const configureStatus = getValue(discriminator, '/customizeExporter') - return configureStatus -} - -function onCustomizeExporterChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/customizeExporter') - if (configureStatus) { commit('wizard/model$update', { - path: '/resources/kubedbComPgBouncer/spec/monitor/prometheus/exporter', - value: {}, + path: `/resources/autoscalingKubedbComPgBouncerAutoscaler/metadata/labels`, + value: dbDetails.metadata.labels, force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComPgBouncer/spec/monitor/prometheus/exporter') } -} -// ********************************* Initialization & Backup ************************************* -const stashAppscodeComRestoreSession_init = { - spec: { - repository: { - name: '', - }, - rules: [ - { - snapshots: ['latest'], - }, - ], - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} -const initScript = { - scriptPath: '', - secret: { - secretName: '', - }, -} -const stashAppscodeComRepository_init_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const stashAppscodeComRepository_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const restoreSessionInitRunTimeSettings = { - container: { - resources: { - requests: { - cpu: '', - memory: '', - }, - limits: { - cpu: '', - memory: '', - }, - }, - nice: { - adjustment: null, - }, - ionice: { - class: null, - classData: null, - }, - securityContext: { - privileged: false, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - env: [], - envFrom: [], - }, - pod: { - serviceAccountName: '', - imagePullSecrets: [], - securityContext: { - fsGroup: null, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - }, -} - -const stashAppscodeComBackupConfiguration = { - spec: { - repository: { - name: '', - }, - retentionPolicy: { - keepLast: 5, - name: 'keep-last-5', - prune: true, - }, - schedule: '*/5 * * * *', - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} + async function getNamespaces() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function valueExists(value, getValue, path) { - const val = getValue(value, path) - if (val) return true - else return false -} - -function initPrePopulateDatabase({ getValue, model }) { - const waitForInitialRestore = getValue( - model, - '/resources/kubedbComPgBouncer/spec/init/waitForInitialRestore', - ) - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - const script = getValue(model, '/resources/kubedbComPgBouncer/spec/init/script') + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, + }) - return waitForInitialRestore || !!stashAppscodeComRestoreSession_init || !!script ? 'yes' : 'no' -} + const resources = (resp && resp.data && resp.data.items) || [] -function onPrePopulateDatabaseChange({ commit, getValue, discriminator, model }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - if (prePopulateDatabase === 'no') { - // delete related properties - commit('wizard/model$update', { - path: '/resources/kubedbComPgBouncer/spec/init/waitForInitialRestore', - value: false, + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } }) - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - commit('wizard/model$delete', '/resources/kubedbComPgBouncer/spec/init/script') - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else { - const dbName = getValue(model, '/metadata/release/name') - // set stashAppscodeComRestoreSession_init if it doesn't exist - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - force: true, - }) - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - } } -} - -function initDataSource({ getValue, model }) { - const script = getValue(model, '/resources/kubedbComPgBouncer/spec/init/script') - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - - if (script) return 'script' - else if (stashAppscodeComRestoreSession_init) return 'stashBackup' - else return undefined -} - -function onDataSourceChange({ commit, getValue, discriminator, model }) { - const dataSource = getValue(discriminator, '/dataSource') - - commit('wizard/model$update', { - path: '/resources/kubedbComPgBouncer/spec/init/waitForInitialRestore', - value: dataSource === 'stashBackup', - force: true, - }) - - if (dataSource === 'script') { - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - - // create a new script if there is no script property - if (!valueExists(model, getValue, '/resources/kubedbComPgBouncer/spec/init/script')) - commit('wizard/model$update', { - path: '/resources/kubedbComPgBouncer/spec/init/script', - value: initScript, - }) - } else if (dataSource === 'stashBackup') { - commit('wizard/model$delete', '/resources/kubedbComPgBouncer/spec/init/script') - - // create a new stashAppscodeComRestoreSession_init if there is no stashAppscodeComRestoreSession_init property - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - const dbName = getValue(model, '/metadata/release/name') - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - }) - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - } + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found } -} -// // for script -function initVolumeType({ getValue, model }) { - const configMap = getValue(model, '/resources/kubedbComPgBouncer/spec/init/script/configMap/name') - const secret = getValue(model, '/resources/kubedbComPgBouncer/spec/init/script/secret/secretName') - - if (configMap) return 'configMap' - else if (secret) return 'secret' - else return undefined -} - -function onVolumeTypeChange({ commit, getValue, discriminator, model }) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - if (sourceVolumeType === 'configMap') { - // add configMap object and delete secret object - commit('wizard/model$delete', '/resources/kubedbComPgBouncer/spec/init/script/secret') - - if (!valueExists(model, getValue, '/resources/kubedbComPgBouncer/spec/init/script/configMap')) { - commit('wizard/model$update', { - path: '/resources/kubedbComPgBouncer/spec/init/script/configMap', - value: { - name: '', - }, - }) - } - } else if (sourceVolumeType === 'secret') { - // delete configMap object and add secret object - commit('wizard/model$delete', '/resources/kubedbComPgBouncer/spec/init/script/configMap') - - if (!valueExists(model, getValue, '/resources/kubedbComPgBouncer/spec/init/script/secret')) { - commit('wizard/model$update', { - path: '/resources/kubedbComPgBouncer/spec/init/script/secret', - value: { - secretName: '', - }, - }) + function onNamespaceChange() { + const namespace = getValue( + model, + '/resources/autoscalingKubedbComPgBouncerAutoscaler/metadata/namespace', + ) + if (!namespace) { + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/databaseRef/name', + ) } } -} - -function showInitializationForm({ getValue, discriminator, watchDependency }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - watchDependency('discriminator#/prePopulateDatabase') - return prePopulateDatabase === 'yes' -} - -function showScriptOrStashForm({ getValue, discriminator, watchDependency }, value) { - const dataSource = getValue(discriminator, '/dataSource') - watchDependency('discriminator#/dataSource') - return dataSource === value -} - -function showConfigMapOrSecretName({ getValue, discriminator, watchDependency }, value) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - watchDependency('discriminator#/sourceVolumeType') - return sourceVolumeType === value -} - -// for stash backup -function initializeNamespace({ getValue, model }) { - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} -function showRepositorySelectOrCreate({ getValue, discriminator, watchDependency }, value) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') + async function getDbs() { + // watchDependency('model#/resources/autoscalingKubedbComPgBouncerAutoscaler/metadata/namespace') + const namespace = getValue( + model, + '/resources/autoscalingKubedbComPgBouncerAutoscaler/metadata/namespace', + ) + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - return repositoryChoise === value -} + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) -function onInitRepositoryChoiseChange({ getValue, discriminator, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - if (repositoryChoise === 'select') { - // delete stashAppscodeComRepository_init_repo from model - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else if (repositoryChoise === 'create') { - // add stashAppscodeComRepository_init_repo to model - commit('wizard/model$update', { - path: 'resources/stashAppscodeComRepository_init_repo', - value: stashAppscodeComRepository_init_repo, - }) + const resources = (resp && resp.data && resp.data.items) || [] - const repositoryName = `${getValue(model, '/metadata/release/name')}-init-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: repositoryName, + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } }) } -} -function initCustomizeRestoreJobRuntimeSettings({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function initCustomizeRestoreJobRuntimeSettingsForBackup({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function onCustomizeRestoreJobRuntimeSettingsChange({ commit, getValue, discriminator, model }) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - ) { - // set new value + function initMetadata() { + const dbName = + getValue(model, '/resources/autoscalingKubedbComPgBouncerAutoscaler/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/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - value: restoreSessionInitRunTimeSettings, + path: '/resources/autoscalingKubedbComPgBouncerAutoscaler/metadata/name', + value: modifiedName, + force: true, }) - } - } -} -function onCustomizeRestoreJobRuntimeSettingsChangeForBackup({ - commit, - getValue, - discriminator, - model, -}) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', + // delete the other type object from model + if (type === 'compute') + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/storage', + ) + if (type === 'storage') + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/compute', ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - value: {}, - force: true, - }) - } } -} - -function showRuntimeForm({ discriminator, getValue, watchDependency }, value) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - watchDependency('discriminator#/customizeRestoreJobRuntimeSettings') - return customizeRestoreJobRuntimeSettings === value -} - -async function getImagePullSecrets({ getValue, model, watchDependency, axios, storeGet }) { - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - - let resources = await getNamespacedResourceList(axios, storeGet, { - namespace, - group: 'core', - version: 'v1', - resource: 'secrets', - }) - - resources = resources.filter((item) => { - const validType = ['kubernetes.io/dockerconfigjson'] - return validType.includes(item.type) - }) - - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: { name: name }, - } - }) -} - -// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// FOR Backup Configuration + async function fetchTopologyMachines() { + const instance = hasAnnotations() -// schedule bakcup + 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) -function getBackupConfigsAndAnnotations(getValue, model) { - const stashAppscodeComBackupConfiguration = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration', - ) - const kubedbComPgBouncerAnnotations = - getValue(model, '/resources/kubedbComPgBouncer/metadata/annotations') || {} - - const isBluePrint = Object.keys(kubedbComPgBouncerAnnotations).some( - (k) => - k === 'stash.appscode.com/backup-blueprint' || - k === 'stash.appscode.com/schedule' || - k.startsWith('params.stash.appscode.com/'), - ) - - return { - stashAppscodeComBackupConfiguration, - isBluePrint, + const nodeGroups = resp.data?.spec?.nodeGroups || [] + setDiscriminatorValue('/topologyMachines', nodeGroups) + return nodeGroups + } catch (e) { + console.log(e) + return [] + } + } } -} - -function deleteKubeDbComPgBouncerDbAnnotation(getValue, model, commit) { - const annotations = getValue(model, '/resources/kubedbComPgBouncer/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/kubedbComPgBouncer/metadata/annotations', - value: filteredAnnotations, - }) -} - -function addKubeDbComPgBouncerDbAnnotation(getValue, model, commit, key, value, force) { - const annotations = getValue(model, '/resources/kubedbComPgBouncer/metadata/annotations') || {} - if (annotations[key] === undefined) { - annotations[key] = value - } else if (force) { - annotations[key] = value + function setTrigger(path) { + let value = getValue(model, `/resources/${path}`) + if (value) return value + return 'On' } - commit('wizard/model$update', { - path: '/resources/kubedbComPgBouncer/metadata/annotations', - value: annotations, - force: true, - }) -} - -function initScheduleBackupForEdit({ getValue, model, setDiscriminatorValue }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function initScheduleBackup({ getValue, model }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function onScheduleBackupChange({ commit, getValue, discriminator, model }) { - 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 kubedbComPgBouncer annotation - deleteKubeDbComPgBouncerDbAnnotation(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 setApplyToIfReady() { + return 'IfReady' } -} - -// backup form -function showBackupForm({ getValue, discriminator, watchDependency }) { - const scheduleBackup = getValue(discriminator, '/scheduleBackup') - watchDependency('discriminator#/scheduleBackup') - - if (scheduleBackup === 'yes') return true - else return false -} -// invoker form -function initBackupInvoker({ getValue, model }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - if (stashAppscodeComBackupConfiguration) return 'backupConfiguration' - else if (isBluePrint) return 'backupBlueprint' - else return undefined -} + function hasAnnotations() { + const annotations = + getValue(model, '/resources/autoscalingKubedbComPgBouncerAutoscaler/metadata/annotations') || + {} + const instance = annotations['kubernetes.io/instance-type'] -function onBackupInvokerChange({ getValue, discriminator, commit, model }) { - const backupInvoker = getValue(discriminator, '/backupInvoker') - - if (backupInvoker === 'backupConfiguration') { - // delete annotation and create backup config object - deleteKubeDbComPgBouncerDbAnnotation(getValue, model, commit) - const dbName = getValue(model, '/metadata/release/name') - - if (!valueExists(model, getValue, '/resources/stashAppscodeComBackupConfiguration')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration', - value: stashAppscodeComBackupConfiguration, - }) - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, - force: true, - }) - } - } else if (backupInvoker === 'backupBlueprint') { - // delete backup configuration object and create the annotation - commit('wizard/model$delete', '/resources/stashAppscodeComBackupConfiguration') - addKubeDbComPgBouncerDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/backup-blueprint', - '', - ) + return !!instance } -} - -function showInvokerForm({ getValue, discriminator, watchDependency }, value) { - const backupInvoker = getValue(discriminator, '/backupInvoker') - watchDependency('discriminator#/backupInvoker') - - return backupInvoker === value -} - -// backup configuration form -function initalizeTargetReferenceName({ getValue, model, watchDependency }) { - const databaseName = getValue(model, '/metadata/release/name') - watchDependency('model#/metadata/release/name') - - return databaseName -} -// restore session repository -function setInitialRestoreSessionRepo({ getValue, model }) { - const value = getValue(model, 'resources/stashAppscodeComRepository_init_repo') - return value ? 'create' : 'select' -} - -// backup config repository -function initRepositoryChoise({ getValue, model }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - - if (stashAppscodeComRepository_repo) return 'create' - else return 'select' -} - -function initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' - setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) - - return repoInitialSelectionStatus -} - -function onRepositoryChoiseChange({ getValue, discriminator, watchDependency, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - if (repositoryChoise === 'select') { - // delete the stashAppscodeComRepository_repo - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') - } else if (repositoryChoise === 'create') { - // create new stashAppscodeComRepository_repo - if (!valueExists(model, getValue, '/resources/stashAppscodeComRepository_repo')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRepository_repo', - value: stashAppscodeComRepository_repo, - }) - const repositoryName = `${getValue(model, '/metadata/release/name')}-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) - } + function hasNoAnnotations() { + return !hasAnnotations() } -} - -function onRepositoryNameChange({ getValue, model, commit }) { - const repositoryName = getValue(model, 'resources/stashAppscodeComRepository_repo/metadata/name') - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) -} - -// backup blueprint form -function getMongoAnnotations(getValue, model) { - const annotations = getValue(model, '/resources/kubedbComPgBouncer/metadata/annotations') - return { ...annotations } || {} -} - -function initFromAnnotationValue({ getValue, model }, key) { - const annotations = getMongoAnnotations(getValue, model) - return annotations[key] -} - -function onBackupBlueprintNameChange({ getValue, discriminator, commit, model }) { - const backupBlueprintName = getValue(discriminator, '/backupBlueprintName') - addKubeDbComPgBouncerDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/backup-blueprint', - backupBlueprintName, - true, - ) -} - -function onBackupBlueprintScheduleChange({ getValue, discriminator, commit, model }) { - const backupBlueprintSchedule = getValue(discriminator, '/schedule') - addKubeDbComPgBouncerDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/schedule', - backupBlueprintSchedule, - true, - ) -} + function setAllowedMachine(minmax) { + const mx = instance?.includes(',') ? instance.split(',')[1] : '' + const mn = instance?.includes(',') ? instance.split(',')[0] : '' + const machineName = minmax === 'min' ? mn : mx -function initFromAnnotationKeyValue({ getValue, model }, prefix) { - const annotations = getMongoAnnotations(getValue, model) - const newOb = {} - Object.keys(annotations).forEach((key) => { - if (key.startsWith(prefix)) { - const newKey = key.replace(prefix, '') - newOb[newKey] = annotations[key] + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] + const machineData = nodeGroups.find((item) => item.topologyValue === machineName) + if (machineData) { + return { + machine: machineName, + cpu: machineData.allocatable?.cpu, + memory: machineData.allocatable?.memory, + } } - }) - return newOb -} - -function onTaskParametersChange({ getValue, discriminator, model, commit }) { - const taskParameters = getValue(discriminator, '/taskParameters') - - const taskParamterKeys = Object.keys(taskParameters).map( - (tp) => `params.stash.appscode.com/${tp}`, - ) - const oldAnnotations = getValue(model, '/resources/kubedbComPgBouncer/metadata/annotations') || {} - const newAnnotations = {} + return { machine: machineName || '', cpu: '', memory: '' } + } - const filteredAnnotationKeys = Object.keys(oldAnnotations).filter( - (key) => !taskParamterKeys.includes(key) && !key.startsWith('params.stash.appscode.com/'), - ) + async function getMachines(minmax) { + // watchDependency('discriminator#/topologyMachines') + const depends = minmax === 'min' ? 'max' : 'min' + const dependantPath = `/allowedMachine-${depends}` - filteredAnnotationKeys.forEach((key) => { - newAnnotations[key] = oldAnnotations[key] - }) + // watchDependency(`discriminator#${dependantPath}`) + const dependantMachineObj = getValue(discriminator, dependantPath) + const dependantMachine = dependantMachineObj?.machine || '' - Object.keys(taskParameters).forEach((tpk) => { - newAnnotations[`params.stash.appscode.com/${tpk}`] = taskParameters[tpk] - }) + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] - commit('wizard/model$update', { - path: '/resources/kubedbComPgBouncer/metadata/annotations', - value: newAnnotations, - }) -} + const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) -function isValueExistInModel({ model, getValue }, path) { - const modelValue = getValue(model, path) - return !!modelValue -} - -function onNamespaceChange({ commit, model, getValue }) { - const namespace = getValue(model, '/metadata/release/namespace') - const agent = getValue(model, '/resources/kubedbComPgBouncer/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', - value: [namespace], - force: true, + 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, + }, + } }) - } -} -function onLabelChange({ commit, model, getValue }) { - const labels = getValue(model, '/resources/kubedbComPgBouncer/spec/metadata/labels') - - const agent = getValue(model, '/resources/kubedbComPgBouncer/spec/monitor/agent') + const filteredMachine = machines?.filter((item, ind) => + minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, + ) - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) + return dependantIndex === -1 ? machines : filteredMachine } -} - -function onNameChange({ commit, model, getValue }) { - const dbName = getValue(model, '/metadata/release/name') - const agent = getValue(model, '/resources/kubedbComPgBouncer/spec/monitor/agent') + function onMachineChange(type) { + const annoPath = '/resources/autoscalingKubedbComPgBouncerAutoscaler/metadata/annotations' + const annotations = getValue(model, annoPath) || {} + const instance = annotations['kubernetes.io/instance-type'] - const labels = getValue(model, '/resources/kubedbComPgBouncer/spec/metadata/labels') - - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) - } + 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 - const scheduleBackup = getValue(model, '/resources/stashAppscodeComBackupConfiguration') + const minMachineAllocatable = minMachineObj + ? { cpu: minMachineObj.cpu, memory: minMachineObj.memory } + : null + const maxMachineAllocatable = maxMachineObj + ? { cpu: maxMachineObj.cpu, memory: maxMachineObj.memory } + : null + const allowedPath = `/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/compute/${type}` - if (scheduleBackup) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_repo') - if (creatingNewRepo) { + if (minMachine && maxMachine && instance !== minMaxMachine) { commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: `${dbName}-repo`, + path: `${allowedPath}/maxAllowed`, + value: maxMachineAllocatable, force: true, }) - } - } - - const prePopulateDatabase = getValue(model, '/resources/stashAppscodeComRestoreSession_init') - - if (prePopulateDatabase) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_init_repo') - if (creatingNewRepo) { commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: `${dbName}-init-repo`, + path: `${allowedPath}/minAllowed`, + value: minMachineAllocatable, + force: true, + }) + commit('wizard/model$update', { + path: annoPath, + value: annotations, force: true, }) } } - - // to reset configSecret name field - const hasSecretConfig = getValue(model, '/resources/secret_config') - if (hasSecretConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComPgBouncer/spec/configSecret/name', - value: `${dbName}-config`, - force: true, - }) - } - - // to reset shard configSecret name field - const hasSecretShardConfig = getValue(model, '/resources/secret_shard_config') - if (hasSecretShardConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComPgBouncer/spec/shardTopology/shard/configSecret/name', - value: `${dbName}-shard-config`, - force: true, - }) - } - - // to reset shard configSecret name field - const hasSecretConfigServerConfig = getValue(model, '/resources/secret_configserver_config') - if (hasSecretConfigServerConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComPgBouncer/spec/shardTopology/configServer/configSecret/name', - value: `${dbName}-configserver-config`, - force: true, - }) - } - - // to reset mongos configSecret name field - const hasSecretMongosConfig = getValue(model, '/resources/secret_mongos_config') - if (hasSecretMongosConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComPgBouncer/spec/shardTopology/mongos/configSecret/name', - value: `${dbName}-mongos-config`, - force: true, - }) - } -} - -function returnFalse() { - return false -} - -function onAgentChange({ commit, model, getValue }) { - const agent = getValue(model, '/resources/kubedbComPgBouncer/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', - value: [], - force: true, - }) - - onNamespaceChange({ commit, model, getValue }) - onLabelChange({ commit, model, getValue }) - } else { - commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') - } -} - -/************************************* Database Secret Section ********************************************/ - -function getCreateAuthSecret({ model, getValue }) { - const authSecret = getValue(model, '/resources/kubedbComPgBouncer/spec/authSecret') - - return !authSecret -} - -function showExistingSecretSection({ getValue, watchDependency, discriminator }) { - watchDependency('discriminator#/createAuthSecret') - const hasAuthSecretName = getValue(discriminator, '/createAuthSecret') - return !hasAuthSecretName -} - -function showPasswordSection({ getValue, watchDependency, discriminator }) { - return !showExistingSecretSection({ - getValue, - watchDependency, - discriminator, - }) -} - -function setAuthSecretPassword({ model, getValue }) { - const encodedPassword = getValue(model, '/resources/secret_auth/data/password') - return encodedPassword ? decodePassword({}, encodedPassword) : '' -} - -function onAuthSecretPasswordChange({ getValue, discriminator, commit }) { - const stringPassword = getValue(discriminator, '/password') - - if (stringPassword) { - commit('wizard/model$update', { - path: '/resources/secret_auth/data/password', - value: encodePassword({}, stringPassword), - force: true, - }) + + function setControlledResources(type) { + const list = ['cpu', 'memory'] + const path = `/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/compute/${type}/controlledResources` commit('wizard/model$update', { - path: '/resources/secret_auth/data/username', - value: encodePassword({}, 'root'), + path: path, + value: list, force: true, }) - } else { - commit('wizard/model$delete', '/resources/secret_auth') + return list } -} -function disableInitializationSection({ model, getValue, watchDependency }) { - const initialized = getValue(model, '/resources/kubedbComPgBouncer/spec/init/initialized') - watchDependency('model#/resources/kubedbComPgBouncer/spec/init/initialized') - return !!initialized -} + 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 [] + } -// eslint-disable-next-line no-empty-pattern -function encodePassword({}, value) { - return btoa(value) -} + function isNodeTopologySelected() { + // watchDependency( + // 'model#/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/compute/nodeTopology/name', + // ) + const nodeTopologyName = + getValue( + model, + '/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/compute/nodeTopology/name', + ) || '' + return !!nodeTopologyName.length + } -// eslint-disable-next-line no-empty-pattern -function decodePassword({}, value) { - return atob(value) -} + function showOpsRequestOptions() { + if (isKubedb() === true) return true + // watchDependency('model#/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/databaseRef/name') + // watchDependency('discriminator#/autoscalingType') + return ( + !!getValue( + model, + '/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/databaseRef/name', + ) && !!getValue(discriminator, '/autoscalingType') + ) + } + + /****** Monitoring *********/ -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/resources/kubedbComPgBouncer/spec/authSecret') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/resources/secret_auth') + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value } -} -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - if (owner && cluster && namespace) { try { const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, { - params: { - filter: { - items: { - data: { username: null, password: null }, - metadata: { name: null }, - type: null, - }, - }, - }, + params: { filter: { items: { metadata: { name: null } } } }, }, ) - const secrets = (resp && resp.data && resp.data.items) || [] - - const filteredSecrets = secrets.filter((item) => { - const validType = [ - 'kubernetes.io/service-account-token', - 'Opaque', - 'kubernetes.io/basic-auth', - ] - return validType.includes(item.type) - }) + const resources = (resp && resp.data && resp.data.items) || [] - filteredSecrets.map((item) => { + resources.map((item) => { const name = (item.metadata && item.metadata.name) || '' item.text = name item.value = name return true }) - return filteredSecrets + return resources } catch (e) { console.log(e) + return [] } } - return [] -} -//////////////////// custom config ///////////////// -function onConfigurationSourceChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSource') - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_config') - } else { - const value = getValue(model, '/resources/secret_config') - if (!value) { + 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/secret_config', + path: '/resources/kubedbComPgBouncer/spec/monitor', value: {}, force: true, }) + } else { + commit('wizard/model$delete', '/resources/kubedbComPgBouncer/spec/monitor') } - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: '/resources/kubedbComPgBouncer/spec/configSecret/name', - value: configSecretName, + path: '/form/alert/enabled', + value: configureStatus ? 'warning' : 'none', force: true, }) } -} - -function onConfigurationChange({ getValue, commit, discriminator, model }) { - const value = getValue(discriminator, '/configuration') - commit('wizard/model$update', { - path: '/resources/secret_config/stringData/user.conf', - value: value, - force: true, - }) - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComPgBouncer/spec/configSecret/name', - value: configSecretName, - force: true, - }) -} -function onConfigurationChangeEdit({ getValue, commit, discriminator, model }) { - const value = getValue(discriminator, '/configuration') - - commit('wizard/model$update', { - path: '/resources/secret_config/data/pgbouncer.ini', - value: btoa(value), - force: true, - }) - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComPgBouncer/spec/configSecret/name', - value: configSecretName, - force: true, - }) -} - -function setConfigurationSource({ model, getValue }) { - const modelValue = getValue(model, '/resources/secret_config') - if (modelValue) { - return 'create-new-config' + function showCustomizeExporterSection() { + // watchDependency('discriminator#/customizeExporter') + const configureStatus = getValue(discriminator, '/customizeExporter') + return configureStatus } - return 'use-existing-config' -} - -function setSecretConfigNamespace({ getValue, model, watchDependency }) { - watchDependency('model#/metadata/release/namespace') - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} - -function setConfiguration({ model, getValue }) { - return getValue(model, '/resources/secret_config/stringData/user.conf') -} - -function setConfigurationForEdit({ model, getValue }) { - const value = getValue(model, '/resources/secret_config/data/pgbouncer.ini') - return atob(value) -} - -function setConfigurationFiles({ model, getValue }) { - const value = getValue(model, '/resources/secret_config/data/user.conf') - return atob(value) -} - -function onSetCustomConfigChange({ discriminator, getValue, commit }) { - const value = getValue(discriminator, '/setCustomConfig') - if (value === 'no') { - commit('wizard/model$delete', '/resources/kubedbComPgBouncer/spec/configSecret') - commit('wizard/model$delete', '/resources/secret_config') + function onCustomizeExporterChange() { + const configureStatus = getValue(discriminator, '/customizeExporter') + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComPgBouncer/spec/monitor/prometheus/exporter', + value: {}, + force: true, + }) + } else { + commit( + 'wizard/model$delete', + '/resources/kubedbComPgBouncer/spec/monitor/prometheus/exporter', + ) + } } -} - -function getOpsRequestUrl({ storeGet, model, getValue, mode }, 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 + `/create-opsrequest-${reqType.toLowerCase()}?namespace=${namespace}` - - if (mode === 'standalone-step') return pathConstructedForKubedb - else - return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/pgbounceropsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` -} - -const getAppbinding = async ({ axios, storeGet, getValue, watchDependency, rootModel }) => { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const group = 'appcatalog.appscode.com' - const version = 'v1alpha1' - const resource = 'appbindings' - - watchDependency('rootModel#/databaseRef/namespace') - const namespace = getValue(rootModel, '/databaseRef/namespace') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}`, - { - params: { - filter: { items: { metadata: { name: null }, type: 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 -} - -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} - -function onRefChange({ discriminator, getValue, commit }) { - const ref = getValue(discriminator, '/pgRef') || {} - commit('wizard/model$update', { - path: '/resources/kubedbComPgBouncer/spec/database/databaseRef/name', - value: ref.name || '', - force: true, - }) - commit('wizard/model$update', { - path: '/resources/kubedbComPgBouncer/spec/database/databaseRef/namespace', - value: ref.namespace || '', - force: true, - }) -} - -async function getAppBindings({ axios, storeGet }, type) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const queryParams = { - filter: { - items: { - metadata: { name: null, namespace: null }, - spec: { type: null }, - }, - }, + function isValueExistInModel(path) { + const modelValue = getValue(model, path) || null + return !!modelValue } - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/appcatalog.appscode.com/v1alpha1/appbindings`, - queryParams, - ) - const resources = (resp && resp.data && resp.data.items) || [] - const fileredResources = resources - .filter((item) => item.spec?.type === `kubedb.com/${type}`) - .map((item) => { - const name = item.metadata?.name || '' - const namespace = item.metadata?.namespace || '' - return { - text: `${namespace}/${name}`, - value: { - name: name, - namespace: namespace, - }, - } - }) - return fileredResources - } catch (e) { - console.log(e) - return [] - } -} + // function onNamespaceChange() { + // const namespace = getValue(model, '/metadata/release/namespace') + // const agent = getValue(model, '/resources/kubedbComPgBouncer/spec/monitor/agent') + // if (agent === 'prometheus.io') { + // commit('wizard/model$update', { + // path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + // value: [namespace], + // force: true, + // }) + // } + // } -///////////////////////// Autoscaler /////////////////// -let autoscaleType = '' -let dbDetails = {} + function onLabelChange() { + const labels = getValue(model, '/resources/kubedbComPgBouncer/spec/metadata/labels') -function isConsole({ storeGet, commit }) { - const isKube = isKubedb({ storeGet }) + const agent = getValue(model, '/resources/kubedbComPgBouncer/spec/monitor/agent') - if (isKube) { - const dbName = storeGet('/route/params/name') || '' - commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComPgBouncerAutoscaler/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/autoscalingKubedbComPgBouncerAutoscaler/metadata/name', - value: modifiedName, - force: true, - }) - const namespace = storeGet('/route/query/namespace') || '' - if (namespace) { + if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComPgBouncerAutoscaler/metadata/namespace', - value: namespace, + path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', + value: labels, force: true, }) } } - return !isKube -} - -function isKubedb({ storeGet }) { - return !!storeGet('/route/params/actions') -} - -function showOpsRequestOptions({ model, getValue, watchDependency, storeGet, discriminator }) { - if (isKubedb({ storeGet }) === true) return true - watchDependency('model#/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/databaseRef/name') - watchDependency('discriminator#/autoscalingType') - return ( - !!getValue(model, '/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/databaseRef/name') && - !!getValue(discriminator, '/autoscalingType') - ) -} + function onAgentChange() { + const agent = getValue(model, '/resources/kubedbComPgBouncer/spec/monitor/agent') + if (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', + value: [], + force: true, + }) -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + onNamespaceChange() + onLabelChange() + } else { + commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') + } + } -async function getNamespaces({ axios, storeGet }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + const isKube = !!storeGet('/route/params/actions') - const resources = (resp && resp.data && resp.data.items) || [] + if (isKube) return pathConstructedForKubedb + else + return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/pgbounceropsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` + } - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, + function onNamespaceChange() { + const namespace = getValue( + model, + '/resources/autoscalingKubedbComPgBouncerAutoscaler/metadata/namespace', + ) + if (!namespace) { + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/databaseRef/name', + ) } - }) -} - -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - watchDependency('model#/resources/autoscalingKubedbComPgBouncerAutoscaler/metadata/namespace') - const namespace = getValue( - model, - '/resources/autoscalingKubedbComPgBouncerAutoscaler/metadata/namespace', - ) - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises`, - { - 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 setValueFrom() { + if (isConfigMapTypeValueFrom()) { + return 'configMap' + } else if (isSecretTypeValueFrom()) { + return 'secret' + } else { + return 'input' } - }) -} + } -async function getDbDetails({ commit, setDiscriminatorValue, axios, storeGet, getValue, model }) { - const owner = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - const namespace = - storeGet('/route/query/namespace') || - getValue(model, '/resources/autoscalingKubedbComPgBouncerAutoscaler/metadata/namespace') || - '' - const name = - storeGet('/route/params/name') || - getValue(model, '/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/databaseRef/name') || - '' - - if (namespace && name) { - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/pgbouncers/${name}`, - ) - dbDetails = resp.data || {} - setDiscriminatorValue('/dbDetails', true) - } catch (e) { - console.log(e) + 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, + }) } } - commit('wizard/model$update', { - path: `/metadata/release/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/metadata/release/namespace`, - value: namespace, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/databaseRef/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComPgBouncerAutoscaler/metadata/labels`, - value: dbDetails.metadata.labels, - force: true, - }) -} + // function isEqualToValueFromType(value) { + // //watchDependency('discriminator#/valueFromType') + // const valueFrom = getValue(discriminator, '/valueFromType') + // return valueFrom === value + // } -async function dbTypeEqualsTo({ watchDependency, commit }, type) { - watchDependency('discriminator#/dbDetails') + async function resourceNames(group, version, resource) { + const namespace = getValue(model, '/metadata/release/namespace') + // watchDependency('model#/metadata/release/namespace') - const { spec } = dbDetails || {} - const { topology } = spec || {} - let verd = '' - if (topology) verd = 'topology' - else { - verd = 'combined' - } - clearSpecModel({ commit }, verd) - return type === verd && spec -} + let resources = await getNamespacedResourceList(axios, storeGet, { + namespace, + group, + version, + resource, + }) -function clearSpecModel({ commit }, dbtype) { - if (dbtype === 'standalone') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/${autoscaleType}/cluster`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/${autoscaleType}/sentinel`, - ) - } else if (dbtype === 'cluster') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/${autoscaleType}/sentinel`, - ) - } else if (dbtype === 'sentinel') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/${autoscaleType}/cluster`, - ) - } -} + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } -function initMetadata({ getValue, discriminator, model, commit, storeGet }) { - const dbName = - getValue(model, '/resources/autoscalingKubedbComPgBouncerAutoscaler/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/autoscalingKubedbComPgBouncerAutoscaler/metadata/name', - value: modifiedName, - force: true, + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } }) + } - // delete the other type object from model - if (type === 'compute') - commit('wizard/model$delete', '/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/storage') - if (type === 'storage') - commit('wizard/model$delete', '/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/compute') -} + async function getNamespacedResourceList( + axios, + storeGet, + { namespace, group, version, resource }, + ) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function onNamespaceChange({ model, getValue, commit }) { - const namespace = getValue( - model, - '/resources/autoscalingKubedbComPgBouncerAutoscaler/metadata/namespace', - ) - if (!namespace) { - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/databaseRef/name', - ) - } -} + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` -function ifScalingTypeEqualsTo( - { storeGet, watchDependency, getValue, discriminator, model }, - type, -) { - watchDependency('discriminator#/autoscalingType') - watchDependency('model#/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/databaseRef/name') - - const operation = storeGet('/route/params/actions') || '' - if (operation.length) { - const splitOp = operation.split('-') - if (splitOp.length > 2) autoscaleType = splitOp[2] - } else autoscaleType = getValue(discriminator, '/autoscalingType') || '' - const isDatabaseSelected = !!getValue( - model, - '/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/databaseRef/name', - ) - return autoscaleType === type && isDatabaseSelected -} + let ans = [] + try { + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) -async function fetchNodeTopology({ axios, storeGet }) { - 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) + const items = (resp && resp.data && resp.data.items) || [] + ans = items + } catch (e) { + console.log(e) + } + + return ans } - return [] -} -function isNodeTopologySelected({ watchDependency, model, getValue }) { - watchDependency( - 'model#/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/compute/nodeTopology/name', - ) - const nodeTopologyName = - getValue( + 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/autoscalingKubedbComPgBouncerAutoscaler/spec/compute/nodeTopology/name', - ) || '' - return !!nodeTopologyName.length -} + `/resources/kubedbComPgBouncer/spec/monitor/prometheus/exporter/env/${index}/valueFrom/configMapKeyRef/name`, + ) -function setControlledResources({ commit }, type) { - const list = ['cpu', 'memory'] - const path = `/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/compute/${type}/controlledResources` - commit('wizard/model$update', { - path: path, - value: list, - force: true, - }) - return list -} + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/configMapKeyRef/name') -function setTrigger({ model, getValue }, path) { - let value = getValue(model, `/resources/${path}`) - if (value) return value - return 'On' -} + if (!configMapName) return [] -function setApplyToIfReady() { - return 'IfReady' -} + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/configmaps/${configMapName}`, + ) -function handleUnit({ commit, model, getValue }, 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, - }) + 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 fetchTopologyMachines({ axios, getValue, storeGet, model, setDiscriminatorValue }) { - const instance = hasAnnotations({ model, getValue }) + 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') - 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 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) + }) - const nodeGroups = resp.data?.spec?.nodeGroups || [] - setDiscriminatorValue('/topologyMachines', nodeGroups) - return nodeGroups + 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 [] } } -} - -function setAllowedMachine({ model, getValue }, minmax) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComPgBouncerAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - const mx = instance?.includes(',') ? instance.split(',')[1] : '' - const mn = instance?.includes(',') ? instance.split(',')[0] : '' - if (minmax === 'min') return mn - else return mx -} - -async function getMachines({ getValue, watchDependency, discriminator }, minmax) { - watchDependency('discriminator#/topologyMachines') - const depends = minmax === 'min' ? 'max' : 'min' - const dependantPath = `/allowedMachine-${depends}` - - watchDependency(`discriminator#${dependantPath}`) - const dependantMachine = getValue(discriminator, dependantPath) + 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/kubedbComPgBouncer/spec/monitor/prometheus/exporter/env/${index}/valueFrom/secretKeyRef/name`, + ) - const nodeGroups = getValue(discriminator, '/topologyMachines') || [] + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/secretKeyRef/name') - const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) + if (!secretName) return [] - const machines = nodeGroups?.map((item) => { - const subText = `CPU: ${item.allocatable.cpu}, Memory: ${item.allocatable.memory}` - const text = item.topologyValue - return { text, subText, value: item.topologyValue } - }) + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets/${secretName}`, + ) - const filteredMachine = machines?.filter((item, ind) => - minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, - ) + const secret = (resp && resp.data && resp.data.data) || {} - return dependantIndex === -1 ? machines : filteredMachine -} + const secretKeys = Object.keys(secret).map((item) => ({ + text: item, + value: item, + })) -function hasAnnotations({ model, getValue }) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComPgBouncerAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] + return secretKeys + } catch (e) { + console.log(e) + return [] + } + } - return !!instance -} + function returnFalse() { + return false + } + + 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 + }) -function hasNoAnnotations({ model, getValue }) { - return !hasAnnotations({ model, getValue }) -} + if (filteredEnv.length) + commit('wizard/model$update', { + path: '/resources/kubedbComPgBouncer/spec/monitor/prometheus/exporter/env', + value: filteredEnv, + force: true, + }) + } -function onMachineChange({ model, getValue, discriminator, commit }, type) { - const annoPath = '/resources/autoscalingKubedbComPgBouncerAutoscaler/metadata/annotations' - const annotations = getValue(model, annoPath) - const instance = annotations['kubernetes.io/instance-type'] + function initEnvArray() { + const env = getValue( + model, + '/resources/kubedbComPgBouncer/spec/monitor/prometheus/exporter/env', + ) - const minMachine = getValue(discriminator, '/allowedMachine-min') - const maxMachine = getValue(discriminator, '/allowedMachine-max') - const minMaxMachine = `${minMachine},${maxMachine}` - annotations['kubernetes.io/instance-type'] = minMaxMachine + return env || [] + } - const machines = getValue(discriminator, `/topologyMachines`) || [] - const minMachineObj = machines.find((item) => item.topologyValue === minMachine) - const maxMachineObj = machines.find((item) => item.topologyValue === maxMachine) - const minMachineAllocatable = minMachineObj?.allocatable - const maxMachineAllocatable = maxMachineObj?.allocatable - const allowedPath = `/resources/autoscalingKubedbComPgBouncerAutoscaler/spec/compute/${type}` + function isEqualToTemp(value, index) { + //watchDependency('discriminator#/valueFromType') + const valueFrom = getValue(discriminator, `/env/${index}/temp/valueFromType`) + return valueFrom === value + } - 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 initMonitoring() { + const env = + getValue(model, '/resources/kubedbComPgBouncer/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 { - isRancherManaged, - handleUnit, - isConsole, - getNamespaces, - getDbs, - isKubedb, - getDbDetails, - dbTypeEqualsTo, - clearSpecModel, - initMetadata, - onNamespaceChange, - ifScalingTypeEqualsTo, - fetchNodeTopology, - isNodeTopologySelected, - setControlledResources, - setTrigger, - setApplyToIfReady, - showOpsRequestOptions, - isVariantAvailable, - fetchJsons, - getAppbinding, - onDatabaseModeChange, - setDatabaseMode, - disableLableChecker, - isEqualToModelPathValue, - getResources, - isEqualToDiscriminatorPath, - setValueFromModel, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - returnTrue, - returnStringYes, - setAddressType, - getPgBouncerVersions, - isEqualToDatabaseMode, - setApiGroup, - getIssuerRefsName, - hasIssuerRefName, - hasNoIssuerRefName, - setSSLMode, - showTlsConfigureSection, - onTlsConfigureChange, - getAliasOptions, - showMonitoringSection, - onEnableMonitoringChange, - showCustomizeExporterSection, - onCustomizeExporterChange, - valueExists, - onConfigurationChangeEdit, - setConfigurationForEdit, - initPrePopulateDatabase, - onPrePopulateDatabaseChange, - initDataSource, - onDataSourceChange, - initVolumeType, - onVolumeTypeChange, - showInitializationForm, - showScriptOrStashForm, - showConfigMapOrSecretName, - initializeNamespace, - showRepositorySelectOrCreate, - onInitRepositoryChoiseChange, - initCustomizeRestoreJobRuntimeSettings, - initCustomizeRestoreJobRuntimeSettingsForBackup, - onCustomizeRestoreJobRuntimeSettingsChange, - onCustomizeRestoreJobRuntimeSettingsChangeForBackup, - showRuntimeForm, - getImagePullSecrets, - getBackupConfigsAndAnnotations, - deleteKubeDbComPgBouncerDbAnnotation, - addKubeDbComPgBouncerDbAnnotation, - initScheduleBackup, - initScheduleBackupForEdit, - onScheduleBackupChange, - showBackupForm, - initBackupInvoker, - onBackupInvokerChange, - showInvokerForm, - initalizeTargetReferenceName, - setInitialRestoreSessionRepo, - initRepositoryChoise, - initRepositoryChoiseForEdit, - setConfigurationForEdit, - onRepositoryChoiseChange, - onRepositoryNameChange, - getMongoAnnotations, - initFromAnnotationValue, - onBackupBlueprintNameChange, - onBackupBlueprintScheduleChange, - initFromAnnotationKeyValue, - onTaskParametersChange, - isValueExistInModel, - onNamespaceChange, - onLabelChange, - onNameChange, - returnFalse, - onAgentChange, - getCreateAuthSecret, - showExistingSecretSection, - showPasswordSection, - setAuthSecretPassword, - onAuthSecretPasswordChange, - disableInitializationSection, - encodePassword, - decodePassword, - onCreateAuthSecretChange, - getSecrets, - onConfigurationSourceChange, - onConfigurationChange, - setConfigurationSource, - setSecretConfigNamespace, - setConfiguration, - setConfigurationFiles, - onSetCustomConfigChange, - getOpsRequestUrl, - onRefChange, - getAppBindings, - getMachines, - setAllowedMachine, - hasAnnotations, - hasNoAnnotations, - fetchTopologyMachines, - onMachineChange, + return { + isConsole, + isKubedb, + getDbDetails, + getNamespaces, + isRancherManaged, + onNamespaceChange, + getDbs, + initMetadata, + fetchTopologyMachines, + setTrigger, + setApplyToIfReady, + hasAnnotations, + hasNoAnnotations, + setAllowedMachine, + getMachines, + onMachineChange, + setControlledResources, + fetchNodeTopology, + isNodeTopologySelected, + showOpsRequestOptions, + + getOpsRequestUrl, + isValueExistInModel, + onEnableMonitoringChange, + showMonitoringSection, + onAgentChange, + getResources, + isEqualToModelPathValue, + onCustomizeExporterChange, + showCustomizeExporterSection, + onLabelChange, + setValueFrom, + onValueFromChange, + resourceNames, + getConfigMapKeys, + getSecrets, + getSecretKeys, + isConfigMapTypeValueFrom, + isSecretTypeValueFrom, + getNamespacedResourceList, + returnFalse, + onEnvArrayChange, + initEnvArray, + isEqualToTemp, + initMonitoring, + } } diff --git a/charts/kubedbcom-pgpool-editor-options/ui/create-ui.yaml b/charts/kubedbcom-pgpool-editor-options/ui/create-ui.yaml index 52fdd164cf..3c0987b7ea 100644 --- a/charts/kubedbcom-pgpool-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-pgpool-editor-options/ui/create-ui.yaml @@ -1,311 +1,311 @@ -steps: -- form: - discriminator: - bundleApiLoaded: - default: false - type: boolean - postgresRef: - default: {} - type: object +step: +- type: single-step-form + loader: initBundle + elements: + - type: label-element + label: '' + subtitle: Select the Pgpool version you want to deploy on Kubernetes.The chosen version determines the Pgpool engine features, compatibility, and runtime behavior of your connection pooler. + - disableUnselect: true + loader: getAdminOptions|databases/Pgpool/versions + if: + type: function + name: isToggleOn|databases/Pgpool/versions + label: Database Version + schema: schema/properties/spec/properties/admin/properties/databases/properties/Pgpool/properties/versions/properties/default + type: select + - init: + type: func + value: getDefault|databases/Pgpool/mode + loader: getAdminOptions|databases/Pgpool/mode + isHorizontal: true + if: + type: function + name: isToggleOn|databases/Pgpool/mode + label: Database Mode + watcher: + func: onModeChange + paths: + - schema/properties/spec/properties/mode + schema: schema/properties/spec/properties/mode + type: radio + - if: + type: function + name: isEqualToModelPathValue|Replicaset|/spec/mode + label: Replica Number + schema: schema/properties/spec/properties/replicas + type: input + - elements: + - type: label-element + label: '' + subtitle: Select a machine profile to allocate CPU and memory resources for your connection pooler. Choose 'custom' to manually specify resource requirements or select a predefined profile. + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + customClass: mt-10 + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: CPU + loader: setLimits|cpu + watcher: + func: setRequests|cpu + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: Memory + loader: setLimits|memory + watcher: + func: setRequests|memory + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + label: Machine Profile + showLabels: true + type: block-layout + - elements: + - type: horizontal-layout + showLabels: true + elements: + - loader: getAdminOptions|storageClasses + if: + type: function + name: isToggleOn|storageClasses + label: Storage Class + schema: schema/properties/spec/properties/admin/properties/storageClasses/properties/default + type: select + - loader: getAppBindings|postgres + label: Select Database Reference + watcher: + func: onRefChange|postgresRef + paths: + - temp/properties/postgresRef + refresh: true + validation: + type: required + schema: temp/properties/postgresRef + type: select + type: block-layout + - description: Configure Credentials, Deployment Mode etc. elements: - - computed: initBundle - if: returnFalse - type: label-element - - disableUnselect: true - fetch: getAdminOptions|databases/Pgpool/versions - if: isToggleOn|databases/Pgpool/versions - label: - text: labels.database.version - schema: - $ref: schema#/properties/spec/properties/admin/properties/databases/properties/Pgpool/properties/versions/properties/default + - elements: + - type: label-element + label: '' + subtitle: Add custom labels and annotations to your database resources for organization, monitoring, and integration with other Kubernetes tools and services. + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/annotations + label: Labels & Annotations + showLabels: true + hideBlock: true + type: block-layout + - init: + type: func + value: getDefault|deletionPolicy + customClass: mt-20 + if: + type: function + name: isToggleOn|deletionPolicy + label: Deletion Policy + watcher: + func: setStorageClass + paths: + - schema/properties/spec/properties/deletionPolicy + options: + - description: options.deletionPolicy.delete.description + text: Delete + value: Delete + - description: options.deletionPolicy.halt.description + text: Halt + value: Halt + - description: options.deletionPolicy.wipeOut.description + text: WipeOut + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: DoNotTerminate + value: DoNotTerminate + schema: schema/properties/spec/properties/deletionPolicy type: select - - computed: getDefault|databases/Pgpool/mode - fetch: getAdminOptions|databases/Pgpool/mode - hasDescription: true - if: isToggleOn|databases/Pgpool/mode - label: - text: labels.database.mode - onChange: onModeChange - schema: - $ref: schema#/properties/spec/properties/mode - type: radio - - if: isEqualToModelPathValue|Replicaset|/spec/mode - label: - text: labels.replicas - schema: - $ref: schema#/properties/spec/properties/replicas + - if: + type: function + name: getDefaultValue|spec/admin/authCredential/customize + label: Provide Authentication Credentials? + watcher: + func: onAuthChange + paths: + - temp/createAuthSecret + schema: temp/createAuthSecret + type: switch + - if: + type: function + name: showReferSecretSwitch + label: Refer existing Secret? + watcher: + func: onReferSecretChange + paths: + - temp/referSecret + schema: temp/referSecret + type: switch + - loader: getReferSecrets + if: + type: function + name: showSecretDropdown + label: Secret + schema: schema/properties/spec/properties/authSecret/properties/name + type: select + - if: + type: function + name: showReferSecret + label: Password + schema: schema/properties/spec/properties/authSecret/properties/password type: input - - elements: - - computed: setMachineToCustom - customClass: mt-10 - fetch: getMachineListForOptions - label: - text: labels.machine - schema: - $ref: schema#/properties/spec/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.cpu - onChange: setRequests|cpu - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.memory - onChange: setRequests|memory - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - label: - text: labels.machine_profile - show_label: true - type: single-step-form - - fetch: getAdminOptions|storageClasses - if: isToggleOn|storageClasses - label: - text: labels.storage.class - schema: - $ref: schema#/properties/spec/properties/admin/properties/storageClasses/properties/default + - if: + type: function + name: getDefaultValue|spec/admin/customConfiguration + label: Configure Database? + watcher: + func: clearConfiguration + paths: + - temp/configDatabase + schema: temp/configDatabase + type: switch + - if: + type: function + name: isConfigDatabaseOn + label: Configuration + schema: schema/properties/spec/properties/configuration + type: textarea + - label: Sync Users + schema: schema/properties/spec/properties/syncUsers + type: switch + - isHorizontal: true + if: + type: function + name: isToggleOn|deployment + label: Deployment Mode + options: + - description: Shared + text: Shared + value: Shared + - description: Dedicated + text: Dedicated + value: Dedicated + schema: schema/properties/spec/properties/admin/properties/deployment/properties/default + type: radio + - if: + type: function + name: isToggleOn|clusterTier + isHorizontal: true + label: Cluster Tier + options: + - text: General Purpose + value: GeneralPurpose + - text: Memory Optimized + value: MemoryOptimized + - text: CPU Optimized + value: CPUOptimized + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/default + type: radio + - disableUnselect: true + loader: getAdminOptions|clusterTier/placement + if: + type: function + name: isToggleOn|clusterTier/placement + label: Placement Policy + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default type: select - - fetch: getAppBindings|postgres - label: - text: labels.postgresRef.label - onChange: onRefChange|postgresRef - refresh: true - required: true - schema: - $ref: discriminator#/postgresRef + - disableUnselect: true + loader: getNodeTopology + if: + type: function + name: isToggleOn|clusterTier/nodeTopology + label: Node Topology + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default type: select - - accordion: true - description: - text: Configure Credentials, Deployment Mode etc. - discriminator: - configDatabase: - default: false - type: boolean - createAuthSecret: - default: false - type: boolean - referSecret: - default: false - type: boolean - elements: - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties - type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties - type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - computed: getDefault|deletionPolicy - customClass: mt-20 - if: isToggleOn|deletionPolicy - 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/spec/properties/deletionPolicy - type: select - - if: getDefaultValue|spec/admin/authCredential/customize - label: - text: Provide Authentication Credentials? - onChange: onAuthChange - schema: - $ref: discriminator#/createAuthSecret - type: switch - - if: showReferSecretSwitch - label: - text: Refer existing Secret? - onChange: onReferSecretChange - schema: - $ref: discriminator#/referSecret - type: switch - - fetch: getReferSecrets - if: showSecretDropdown - label: - text: Secret - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/name - type: select - - if: showReferSecret - label: - text: labels.password - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/password - type: input - - computed: isConfigAvailable - if: getDefaultValue|spec/admin/customConfiguration - label: - text: Configure Database? - onChange: clearConfiguration - schema: - $ref: discriminator#/configDatabase - type: switch - - if: isConfigDatabaseOn - label: - text: Configuration - schema: - $ref: schema#/properties/spec/properties/configuration - type: editor - - label: - text: Sync Users? - schema: - $ref: schema#/properties/spec/properties/syncUsers + label: Advanced Configuration + showLabels: true + type: block-layout + - description: Enable Backup, Monitoring, TLS etc. + elements: + - elements: + - init: + type: func + value: setMonitoring + label: Enable Monitoring + watcher: + func: updateAlertValue + paths: + - temp/monitoring + schema: temp/monitoring type: switch - - hasDescription: true - if: isToggleOn|deployment - label: - text: labels.deployment.name - options: - - description: labels.deployment.shared - text: Shared - value: Shared - - description: labels.deployment.dedicated - text: Dedicated - value: Dedicated - schema: - $ref: schema#/properties/spec/properties/admin/properties/deployment/properties/default - type: radio - - if: isToggleOn|clusterTier - isHorizontal: true - label: - text: labels.clusterTier + - customClass: mt-10 + if: + type: function + name: showAlerts + label: Alert Options options: - - text: General Purpose - value: GeneralPurpose - - text: Memory Optimized - value: MemoryOptimized - - text: CPU Optimized - value: CPUOptimized - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/default - type: radio - - disableUnselect: true - fetch: getAdminOptions|clusterTier/placement - if: isToggleOn|clusterTier/placement - label: - text: labels.placement - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + - text: None + value: none + - text: Critical + value: critical + - text: Warning + value: warning + - text: Info + value: info + schema: schema/properties/form/properties/alert/properties/enabled type: select - - disableUnselect: true - fetch: getNodeTopology - if: isToggleOn|clusterTier/nodeTopology - label: - text: labels.nodeTopology - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + if: + type: function + name: isToggleOn|monitoring + type: block-layout + - elements: + - if: + type: function + name: isToggleOn|tls + label: Enable TLS? + schema: schema/properties/spec/properties/admin/properties/tls/properties/default + type: switch + - loader: getAdminOptions|clusterIssuers + if: + type: function + name: showIssuer + label: Cluster Issuers + validation: + type: required + schema: schema/properties/spec/properties/admin/properties/clusterIssuers/properties/default type: select - hideForm: true - label: - text: Advanced Configuration - show_label: true - type: single-step-form - - accordion: true - description: - text: Enable Backup, Monitoring, TLS etc. - elements: - - discriminator: - monitoring: - default: false - type: boolean - elements: - - computed: setMonitoring - label: - text: labels.enable_monitoring - onChange: updateAlertValue - schema: - $ref: discriminator#/monitoring - type: switch - - customClass: mt-10 - if: showAlerts - label: - text: labels.alert.options - options: - - text: None - value: none - - text: Critical - value: critical - - text: Warning - value: warning - - text: Info - value: info - schema: - $ref: schema#/properties/form/properties/alert/properties/enabled - sortable: true - type: select - if: isToggleOn|monitoring - type: single-step-form - - elements: - - label: - text: Enable TLS? - schema: - $ref: schema#/properties/spec/properties/admin/properties/tls/properties/default - type: switch - - fetch: getAdminOptions|clusterIssuers - if: showIssuer - label: - text: labels.clusterIssuers - required: true - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterIssuers/properties/default - type: select - if: isToggleOn|tls - type: single-step-form - if: showAdditionalSettings - label: - text: Additional Options - show_label: true - type: single-step-form - type: single-step-form + type: block-layout + if: + type: function + name: showAdditionalSettings + label: Additional Options + showLabels: true + type: block-layout id: options - title: steps.0.label type: multi-step-form diff --git a/charts/kubedbcom-pgpool-editor-options/ui/functions.js b/charts/kubedbcom-pgpool-editor-options/ui/functions.js index f84f6bf97d..7e5f690534 100644 --- a/charts/kubedbcom-pgpool-editor-options/ui/functions.js +++ b/charts/kubedbcom-pgpool-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -314,966 +316,1020 @@ const modeDetails = { }, } -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) -function getMachineListForOptions({ model, getValue }) { - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') + setDiscriminatorValue('bundleApiLoaded', false) + setDiscriminatorValue('postgresRef', {}) + setDiscriminatorValue('configDatabase', false) + setDiscriminatorValue('createAuthSecret', false) + setDiscriminatorValue('referSecret', false) + setDiscriminatorValue('monitoring', false) + + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } let array = [] + function getMachineListForOptions() { + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') - if (available.length) { - array = available.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - else { - let subText = '', - text = '' - const machineData = machinesFromPreset.find((val) => val.id === machine) - if (machineData) { - subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` - text = machineData.name ? machineData.name : machineData.id - } - return { text, subText, value: machine } - } - }) - } else { - array = machineList - .map((machine) => { + if (available.length) { + array = available.map((machine) => { if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + else { + let subText = '', + text = '' + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + text = machineData.name ? machineData.name : machineData.id + } + return { text, subText, value: machine } + } }) - .filter((val) => !!val) + } else { + array = machineList + .map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { text, subText, value: machine } + }) + .filter((val) => !!val) + } + return array } - return array -} -function setLimits({ model, getValue, commit, watchDependency }, resource, type) { - const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' - watchDependency(`model#${path}`) - const selectedMachine = getValue(model, path) || 'custom' - const reqCommitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - const comparePath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - - const resourceValue = getValue(model, comparePath) - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - - let cpu = '', - memory = '' - if (available.length && selectedMachine !== 'custom') { - const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) - if (machineData) { - cpu = machineData.limits.cpu - memory = machineData.limits.memory + function setLimits(resource, type) { + const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' + // watchDependency(`model#${path}`) + const selectedMachine = getValue(model, path) || 'custom' + const reqCommitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + const comparePath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + + const resourceValue = getValue(model, comparePath) + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + let cpu = '', + memory = '' + if (available.length && selectedMachine !== 'custom') { + const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) + if (machineData) { + cpu = machineData.limits.cpu + memory = machineData.limits.memory + } + } else { + if (selectedMachine === 'custom') { + cpu = resourceValue + memory = resourceValue + } else { + cpu = machines[selectedMachine].resources.limits.cpu + memory = machines[selectedMachine].resources.limits.memory + } } - } else { - if (selectedMachine === 'custom') { - cpu = resourceValue - memory = resourceValue + + if (resource === 'memory') { + commit('wizard/model$update', { + path: reqCommitPath, + value: memory, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: memory, + force: true, + }) + return memory } else { - cpu = machines[selectedMachine].resources.limits.cpu - memory = machines[selectedMachine].resources.limits.memory + commit('wizard/model$update', { + path: reqCommitPath, + value: cpu, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: cpu, + force: true, + }) + return cpu } } - if (resource === 'memory') { + function setRequests(resource, type) { + const modelPath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + + const fullpath = `/spec/podResources/machine` + const modelPathValue = getValue(model, fullpath) + commit('wizard/model$update', { - path: reqCommitPath, - value: memory, + path: commitPath, + value: val, force: true, }) + + if (modelPathValue === 'custom') { + return + } + let commitCpuMemory, ModelPathValue + if (resource && type) { + const fullPath = `/spec/${type}/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/${type}/podResources/resources/requests/${resource}` + } else { + const fullPath = `/spec/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/podResources/resources/requests/${resource}` + } + let cpuMemoryValue + array.forEach((item) => { + if (item.value === ModelPathValue) { + // Parse subText like "CPU: 2, Memory: 2Gi" + const subText = item.subText || '' + if (resource === 'cpu') { + // Extract CPU value + const cpuMatch = subText.match(/CPU:\s*([^,]+)/) + cpuMemoryValue = cpuMatch ? cpuMatch[1].trim() : '' + } else if (resource === 'memory') { + // Extract Memory value + const memoryMatch = subText.match(/Memory:\s*(.+)/) + cpuMemoryValue = memoryMatch ? memoryMatch[1].trim() : '' + } + } + }) commit('wizard/model$update', { - path: comparePath, - value: memory, + path: commitCpuMemory, + value: cpuMemoryValue, force: true, }) - return memory - } else { + return cpuMemoryValue + } + + function setRequests(resource) { + const modelPath = `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + commitPath = `/spec/podResources/resources/limits/${resource}` commit('wizard/model$update', { - path: reqCommitPath, - value: cpu, + path: commitPath, + value: val, force: true, }) + } + + function setMachineToCustom() { + const machine = getValue(model, '/spec/admin/machineProfiles/default') + return machine || 'custom' + } + + async function fetchJsons() { + 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 updateAgentValue(val) { commit('wizard/model$update', { - path: comparePath, - value: cpu, + path: '/spec/monitoring/agent', + value: val ? 'prometheus.io/operator' : '', force: true, }) - return cpu - } -} -function setRequests({ getValue, model, commit }, resource) { - const modelPath = `/spec/podResources/resources/requests/${resource}` - const val = getValue(model, modelPath) - commitPath = `/spec/podResources/resources/limits/${resource}` - commit('wizard/model$update', { - path: commitPath, - value: val, - force: true, - }) -} + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: val ? 'warning' : 'none', + force: true, + }) + } -function setMachineToCustom({ getValue, model }) { - const machine = getValue(model, '/spec/admin/machineProfiles/default') - return machine || 'custom' -} + function getCreateNameSpaceUrl() { + const user = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -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) + const domain = storeGet('/domain') || '' + if (domain.includes('bb.test')) { + return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } } - return { - ui: ui.data || {}, - language: language.data || {}, - functions, + function ifCapiProviderIsNotEmpty() { + // watchDependency('model#/form/capi/provider') + const val = getValue(model, '/form/capi/provider') + if (val) return true } -} -function updateAgentValue({ commit }, val) { - commit('wizard/model$update', { - path: '/spec/monitoring/agent', - value: val ? 'prometheus.io/operator' : '', - force: true, - }) - - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: val ? 'warning' : 'none', - force: true, - }) -} + function showMultiselectZone() { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + if (val === 'capz' && ifDedicated()) return true + } - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + function showSelectZone() { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') + if (val !== 'capz' && ifDedicated()) return true } -} -const ifCapiProviderIsNotEmpty = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/provider') - const val = getValue(model, '/form/capi/provider') - if (val) return true -} + function ifDedicated() { + const val = getValue(model, 'form/capi/dedicated') + if (val) return true + } -const showMultiselectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') + function dedicatedOnChange() { + const val = getValue(model, 'form/capi/dedicated') + if (!val) { + commit('wizard/model$delete', 'form/capi/zones') + commit('wizard/model$delete', 'form/capi/sku') + } + } - if (val === 'capz' && ifDedicated({ model, getValue })) return true -} + function ifZones() { + // watchDependency('model#/form/capi/zones') + // watchDependency('model#/form/capi/dedicated') + const zones = getValue(model, 'form/capi/zones') || [] + const isDedicated = getValue(model, 'form/capi/dedicated') + if (zones.length && isDedicated) return true + } -const showSelectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') - if (val !== 'capz' && ifDedicated({ model, getValue })) return true -} + function zonesOnChange() { + const zones = getValue(model, 'form/capi/zones') || [] + if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') + } -const ifDedicated = ({ model, getValue }) => { - const val = getValue(model, 'form/capi/dedicated') - if (val) return true -} + async function getZones() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const isDedicated = getValue(model, 'form/capi/dedicated') + if (isDedicated) { + try { + const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) + const val = resp.data.map((item) => { + return { value: item, text: item } + }) + return val + } catch (e) { + console.log(e) + return [] + } + } + } -const dedicatedOnChange = ({ model, getValue, commit }) => { - const val = getValue(model, 'form/capi/dedicated') - if (!val) { - commit('wizard/model$delete', 'form/capi/zones') - commit('wizard/model$delete', 'form/capi/sku') + async function getSKU() { + // watchDependency('model#/form/capi/zones') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const zones = getValue(model, 'form/capi/zones') || [] + if (zones.length) { + try { + let url = `clustersv2/${owner}/${cluster}/vms?` + if (typeof zones === 'string') { + url += `zones=${encodeURIComponent(zones)}` + } else { + zones.forEach((item) => { + url += `zones=${encodeURIComponent(item)}&` + }) + url = url.slice(0, -1) + } + const resp = await axios.get(url) + const val = resp.data.map((item) => { + return { + value: item.name, + text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, + } + }) + return val + } catch (e) { + console.log(e) + return [] + } + } } -} -const ifZones = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/zones') - watchDependency('model#/form/capi/dedicated') - const zones = getValue(model, 'form/capi/zones') || [] - const isDedicated = getValue(model, 'form/capi/dedicated') - if (zones.length && isDedicated) return true -} + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false + } -const zonesOnChange = ({ model, getValue, commit }) => { - const zones = getValue(model, 'form/capi/zones') || [] - if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') -} + function setStorageClass() { + const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' + let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' + const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] + const suffix = '-retain' -async function getZones({ storeGet, axios, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const isDedicated = getValue(model, 'form/capi/dedicated') - if (isDedicated) { - try { - const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) - const val = resp.data.map((item) => { - return { value: item, text: item } + const simpleClassList = storageClassList.filter((item) => { + return !item.endsWith(suffix) + }) + const retainClassList = storageClassList.filter((item) => { + return item.endsWith(suffix) + }) + if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { + storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] + } else { + storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + } + + const isChangeable = isToggleOn('storageClasses') + if (isChangeable && storageClass) { + commit('wizard/model$update', { + path: '/spec/admin/storageClasses/default', + value: storageClass, + force: true, }) - return val - } catch (e) { - console.log(e) - return [] } } -} -async function getSKU({ storeGet, axios, model, getValue, watchDependency }) { - watchDependency('model#/form/capi/zones') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const zones = getValue(model, 'form/capi/zones') || [] - if (zones.length) { + let placement = [] + let versions = [] + let storageClass = [] + let clusterIssuers = [] + let nodetopologiesShared = [] + let nodetopologiesDedicated = [] + let features = [] + async function initBundle() { + const owner = storeGet('/route/params/user') + const namespace = getValue(model, '/metadata/release/namespace') + const cluster = storeGet('/route/params/cluster') + + let db = getValue(model, '/metadata/resource/kind') + db = db.toLowerCase() + let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` + const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` + try { - let url = `clustersv2/${owner}/${cluster}/vms?` - if (typeof zones === 'string') { - url += `zones=${encodeURIComponent(zones)}` - } else { - zones.forEach((item) => { - url += `zones=${encodeURIComponent(item)}&` + const resp = await axios.get(url) + features = resp.data.features || [] + placement = resp.data.placementpolicies || [] + versions = resp.data.versions || [] + storageClass = resp.data.storageclasses || [] + clusterIssuers = resp.data.clusterissuers || [] + nodetopologiesDedicated = resp.data.dedicated || [] + nodetopologiesShared = resp.data.shared || [] + + const response = await axios.get(annotationUrl) + const annotations = response.data?.metadata?.annotations || {} + const uidRange = annotations['openshift.io/sa.scc.uid-range'] + if (uidRange) { + const val = uidRange.split('/')[0] + commit('wizard/model$update', { + path: '/spec/openshift/securityContext/runAsUser', + value: val, + force: true, }) - url = url.slice(0, -1) } - const resp = await axios.get(url) - const val = resp.data.map((item) => { - return { - value: item.name, - text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, - } - }) - return val } catch (e) { console.log(e) - return [] } - } -} -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} - -function setStorageClass({ model, getValue, commit, discriminator, watchDependency }) { - const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' - let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' - const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] - const suffix = '-retain' - - const simpleClassList = storageClassList.filter((item) => { - return !item.endsWith(suffix) - }) - const retainClassList = storageClassList.filter((item) => { - return item.endsWith(suffix) - }) - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] - } else { - storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] - } - - const isChangeable = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'storageClasses', - ) - if (isChangeable && storageClass) { commit('wizard/model$update', { - path: '/spec/admin/storageClasses/default', - value: storageClass, + path: '/spec/deletionPolicy', + value: getDefault('deletionPolicy'), force: true, }) - } -} -let placement = [] -let versions = [] -let storageClass = [] -let clusterIssuers = [] -let nodetopologiesShared = [] -let nodetopologiesDedicated = [] -let features = [] -async function initBundle({ commit, model, getValue, axios, storeGet, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const namespace = getValue(model, '/metadata/release/namespace') - const cluster = storeGet('/route/params/cluster') - - let db = getValue(model, '/metadata/resource/kind') - db = db.toLowerCase() - let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` - const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - - try { - const resp = await axios.get(url) - features = resp.data.features || [] - placement = resp.data.placementpolicies || [] - versions = resp.data.versions || [] - storageClass = resp.data.storageclasses || [] - clusterIssuers = resp.data.clusterissuers || [] - nodetopologiesDedicated = resp.data.dedicated || [] - nodetopologiesShared = resp.data.shared || [] - - const response = await axios.get(annotationUrl) - const annotations = response.data?.metadata?.annotations || {} - const uidRange = annotations['openshift.io/sa.scc.uid-range'] - if (uidRange) { - const val = uidRange.split('/')[0] + if (!getValue(model, `/spec/admin/databases/Pgpool/mode/toggle`)) { + let defMode = getDefault('databases/Pgpool/mode') || '' + if (defMode === '') { + const arr = getValue(model, '/spec/databases/Pgpool/mode/available') || [] + if (arr.length) defMode = arr[0] + } commit('wizard/model$update', { - path: '/spec/openshift/securityContext/runAsUser', - value: val, + path: '/spec/mode', + value: defMode, force: true, }) } - } catch (e) { - console.log(e) - } - commit('wizard/model$update', { - path: '/spec/deletionPolicy', - value: getDefault({ getValue, model }, 'deletionPolicy'), - force: true, - }) - - if (!getValue(model, `/spec/admin/databases/Pgpool/mode/toggle`)) { - let defMode = getDefault({ getValue, model }, 'databases/Pgpool/mode') || '' - if (defMode === '') { - const arr = getValue(model, '/spec/databases/Pgpool/mode/available') || [] - if (arr.length) defMode = arr[0] + if (!features.includes('tls')) { + commit('wizard/model$update', { + path: '/spec/admin/tls/default', + value: false, + force: true, + }) + } + if (!features.includes('binding')) { + commit('wizard/model$update', { + path: '/spec/admin/expose/default', + value: false, + force: true, + }) + } + if (!features.includes('monitoring')) { + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: 'none', + force: true, + }) + } + if (!features.includes('backup')) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: '', + force: true, + }) } - commit('wizard/model$update', { - path: '/spec/mode', - value: defMode, - force: true, - }) - } - if (!features.includes('tls')) { - commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: false, - force: true, - }) - } - if (!features.includes('binding')) { - commit('wizard/model$update', { - path: '/spec/admin/expose/default', - value: false, - force: true, - }) - } - if (!features.includes('monitoring')) { - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: 'none', - force: true, - }) - } - if (!features.includes('backup')) { - commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, - force: true, - }) - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: '', - force: true, - }) + setDiscriminatorValue('/bundleApiLoaded', true) } - setDiscriminatorValue('/bundleApiLoaded', true) -} + function fetchOptions(type) { + let kind = getValue(model, '/metadata/resource/kind') + + let returnArray = [] + if (type === 'clusterTier/placement') { + returnArray = placement + } else if (type === `databases/${kind}/versions`) { + returnArray = versions + } else if (type === 'storageClasses') { + returnArray = storageClass + } else if (type === 'clusterIssuers') { + returnArray = clusterIssuers + } -function fetchOptions({ model, getValue, commit }, type) { - let kind = getValue(model, '/metadata/resource/kind') - - let returnArray = [] - if (type === 'clusterTier/placement') { - returnArray = placement - } else if (type === `databases/${kind}/versions`) { - returnArray = versions - } else if (type === 'storageClasses') { - returnArray = storageClass - } else if (type === 'clusterIssuers') { - returnArray = clusterIssuers - } + if (returnArray.length === 1) { + const path = `/spec/admin/${type}/default` + commit('wizard/model$update', { + path: path, + value: returnArray[0], + force: true, + }) + } - if (returnArray.length === 1) { - const path = `/spec/admin/${type}/default` - commit('wizard/model$update', { - path: path, - value: returnArray[0], - force: true, - }) + return returnArray } - return returnArray -} - -function getAdminOptions({ getValue, model, watchDependency, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') + function getAdminOptions(type) { + // watchDependency('discriminator#/bundleApiLoaded') - const options = getValue(model, `/spec/admin/${type}/available`) || [] + const options = getValue(model, `/spec/admin/${type}/available`) || [] - if (options.length === 0) { - return fetchOptions({ model, getValue, commit }, type) - } - if (type.endsWith('/mode')) { - return ( - options?.map((item) => ({ - description: modeDetails[item]?.description || '', - text: modeDetails[item]?.text || '', - value: item, - })) || [] - ) + if (options.length === 0) { + return fetchOptions(type) + } + if (type.endsWith('/mode')) { + return ( + options?.map((item) => ({ + description: modeDetails[item]?.description || '', + text: modeDetails[item]?.text || '', + value: item, + })) || [] + ) + } + return options } - return options -} -function checkIfFeatureOn({ getValue, model }, type) { - let val = getValue(model, `/spec/admin/${type}/toggle`) - if (type === 'backup' || type === 'archiver') { - val = getValue(model, `/spec/admin/${type}/enable/toggle`) - } - const backupVal = getValue(model, '/spec/backup/tool') - - if (type === 'backup') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } else if (type === 'tls') { - return features.includes('tls') && val - } else if (type === 'expose') { - return features.includes('binding') && val - } else if (type === 'monitoring') { - return features.includes('monitoring') && val - } else if (type === 'archiver') { - return features.includes('backup') && backupVal === 'KubeStash' && val + function checkIfFeatureOn(type) { + let val = getValue(model, `/spec/admin/${type}/toggle`) + if (type === 'backup' || type === 'archiver') { + val = getValue(model, `/spec/admin/${type}/enable/toggle`) + } + const backupVal = getValue(model, '/spec/backup/tool') + + if (type === 'backup') { + return features.includes('backup') && backupVal === 'KubeStash' && val + } else if (type === 'tls') { + return features.includes('tls') && val + } else if (type === 'expose') { + return features.includes('binding') && val + } else if (type === 'monitoring') { + return features.includes('monitoring') && val + } else if (type === 'archiver') { + return features.includes('backup') && backupVal === 'KubeStash' && val + } } -} -function isToggleOn({ getValue, model, discriminator, watchDependency }, type) { - watchDependency('discriminator#/bundleApiLoaded') - watchDependency('model#/spec/admin/deployment/default') - const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') - let deploymentType = getValue(model, `/spec/admin/deployment/default`) - if ( - type === 'tls' || - type === 'backup' || - type === 'expose' || - type === 'monitoring' || - type === 'archiver' - ) { - return checkIfFeatureOn({ getValue, model }, type) - } else if ( - type === 'clusterTier' || - type === 'clusterTier/placement' || - type === 'clusterTier/nodeTopology' - ) { - if (deploymentType === 'Dedicated' && bundleApiLoaded) return true - else return false - } else if (type === 'deployment') { - const deploymentType = getValue(model, '/spec/admin/deployment/default') - if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { - commit('wizard/model$update', { - path: '/spec/admin/deployment/default', - value: 'Shared', - force: true, - }) - } - return ( - getValue(model, `/spec/admin/${type}/toggle`) && - nodetopologiesDedicated.length && - bundleApiLoaded - ) - } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded -} + function isToggleOn(type) { + // watchDependency('discriminator#/bundleApiLoaded') + // watchDependency('model#/spec/admin/deployment/default') + const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') + let deploymentType = getValue(model, `/spec/admin/deployment/default`) + if ( + type === 'tls' || + type === 'backup' || + type === 'expose' || + type === 'monitoring' || + type === 'archiver' + ) { + return checkIfFeatureOn(type) + } else if ( + type === 'clusterTier' || + type === 'clusterTier/placement' || + type === 'clusterTier/nodeTopology' + ) { + if (deploymentType === 'Dedicated' && bundleApiLoaded) return true + else return false + } else if (type === 'deployment') { + const deploymentType = getValue(model, '/spec/admin/deployment/default') + if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + commit('wizard/model$update', { + path: '/spec/admin/deployment/default', + value: 'Shared', + force: true, + }) + } + return ( + getValue(model, `/spec/admin/${type}/toggle`) && + nodetopologiesDedicated.length && + bundleApiLoaded + ) + } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded + } -async function getNodeTopology({ model, getValue, axios, storeGet, watchDependency }) { - watchDependency('model#/spec/admin/deployment/default') - watchDependency('model#/spec/admin/clusterTier/default') - const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' - const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' - let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + async function getNodeTopology() { + // watchDependency('model#/spec/admin/deployment/default') + // watchDependency('model#/spec/admin/clusterTier/default') + const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' + const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' + let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] - const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' - if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared - else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared + else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated - const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) - return filteredList -} + const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) + return filteredList + } -function filterNodeTopology(list, tier, provider) { - // first filter the list from value that exists from the filtered list got from API - const filteredlist = list + function filterNodeTopology(list, tier, provider) { + // first filter the list from value that exists from the filtered list got from API + const filteredlist = list - // filter the list based on clusterTier - if (provider === 'EKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('c') - else if (tier === 'MemoryOptimized') return item.startsWith('r') - else return !item.startsWith('c') && !item.startsWith('r') - }) - } else if (provider === 'AKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - else - return ( - !(item.startsWith('f') || item.startsWith('fx')) && - !( + // filter the list based on clusterTier + if (provider === 'EKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('c') + else if (tier === 'MemoryOptimized') return item.startsWith('r') + else return !item.startsWith('c') && !item.startsWith('r') + }) + } else if (provider === 'AKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('e') || item.startsWith('eb') || item.startsWith('ec') || item.startsWith('m') || item.startsWith('d') ) - ) - }) - } else if (provider === 'GKE') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') - return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - else - return ( - !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && - !( + else + return ( + !(item.startsWith('f') || item.startsWith('fx')) && + !( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + ) + }) + } else if (provider === 'GKE') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') + return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('x4') || item.startsWith('m1') || item.startsWith('m2') || item.startsWith('m3') ) - ) - }) - } else return filteredlist -} + else + return ( + !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && + !( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + ) + }) + } else return filteredlist + } -function returnFalse() { - return false -} + function returnFalse() { + return false + } -function showAlerts({ watchDependency, model, getValue, discriminator }) { - watchDependency('discriminator#/monitoring') - const isMonitorEnabled = getValue(discriminator, '/monitoring') - return ( - isMonitorEnabled && isToggleOn({ getValue, model, watchDependency, discriminator }, 'alert') - ) -} + function showAlerts() { + // watchDependency('discriminator#/monitoring') + const isMonitorEnabled = getValue(discriminator, '/monitoring') + return isMonitorEnabled && isToggleOn('alert') + } -function onBackupSwitch({ discriminator, getValue, commit }) { - const isBackupOn = getValue(discriminator, '/backup') - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: isBackupOn ? 'KubeStash' : '', - force: true, - }) -} + function onBackupSwitch() { + const isBackupOn = getValue(discriminator, '/backup') + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: isBackupOn ? 'KubeStash' : '', + force: true, + }) + } -function clearArbiterHidden({ commit }) { - commit('wizard/model$update', { - path: `/spec/arbiter/enabled`, - value: false, - force: true, - }) - - commit('wizard/model$update', { - path: `/spec/hidden/enabled`, - value: false, - force: true, - }) -} + function clearArbiterHidden() { + commit('wizard/model$update', { + path: `/spec/arbiter/enabled`, + value: false, + force: true, + }) -function isConfigDatabaseOn({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configDatabase') - return getValue(discriminator, '/configDatabase') -} + commit('wizard/model$update', { + path: `/spec/hidden/enabled`, + value: false, + force: true, + }) + } -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} + function isConfigDatabaseOn() { + // watchDependency('discriminator#/configDatabase') + return getValue(discriminator, '/configDatabase') + } -function showHidden({ watchDependency, model, getValue }) { - watchDependency('model#/spec/hidden/enabled') - const isHiddenOn = getValue(model, '/spec/hidden/enabled') || '' - const notStandalone = notEqualToDatabaseMode({ model, getValue, watchDependency }, 'Standalone') - return isHiddenOn && notStandalone -} + function notEqualToDatabaseMode(mode) { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + return modelPathValue && modelPathValue !== mode + } -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} + function showHidden() { + // watchDependency('model#/spec/hidden/enabled') + const isHiddenOn = getValue(model, '/spec/hidden/enabled') || '' + const notStandalone = notEqualToDatabaseMode('Standalone') + return isHiddenOn && notStandalone + } -function showArbiter({ watchDependency, model, getValue }) { - watchDependency('model#/spec/arbiter/enabled') - const isArbiterOn = getValue(model, '/spec/arbiter/enabled') || '' - const notStandalone = notEqualToDatabaseMode({ model, getValue, watchDependency }, 'Standalone') - return isArbiterOn && notStandalone -} + function notEqualToDatabaseMode(mode) { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + return modelPathValue && modelPathValue !== mode + } -function clearConfiguration({ discriminator, getValue, commit }) { - const configOn = getValue(discriminator, '/configDatabase') + function showArbiter() { + // watchDependency('model#/spec/arbiter/enabled') + const isArbiterOn = getValue(model, '/spec/arbiter/enabled') || '' + const notStandalone = notEqualToDatabaseMode('Standalone') + return isArbiterOn && notStandalone + } + + function clearConfiguration() { + const configOn = getValue(discriminator, '/configDatabase') - if (!configOn) { - commit('wizard/model$delete', '/spec/configuration') + if (!configOn) { + commit('wizard/model$delete', '/spec/configuration') + } } -} -function showIssuer({ model, getValue, watchDependency, discriminator }) { - watchDependency('model#/spec/admin/tls/default') - const isTlsEnabled = getValue(model, '/spec/admin/tls/default') - const isIssuerToggleEnabled = isToggleOn( - { getValue, model, watchDependency, discriminator }, - 'clusterIssuers', - ) - return isTlsEnabled && isIssuerToggleEnabled -} + function showIssuer() { + // watchDependency('model#/spec/admin/tls/default') + const isTlsEnabled = getValue(model, '/spec/admin/tls/default') + const isIssuerToggleEnabled = isToggleOn('clusterIssuers') + return isTlsEnabled && isIssuerToggleEnabled + } -function onAuthChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/authSecret/password', - value: '', - force: true, - }) -} + function onAuthChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/spec/authSecret/password', + value: '', + force: true, + }) + } -function setMonitoring({ getValue, model }) { - const agent = getValue(model, '/spec/admin/monitoring/agent') || '' - return !!agent -} + function setMonitoring() { + const agent = getValue(model, '/spec/admin/monitoring/agent') || '' + return !!agent + } -function setBackup({ model, getValue }) { - const backup = getValue(model, '/spec/backup/tool') - const val = getValue(model, '/spec/admin/backup/enable/default') - return backup === 'KubeStash' && features.includes('backup') && val -} + function setBackup() { + const backup = getValue(model, '/spec/backup/tool') + const val = getValue(model, '/spec/admin/backup/enable/default') + return backup === 'KubeStash' && features.includes('backup') && val + } -function isMachineCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue === 'custom' -} + function isMachineCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue === 'custom' + } -function isMachineNotCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue !== 'custom' && !!modelPathValue -} + function isMachineNotCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue !== 'custom' && !!modelPathValue + } -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, }, - }, - ) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] + ) + if (resp.data?.status?.projects) { + const projects = resp.data?.status?.projects + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } + } catch (e) { + console.log(e) } - } catch (e) { - console.log(e) + return [] } - return [] -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } -function updateAlertValue({ commit, model, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const alert = isMonitorEnabled ? 'warning' : 'none' - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: alert, - force: true, - }) - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} + function updateAlertValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const alert = isMonitorEnabled ? 'warning' : 'none' + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: alert, + force: true, + }) + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: agent, + force: true, + }) + } -function onModeChange({ model, getValue, commit }) { - const dbMode = getValue(model, '/spec/mode') - commit('wizard/model$update', { - path: '/spec/replicas', - value: dbMode === 'Replicaset' ? 3 : 1, - force: true, - }) -} + function onModeChange() { + const dbMode = getValue(model, '/spec/mode') + commit('wizard/model$update', { + path: '/spec/replicas', + value: dbMode === 'Replicaset' ? 3 : 1, + force: true, + }) + } -async function getAppBindings({ axios, storeGet }, type) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const queryParams = { - filter: { - items: { - metadata: { name: null, namespace: null }, - spec: { type: null }, + async function getAppBindings(type) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const queryParams = { + filter: { + items: { + metadata: { name: null, namespace: null }, + spec: { type: null }, + }, }, - }, + } + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/appcatalog.appscode.com/v1alpha1/appbindings`, + queryParams, + ) + const resources = (resp && resp.data && resp.data.items) || [] + + const fileredResources = resources + .filter((item) => item.spec?.type === `kubedb.com/${type}`) + .map((item) => { + const name = item.metadata?.name || '' + const namespace = item.metadata?.namespace || '' + return { + text: `${namespace}/${name}`, + value: { + name: name, + namespace: namespace, + }, + } + }) + return fileredResources + } catch (e) { + console.log(e) + return [] + } } - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/appcatalog.appscode.com/v1alpha1/appbindings`, - queryParams, - ) - const resources = (resp && resp.data && resp.data.items) || [] - - const fileredResources = resources - .filter((item) => item.spec?.type === `kubedb.com/${type}`) - .map((item) => { - const name = item.metadata?.name || '' - const namespace = item.metadata?.namespace || '' - return { - text: `${namespace}/${name}`, - value: { - name: name, - namespace: namespace, - }, - } - }) - return fileredResources - } catch (e) { - console.log(e) - return [] + + function onRefChange(type) { + const ref = getValue(discriminator, `/${type}`) || {} + commit('wizard/model$update', { + path: `/spec/${type}/name`, + value: ref.name || '', + force: true, + }) + commit('wizard/model$update', { + path: `/spec/${type}/namespace`, + value: ref.namespace || '', + force: true, + }) } -} -function onRefChange({ discriminator, getValue, commit }, type) { - const ref = getValue(discriminator, `/${type}`) || {} - commit('wizard/model$update', { - path: `/spec/${type}/name`, - value: ref.name || '', - force: true, - }) - commit('wizard/model$update', { - path: `/spec/${type}/namespace`, - value: ref.namespace || '', - force: true, - }) -} + function showAdditionalSettings() { + // watchDependency('discriminator#/bundleApiLoaded') + return features.length + } -function showAdditionalSettings({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return features.length -} + function getDefault(type) { + const val = getValue(model, `/spec/admin/${type}/default`) || '' + return val + } -function getDefault({ getValue, model }, type) { - const val = getValue(model, `/spec/admin/${type}/default`) || '' - return val -} + async function getReferSecrets() { + const referSecret = getValue(discriminator, '/referSecret') + if (!referSecret) { + return [] + } -function isConfigAvailable({ getValue, model }) { - const val = getValue(model, '/spec/configuration') - return val !== '' -} + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/metadata/release/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` -async function getReferSecrets({ getValue, model, storeGet, axios, discriminator }) { - const referSecret = getValue(discriminator, '/referSecret') - if (!referSecret) { - return [] + const options = [] + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + return options } - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/metadata/release/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - - const options = [] - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) - } catch (e) { - console.log(e) + function showAuthPasswordField() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !modelPathValue && showReferSecret() } - return options -} - -function showAuthPasswordField({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} -function showSecretDropdown({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showSecretDropdown() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !!modelPathValue && showReferSecret() + } -function showReferSecret({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/createAuthSecret') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue -} + function showReferSecret() { + const modelPathValue = getValue(discriminator, '/createAuthSecret') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue + } -function getDefaultValue({ getValue, model }, path) { - const val = getValue(model, `/${path}`) || '' - return val -} + function getDefaultValue(path) { + const val = getValue(model, `/${path}`) || '' + return val + } -function showReferSecretSwitch({ model, getValue, watchDependency, discriminator }) { - const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showReferSecretSwitch() { + const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue && showReferSecret() + } -function onReferSecretChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) -} + function onReferSecretChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + } -return { - showReferSecretSwitch, - onReferSecretChange, - getDefaultValue, - isRancherManaged, - showSecretDropdown, - showReferSecret, - getReferSecrets, - isConfigAvailable, - returnFalse, - initBundle, - getNamespaces, - updateAlertValue, - getAdminOptions, - isToggleOn, - showAlerts, - getNodeTopology, - clearArbiterHidden, - showHidden, - isConfigDatabaseOn, - notEqualToDatabaseMode, - filterNodeTopology, - onAuthChange, - setMonitoring, - isMachineNotCustom, - isMachineCustom, - showIssuer, - showArbiter, - clearConfiguration, - onBackupSwitch, - isVariantAvailable, - fetchJsons, - showAuthPasswordField, - isEqualToModelPathValue, - getMachineListForOptions, - setLimits, - setRequests, - setMachineToCustom, - updateAgentValue, - getCreateNameSpaceUrl, - ifCapiProviderIsNotEmpty, - ifDedicated, - dedicatedOnChange, - ifZones, - zonesOnChange, - getZones, - getSKU, - showMultiselectZone, - showSelectZone, - setStorageClass, - onModeChange, - getAppBindings, - onRefChange, - setBackup, - showAdditionalSettings, - getDefault, + return { + showReferSecretSwitch, + onReferSecretChange, + getDefaultValue, + isRancherManaged, + showSecretDropdown, + showReferSecret, + getReferSecrets, + returnFalse, + initBundle, + getNamespaces, + updateAlertValue, + getAdminOptions, + isToggleOn, + showAlerts, + getNodeTopology, + clearArbiterHidden, + showHidden, + isConfigDatabaseOn, + notEqualToDatabaseMode, + filterNodeTopology, + onAuthChange, + setMonitoring, + isMachineNotCustom, + isMachineCustom, + showIssuer, + showArbiter, + clearConfiguration, + onBackupSwitch, + isVariantAvailable, + fetchJsons, + showAuthPasswordField, + isEqualToModelPathValue, + getMachineListForOptions, + setLimits, + setRequests, + setMachineToCustom, + updateAgentValue, + getCreateNameSpaceUrl, + ifCapiProviderIsNotEmpty, + ifDedicated, + dedicatedOnChange, + ifZones, + zonesOnChange, + getZones, + getSKU, + showMultiselectZone, + showSelectZone, + setStorageClass, + onModeChange, + getAppBindings, + onRefChange, + setBackup, + showAdditionalSettings, + getDefault, + } } diff --git a/charts/kubedbcom-pgpool-editor/ui/edit-ui.yaml b/charts/kubedbcom-pgpool-editor/ui/edit-ui.yaml index 321ff9c769..1ff9bf3056 100644 --- a/charts/kubedbcom-pgpool-editor/ui/edit-ui.yaml +++ b/charts/kubedbcom-pgpool-editor/ui/edit-ui.yaml @@ -1,460 +1,494 @@ -steps: -- form: - discriminator: - dbDetails: - default: false - type: boolean +type: multi-step-form +step: + - type: single-step-form + id: compute-autoscaler + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: Select Db - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: Select Type - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - discriminator: - topologyMachines: - default: [] - type: array - elements: - - fetch: fetchTopologyMachines - if: returnFalse - schema: - $ref: discriminator#/topologyMachines - type: input - - elements: - - computed: setTrigger|autoscalingKubedbComPgpoolAutoscaler/spec/compute/pgpool/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/pgpool/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/pgpool/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/pgpool/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-max: - type: string - allowedMachine-min: - type: string - elements: - - computed: setAllowedMachine|min - disableUnselect: true - fetch: getMachines|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|pgpool - schema: - $ref: discriminator#/properties/allowedMachine-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/pgpool/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/pgpool/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/pgpool/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|max - disableUnselect: true - fetch: getMachines|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|pgpool - schema: - $ref: discriminator#/properties/allowedMachine-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/pgpool/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/pgpool/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/pgpool/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|pgpool - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/pgpool/properties/controlledResources - type: multiselect - label: - text: pgpool - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/pgpool - show_label: true - type: single-step-form - - elements: - - fetch: fetchNodeTopology - label: - text: Select Node Topology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name - type: select - - if: isNodeTopologySelected - label: - text: ScaleUp Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage - type: input - - if: isNodeTopologySelected - label: - text: ScaleDown Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage - type: input - if: hasNoAnnotations - label: - text: NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/nodeTopology - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout + - type: block-layout + if: + type: function + name: isConsole + elements: + - type: input + label: Name + schema: schema/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/metadata/properties/name + - type: select + label: Select Namespace + loader: getNamespaces + if: + type: function + name: isRancherManaged + schema: schema/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/metadata/properties/namespace + - type: select + label: Select Db + loader: getDbs + validation: + type: required + refresh: true + schema: schema/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/databaseRef/properties/name + watcher: + func: initMetadata + paths: + - schema/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/databaseRef/properties/name + + - type: radio + if: + type: function + name: isConsole + label: Select Type + validation: + type: required + schema: temp/properties/autoscalingType + watcher: + func: initMetadata + paths: + - temp/properties/autoscalingType options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: compute-autoscaler - title: steps.6.label -- form: - discriminator: - enableMonitoring: - default: true - type: boolean + - text: Compute + value: compute + description: Scale your CPU Memory based on resource usage + - text: Storage + value: storage + description: Expand your database size based on volume usage + + - type: block-layout + showLabels: false + loader: fetchTopologyMachines + elements: + # pgpool mode + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComPgpoolAutoscaler/spec/compute/pgpool/trigger + schema: temp/properties/compute/properties/pgpool/properties/trigger + watcher: + func: onTriggerChange|compute/pgpool + paths: + - temp/properties/compute/properties/pgpool/properties/trigger + - type: label-element + label: Pod lifetime threshold + subtitle: Specifies the duration a pod can exist before being considered for scaling decisions, ensuring resource optimization and workload stability + - type: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/pgpool/properties/podLifeTimeThreshold + customClass: width-300 + - type: block-layout + label: Pgpool + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/pgpool + elements: + - type: threshold-input + label: Resource Diff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/pgpool/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|min + loader: + name: getMachines|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-max + watcher: + func: onMachineChange|pgpool + paths: + - temp/properties/allowedMachine-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/pgpool/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/pgpool/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|max + loader: + name: getMachines|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-min + watcher: + func: onMachineChange|pgpool + paths: + - temp/properties/allowedMachine-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/pgpool/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/pgpool/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|compute/pgpool + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/pgpool/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/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/pgpool/properties/containerControlledValues + - type: block-layout + label: Node Topology + if: + type: function + name: hasNoAnnotations + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/nodeTopology + elements: + - type: label-element + label: Node Topology Configuration + subtitle: Configure node topology constraints to control where your database pods are scheduled based on node labels + - type: select + label: Select Node Topology + loader: fetchNodeTopology + schema: schema/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name + - type: threshold-input + label: ScaleUp Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage + - type: threshold-input + label: ScaleDown Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage + + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + # schema: schema/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/opsRequestOptions + elements: + - type: time-picker + label: Timeout + subtitle: Specify the maximum time allowed for the scaling operation to complete. Use formats like 30s, 1m (1 minute) or 2h (2 hours). + schema: schema/properties/resources/properties/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComPgpoolAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: monitoring + loader: initMonitoring elements: - - label: - text: labels.to_update_exporter_resources - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - function: getOpsRequestUrl|VerticalScaling - - computed: isValueExistInModel|/resources/kubedbComPgpool/spec/monitor - label: - text: labels.enable_monitoring - onChange: onEnableMonitoringChange - schema: - $ref: discriminator#/enableMonitoring - type: switch - - discriminator: - customizeExporter: - default: true - type: boolean + - type: label-element + label: To update Exporter Resource section click on Create OpsRequest + - type: anchor + label: Create OpsRequest + schema: temp/properties/opsRequestUrl + init: + type: func + value: getOpsRequestUrl|scale-vertically + - type: switch + label: Enable Monitoring + fullwidth: true + schema: temp/properties/enableMonitoring + init: + type: func + value: isValueExistInModel|/resources/kubedbComPgpool/spec/monitor + watcher: + func: onEnableMonitoringChange + paths: + - temp/properties/enableMonitoring + - type: block-layout + label: Monitoring Configuration + showLabels: false + if: + type: function + name: showMonitoringSection 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/kubedbComPgpool/properties/spec/properties/monitor/properties/agent - type: radio - - elements: - - label: - text: labels.scrapping_interval - schema: - $ref: schema#/properties/resources/properties/kubedbComPgpool/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval - type: input - if: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComPgpool/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: label-element + label: Monitoring Method Selection + subtitle: Choose the monitoring approach that best fits your infrastructure. Prometheus Operator provides automated ServiceMonitor creation, while custom options give you more control. + - type: radio + label: Select a Monitoring Method + schema: schema/properties/resources/properties/kubedbComPgpool/properties/spec/properties/monitor/properties/agent + isHorizontal: true + options: + - text: Prometheus Operator + value: prometheus.io/operator + description: Inject metric exporter sidecar and creates a ServiceMonitor + - text: Custom ServiceMonitor + value: prometheus.io + description: Injects the metric exporter sidecar and let you customize ServiceMonitor + - text: Custom Scraper + value: prometheus.io/builtin + description: Inject metric exporter sidecar and add Prometheus annotations to the stats Service + init: + type: static + value: prometheus.io/operator + watcher: + func: onAgentChange + paths: + - schema/properties/resources/properties/kubedbComPgpool/properties/spec/properties/monitor/properties/agent + - type: block-layout + label: ServiceMonitor Configuration + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComPgpool/spec/monitor/agent + elements: + - type: label-element + label: Scraping Interval + subtitle: Define how frequently Prometheus should scrape metrics from your database + - type: input + label: Scraping Interval + schema: schema/properties/resources/properties/kubedbComPgpool/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval + - type: block-layout + label: Service Monitor + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComPgpool/spec/monitor/agent + elements: + - type: array-object-form + label: Endpoints + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/endpoints + elements: + - type: switch + label: Honor labels + fullwidth: true + schema: honorLabels + - type: input + label: Interval + schema: interval + validation: + type: required + - type: input + label: Path + schema: path + validation: + type: required + - type: input + label: Port + schema: port + validation: + type: required + - type: select + multiple: true + label: Match Namespaces + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/namespaceSelector/properties/matchNames + loader: getResources|core|v1|namespaces + if: + type: function + name: returnFalse + - type: block-layout + showLabels: false + # schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector + if: + type: function + name: returnFalse + elements: + - type: object-item + label: Labels + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector/properties/matchLabels + - type: object-item + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/metadata/properties/labels + label : Labels + buttonClass: is-light is-outlined + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComPgpool/spec/monitor/agent + # individualItemDisabilityCheck: disableLableChecker + - type: label-element + label: Exporter Configuration + schema: '' + - type: switch + label: Customize Exporter Sidecar + fullwidth: true + schema: temp/properties/customizeExporter + init: + type: static + value: true + watcher: + func: onCustomizeExporterChange + paths: + - temp/properties/customizeExporter + - type: block-layout + label: Customer Exporter Section + showLabels: false + if: + type: function + name: showCustomizeExporterSection + elements: + - type: machine-compare + label: Resources + schema: schema/properties/resources/properties/kubedbComPgpool/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/resources + if: + type: function + name: returnFalse + - type: label-element + label: Security Context + schema: '' + - type: input + schema: schema/properties/resources/properties/kubedbComPgpool/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsUser + label: Run as User + - type: input + schema: schema/properties/resources/properties/kubedbComPgpool/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup + label: Run as Group + - type: input + schema: schema/properties/resources/properties/kubedbComPgpool/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/port + label: Port + - type: array-item-form + label: Args + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/kubedbComPgpool/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args + init: + type: static + value: ['--compatible-mode'] + element: 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/kubedbComPgpool/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/kubedbComPgpool/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: - - if: returnFalse - label: - text: labels.resources - schema: - $ref: schema#/properties/resources/properties/kubedbComPgpool/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/kubedbComPgpool/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/kubedbComPgpool/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup - type: input - - label: - text: labels.port - schema: - $ref: schema#/properties/resources/properties/kubedbComPgpool/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/kubedbComPgpool/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args/items - type: input - label: - text: labels.args - schema: - $ref: schema#/properties/resources/properties/kubedbComPgpool/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args - type: list-input-form - - alias: reusable_env - chart: - name: uibytebuildersdev-component-env - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComPgpool/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 -type: multi-step-form + label: Args + # isSubsection: true + - type: block-layout + label: Metadata + showLabels: false + elements: + - type: array-object-form + init: + type: func + value: initEnvArray + label: Environment Variables + buttonClass: is-light is-outlined + watcher: + func: onEnvArrayChange + paths: + - temp/properties/env + schema: temp/properties/env + elements: + - type: input + label: Name + schema: name + validation: + type: required + - type: radio + label: Value From + schema: temp/properties/valueFromType + validation: + type: required + init: + type: func + value: setValueFrom + options: + - text: Input + value: input + - text: Secret + value: secret + - text: ConfigMap + value: configMap + watcher: + func: onValueFromChange + paths: + - temp/properties/valueFromType + - type: input + label: Value + schema: value + validation: + type: required + if: + name: isEqualToTemp|input + type: function + - type: select + if: + type: function + name: isEqualToTemp|configMap + label: ConfigMap Name + schema: valueFrom/properties/configMapKeyRef/properties/name + loader: + name: resourceNames|core|v1|configmaps + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: ConfigMap Key + schema: valueFrom/properties/configMapKeyRef/properties/key + if: + type: function + name: isEqualToTemp|configMap + loader: + name: getConfigMapKeys + watchPaths: + - schema/resources/kubedbComPgpool/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/configMapKeyRef/name + - schema/metadata/release/namespace + - type: select + label: Secret Name + schema: valueFrom/properties/secretKeyRef/properties/name + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecrets + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: Secret Key + schema: valueFrom/properties/secretKeyRef/properties/key + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecretKeys + watchPaths: + - schema/resources/kubedbComPgpool/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/secretKeyRef/name + - schema/metadata/release/namespace diff --git a/charts/kubedbcom-pgpool-editor/ui/functions.js b/charts/kubedbcom-pgpool-editor/ui/functions.js index eea703407d..ec453245a2 100644 --- a/charts/kubedbcom-pgpool-editor/ui/functions.js +++ b/charts/kubedbcom-pgpool-editor/ui/functions.js @@ -1,2207 +1,920 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + // ************************* common functions ******************************************** // eslint-disable-next-line no-empty-pattern -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, - } -} +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) -function disableLableChecker({ itemCtx }) { - const { key } = itemCtx - if (key.startsWith('app.kubernetes.io') || key.includes('helm')) return true - else return false -} + setDiscriminatorValue('/enableMonitoring', false) + setDiscriminatorValue('/customizeExporter', true) + setDiscriminatorValue('/valueFromType', 'input') + setDiscriminatorValue('/env', []) -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} + // Autoscaler Discriminators + setDiscriminatorValue('/dbDetails', false) + setDiscriminatorValue('/topologyMachines', []) + setDiscriminatorValue('/allowedMachine-pgpool-min', '') + setDiscriminatorValue('/allowedMachine-pgpool-max', '') + setDiscriminatorValue('/allowedMachine-min', '') + setDiscriminatorValue('/allowedMachine-max', '') -async function getResources({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + let autoscaleType = '' + let dbDetails = {} + let instance = {} - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + function isConsole() { + const isKube = isKubedb() - const resources = (resp && resp.data && resp.data.items) || [] + if (isKube) { + const dbName = storeGet('/route/params/name') || '' + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComPgpoolAutoscaler/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/autoscalingKubedbComPgpoolAutoscaler/metadata/name', + value: modifiedName, + force: true, + }) + const namespace = storeGet('/route/query/namespace') || '' + if (namespace) { + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComPgpoolAutoscaler/metadata/namespace', + value: namespace, + force: true, + }) + } + } - 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 [] + return !isKube } -} - -function isEqualToDiscriminatorPath( - { discriminator, getValue, watchDependency }, - value, - discriminatorPath, -) { - watchDependency('discriminator#' + discriminatorPath) - const discriminatorValue = getValue(discriminator, discriminatorPath) - return discriminatorValue === value -} - -function setValueFromModel({ getValue, model }, path) { - return getValue(model, path) -} - -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) + function isKubedb() { + return !!storeGet('/route/params/actions') } - return ans -} - -async function getResourceList(axios, storeGet, { 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) + function showOpsRequestOptions() { + if (isKubedb() === true) return true + // watchDependency('model#/resources/autoscalingKubedbComPgpoolAutoscaler/spec/databaseRef/name') + // watchDependency('discriminator#/autoscalingType') + return ( + !!getValue(model, '/resources/autoscalingKubedbComPgpoolAutoscaler/spec/databaseRef/name') && + !!getValue(discriminator, '/autoscalingType') + ) } - return ans -} - -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - 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) - }) + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + async function getNamespaces() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) - - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, }) - } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} - -function returnTrue() { - return true -} - -function returnStringYes() { - return 'yes' -} -function setAddressType({ model, getValue }) { - const value = getValue(model, '/resources/kubedbComPgpool/spec/useAddressType') + const resources = (resp && resp.data && resp.data.items) || [] - if (!value) { - return 'DNS' + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) } - return value -} - -// ************************* Basic Info ********************************************** -async function getPgpoolVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, - }, - }, - } + async function getDbs() { + // watchDependency('model#/resources/autoscalingKubedbComPgpoolAutoscaler/metadata/namespace') + const namespace = getValue( + model, + '/resources/autoscalingKubedbComPgpoolAutoscaler/metadata/namespace', + ) + 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}`, + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises`, { - params: queryParams, + params: { filter: { items: { metadata: { name: null } } } }, }, ) const resources = (resp && resp.data && resp.data.items) || [] - // keep only non deprecated versions - const filteredMongoDbVersions = resources.filter((item) => item.spec && !item.spec.deprecated) - - filteredMongoDbVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredMongoDbVersions - } catch (e) { - console.log(e) - return [] - } -} - -// ********************* Database Mode *********************** -function setDatabaseMode({ model, getValue }) { - const replicas = getValue(model, '/resources/kubedbComPgpool/spec/replicas') - - return replicas === 1 ? 'Standalone' : 'Cluster' -} - -function isEqualToDatabaseMode({ getValue, watchDependency, discriminator }, value) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - return mode === value -} - -const onDatabaseModeChange = ({ discriminator, getValue, commit }) => { - const databaseMode = getValue(discriminator, '/activeDatabaseMode') - - commit('wizard/model$update', { - path: '/resources/kubedbComPgpool/spec/replicas', - value: databaseMode === 'Standalone' ? 1 : 3, - force: true, - }) -} - -// ************************** TLS ******************************88 - -function setApiGroup() { - return 'cert-manager.io' -} - -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - watchDependency('model#/resources/kubedbComPgpool/spec/tls/issuerRef/apiGroup') - watchDependency('model#/resources/kubedbComPgpool/spec/tls/issuerRef/kind') - watchDependency('model#/metadata/release/namespace') - const apiGroup = getValue(model, '/resources/kubedbComPgpool/spec/tls/issuerRef/apiGroup') - const kind = getValue(model, '/resources/kubedbComPgpool/spec/tls/issuerRef/kind') - const namespace = getValue(model, '/metadata/release/namespace') - - let url - if (kind === 'Issuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/namespaces/${namespace}/issuers` - } else if (kind === 'ClusterIssuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/clusterissuers` - } - - if (!url) return [] - - try { - const resp = await axios.get(url) - - const resources = (resp && resp.data && resp.data.items) || [] - - resources.map((item) => { + return resources.map((item) => { const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + return { + text: name, + value: name, + } }) - return resources - } catch (e) { - console.log(e) - return [] } -} - -async function hasIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await getIssuerRefsName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - return !!(resp && resp.length) -} - -async function hasNoIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await hasIssuerRefName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !resp -} - -function setSSLMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComPgpool/spec/sslMode') - return val || 'require' -} - -function showTlsConfigureSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configureTLS') - const configureStatus = getValue(discriminator, '/configureTLS') - return configureStatus -} + async function getDbDetails() { + const annotations = + getValue(model, '/resources/autoscalingKubedbComPgpoolAutoscaler/metadata/annotations') || {} + instance = annotations['kubernetes.io/instance-type'] + const owner = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + const namespace = + storeGet('/route/query/namespace') || + getValue(model, '/resources/autoscalingKubedbComPgpoolAutoscaler/metadata/namespace') || + '' + const name = + storeGet('/route/params/name') || + getValue(model, '/resources/autoscalingKubedbComPgpoolAutoscaler/spec/databaseRef/name') || + '' + + if (namespace && name) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/pgpools/${name}`, + ) + dbDetails = resp.data || {} + setDiscriminatorValue('/dbDetails', true) + } catch (e) { + console.log(e) + } + } -function onTlsConfigureChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/configureTLS') - if (configureStatus) { commit('wizard/model$update', { - path: '/resources/kubedbComPgpool/spec/tls', - value: { issuerRef: {}, certificates: [] }, + path: `/metadata/release/name`, + value: name, force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComPgpool/spec/tls') - commit('wizard/model$delete', '/resources/kubedbComPgpool/spec/sslMode') - } -} - -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} - -/****** Monitoring *********/ - -function showMonitoringSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/enableMonitoring') - const configureStatus = getValue(discriminator, '/enableMonitoring') - return configureStatus -} - -function onEnableMonitoringChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/enableMonitoring') - if (configureStatus) { commit('wizard/model$update', { - path: '/resources/kubedbComPgpool/spec/monitor', - value: {}, + path: `/metadata/release/namespace`, + value: namespace, force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComPgpool/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, getValue }) { - watchDependency('discriminator#/customizeExporter') - const configureStatus = getValue(discriminator, '/customizeExporter') - return configureStatus -} - -function onCustomizeExporterChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/customizeExporter') - if (configureStatus) { commit('wizard/model$update', { - path: '/resources/kubedbComPgpool/spec/monitor/prometheus/exporter', - value: {}, + path: `/resources/autoscalingKubedbComPgpoolAutoscaler/spec/databaseRef/name`, + value: name, force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComPgpool/spec/monitor/prometheus/exporter') - } -} - -// ********************************* Initialization & Backup ************************************* -const stashAppscodeComRestoreSession_init = { - spec: { - repository: { - name: '', - }, - rules: [ - { - snapshots: ['latest'], - }, - ], - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} -const initScript = { - scriptPath: '', - secret: { - secretName: '', - }, -} -const stashAppscodeComRepository_init_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const stashAppscodeComRepository_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const restoreSessionInitRunTimeSettings = { - container: { - resources: { - requests: { - cpu: '', - memory: '', - }, - limits: { - cpu: '', - memory: '', - }, - }, - nice: { - adjustment: null, - }, - ionice: { - class: null, - classData: null, - }, - securityContext: { - privileged: false, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - env: [], - envFrom: [], - }, - pod: { - serviceAccountName: '', - imagePullSecrets: [], - securityContext: { - fsGroup: null, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - }, -} - -const stashAppscodeComBackupConfiguration = { - spec: { - repository: { - name: '', - }, - retentionPolicy: { - keepLast: 5, - name: 'keep-last-5', - prune: true, - }, - schedule: '*/5 * * * *', - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} - -function valueExists(value, getValue, path) { - const val = getValue(value, path) - if (val) return true - else return false -} - -function initPrePopulateDatabase({ getValue, model }) { - const waitForInitialRestore = getValue( - model, - '/resources/kubedbComPgpool/spec/init/waitForInitialRestore', - ) - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - const script = getValue(model, '/resources/kubedbComPgpool/spec/init/script') - - return waitForInitialRestore || !!stashAppscodeComRestoreSession_init || !!script ? 'yes' : 'no' -} - -function onPrePopulateDatabaseChange({ commit, getValue, discriminator, model }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - if (prePopulateDatabase === 'no') { - // delete related properties commit('wizard/model$update', { - path: '/resources/kubedbComPgpool/spec/init/waitForInitialRestore', - value: false, + path: `/resources/autoscalingKubedbComPgpoolAutoscaler/metadata/labels`, + value: dbDetails.metadata.labels, + force: true, }) - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - commit('wizard/model$delete', '/resources/kubedbComPgpool/spec/init/script') - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else { - const dbName = getValue(model, '/metadata/release/name') - // set stashAppscodeComRestoreSession_init if it doesn't exist - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - force: true, - }) - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - } } -} - -function initDataSource({ getValue, model }) { - const script = getValue(model, '/resources/kubedbComPgpool/spec/init/script') - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - - if (script) return 'script' - else if (stashAppscodeComRestoreSession_init) return 'stashBackup' - else return undefined -} - -function onDataSourceChange({ commit, getValue, discriminator, model }) { - const dataSource = getValue(discriminator, '/dataSource') - - commit('wizard/model$update', { - path: '/resources/kubedbComPgpool/spec/init/waitForInitialRestore', - value: dataSource === 'stashBackup', - force: true, - }) - - if (dataSource === 'script') { - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - - // create a new script if there is no script property - if (!valueExists(model, getValue, '/resources/kubedbComPgpool/spec/init/script')) - commit('wizard/model$update', { - path: '/resources/kubedbComPgpool/spec/init/script', - value: initScript, - }) - } else if (dataSource === 'stashBackup') { - commit('wizard/model$delete', '/resources/kubedbComPgpool/spec/init/script') - - // create a new stashAppscodeComRestoreSession_init if there is no stashAppscodeComRestoreSession_init property - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - const dbName = getValue(model, '/metadata/release/name') - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - }) + function initMetadata() { + const dbName = + getValue(model, '/resources/autoscalingKubedbComPgpoolAutoscaler/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/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, + path: '/resources/autoscalingKubedbComPgpoolAutoscaler/metadata/name', + value: modifiedName, force: true, }) - } - } -} - -// // for script -function initVolumeType({ getValue, model }) { - const configMap = getValue(model, '/resources/kubedbComPgpool/spec/init/script/configMap/name') - const secret = getValue(model, '/resources/kubedbComPgpool/spec/init/script/secret/secretName') - - if (configMap) return 'configMap' - else if (secret) return 'secret' - else return undefined -} - -function onVolumeTypeChange({ commit, getValue, discriminator, model }) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - if (sourceVolumeType === 'configMap') { - // add configMap object and delete secret object - commit('wizard/model$delete', '/resources/kubedbComPgpool/spec/init/script/secret') - - if (!valueExists(model, getValue, '/resources/kubedbComPgpool/spec/init/script/configMap')) { - commit('wizard/model$update', { - path: '/resources/kubedbComPgpool/spec/init/script/configMap', - value: { - name: '', - }, - }) - } - } else if (sourceVolumeType === 'secret') { - // delete configMap object and add secret object - commit('wizard/model$delete', '/resources/kubedbComPgpool/spec/init/script/configMap') - - if (!valueExists(model, getValue, '/resources/kubedbComPgpool/spec/init/script/secret')) { - commit('wizard/model$update', { - path: '/resources/kubedbComPgpool/spec/init/script/secret', - value: { - secretName: '', - }, - }) - } - } -} - -function showInitializationForm({ getValue, discriminator, watchDependency }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - watchDependency('discriminator#/prePopulateDatabase') - return prePopulateDatabase === 'yes' -} - -function showScriptOrStashForm({ getValue, discriminator, watchDependency }, value) { - const dataSource = getValue(discriminator, '/dataSource') - watchDependency('discriminator#/dataSource') - return dataSource === value -} - -function showConfigMapOrSecretName({ getValue, discriminator, watchDependency }, value) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - watchDependency('discriminator#/sourceVolumeType') - return sourceVolumeType === value -} - -// for stash backup -function initializeNamespace({ getValue, model }) { - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} - -function showRepositorySelectOrCreate({ getValue, discriminator, watchDependency }, value) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - return repositoryChoise === value -} - -function onInitRepositoryChoiseChange({ getValue, discriminator, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - if (repositoryChoise === 'select') { - // delete stashAppscodeComRepository_init_repo from model - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else if (repositoryChoise === 'create') { - // add stashAppscodeComRepository_init_repo to model - commit('wizard/model$update', { - path: 'resources/stashAppscodeComRepository_init_repo', - value: stashAppscodeComRepository_init_repo, - }) - const repositoryName = `${getValue(model, '/metadata/release/name')}-init-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: repositoryName, - }) - } -} - -function initCustomizeRestoreJobRuntimeSettings({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function initCustomizeRestoreJobRuntimeSettingsForBackup({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function onCustomizeRestoreJobRuntimeSettingsChange({ commit, getValue, discriminator, model }) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - value: restoreSessionInitRunTimeSettings, - }) - } + // delete the other type object from model + if (type === 'compute') + commit('wizard/model$delete', '/resources/autoscalingKubedbComPgpoolAutoscaler/spec/storage') + if (type === 'storage') + commit('wizard/model$delete', '/resources/autoscalingKubedbComPgpoolAutoscaler/spec/compute') } -} -function onCustomizeRestoreJobRuntimeSettingsChangeForBackup({ - commit, - getValue, - discriminator, - model, -}) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', + function onNamespaceChange() { + const namespace = getValue( + model, + '/resources/autoscalingKubedbComPgpoolAutoscaler/metadata/namespace', ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', + if (!namespace) { + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComPgpoolAutoscaler/spec/databaseRef/name', ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - value: {}, - force: true, - }) } } -} -function showRuntimeForm({ discriminator, getValue, watchDependency }, value) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - watchDependency('discriminator#/customizeRestoreJobRuntimeSettings') - return customizeRestoreJobRuntimeSettings === value -} - -async function getImagePullSecrets({ getValue, model, watchDependency, axios, storeGet }) { - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - - let resources = await getNamespacedResourceList(axios, storeGet, { - namespace, - group: 'core', - version: 'v1', - resource: 'secrets', - }) - - resources = resources.filter((item) => { - const validType = ['kubernetes.io/dockerconfigjson'] - return validType.includes(item.type) - }) - - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: { name: name }, - } - }) -} - -// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// FOR Backup Configuration - -// schedule bakcup - -function getBackupConfigsAndAnnotations(getValue, model) { - const stashAppscodeComBackupConfiguration = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration', - ) - const kubedbComPgpoolAnnotations = - getValue(model, '/resources/kubedbComPgpool/metadata/annotations') || {} - - const isBluePrint = Object.keys(kubedbComPgpoolAnnotations).some( - (k) => - k === 'stash.appscode.com/backup-blueprint' || - k === 'stash.appscode.com/schedule' || - k.startsWith('params.stash.appscode.com/'), - ) - - return { - stashAppscodeComBackupConfiguration, - isBluePrint, - } -} - -function deleteKubeDbComPgpoolDbAnnotation(getValue, model, commit) { - const annotations = getValue(model, '/resources/kubedbComPgpool/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/kubedbComPgpool/metadata/annotations', - value: filteredAnnotations, - }) -} - -function addKubeDbComPgpoolDbAnnotation(getValue, model, commit, key, value, force) { - const annotations = getValue(model, '/resources/kubedbComPgpool/metadata/annotations') || {} - - if (annotations[key] === undefined) { - annotations[key] = value - } else if (force) { - annotations[key] = value - } - - commit('wizard/model$update', { - path: '/resources/kubedbComPgpool/metadata/annotations', - value: annotations, - force: true, - }) -} - -function initScheduleBackupForEdit({ getValue, model, setDiscriminatorValue }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function initScheduleBackup({ getValue, model }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function onScheduleBackupChange({ commit, getValue, discriminator, model }) { - 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 kubedbComPgpool annotation - deleteKubeDbComPgpoolDbAnnotation(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, - }) - } - } -} - -// backup form -function showBackupForm({ getValue, discriminator, watchDependency }) { - const scheduleBackup = getValue(discriminator, '/scheduleBackup') - watchDependency('discriminator#/scheduleBackup') - - if (scheduleBackup === 'yes') return true - else return false -} - -// invoker form -function initBackupInvoker({ getValue, model }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - if (stashAppscodeComBackupConfiguration) return 'backupConfiguration' - else if (isBluePrint) return 'backupBlueprint' - else return undefined -} - -function onBackupInvokerChange({ getValue, discriminator, commit, model }) { - const backupInvoker = getValue(discriminator, '/backupInvoker') - - if (backupInvoker === 'backupConfiguration') { - // delete annotation and create backup config object - deleteKubeDbComPgpoolDbAnnotation(getValue, model, commit) - const dbName = getValue(model, '/metadata/release/name') - - if (!valueExists(model, getValue, '/resources/stashAppscodeComBackupConfiguration')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration', - value: stashAppscodeComBackupConfiguration, - }) - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, - force: true, + 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) } - } else if (backupInvoker === 'backupBlueprint') { - // delete backup configuration object and create the annotation - commit('wizard/model$delete', '/resources/stashAppscodeComBackupConfiguration') - addKubeDbComPgpoolDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/backup-blueprint', - '', - ) + return [] } -} - -function showInvokerForm({ getValue, discriminator, watchDependency }, value) { - const backupInvoker = getValue(discriminator, '/backupInvoker') - watchDependency('discriminator#/backupInvoker') - - return backupInvoker === value -} - -// backup configuration form -function initalizeTargetReferenceName({ getValue, model, watchDependency }) { - const databaseName = getValue(model, '/metadata/release/name') - watchDependency('model#/metadata/release/name') - - return databaseName -} - -// restore session repository -function setInitialRestoreSessionRepo({ getValue, model }) { - const value = getValue(model, 'resources/stashAppscodeComRepository_init_repo') - return value ? 'create' : 'select' -} - -// backup config repository -function initRepositoryChoise({ getValue, model }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - if (stashAppscodeComRepository_repo) return 'create' - else return 'select' -} - -function initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' - setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) - - return repoInitialSelectionStatus -} - -function onRepositoryChoiseChange({ getValue, discriminator, watchDependency, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - if (repositoryChoise === 'select') { - // delete the stashAppscodeComRepository_repo - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') - } else if (repositoryChoise === 'create') { - // create new stashAppscodeComRepository_repo - if (!valueExists(model, getValue, '/resources/stashAppscodeComRepository_repo')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRepository_repo', - value: stashAppscodeComRepository_repo, - }) - const repositoryName = `${getValue(model, '/metadata/release/name')}-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) - } + function isNodeTopologySelected() { + // watchDependency( + // 'model#/resources/autoscalingKubedbComPgpoolAutoscaler/spec/compute/nodeTopology/name', + // ) + const nodeTopologyName = + getValue( + model, + '/resources/autoscalingKubedbComPgpoolAutoscaler/spec/compute/nodeTopology/name', + ) || '' + return !!nodeTopologyName.length } -} - -function onRepositoryNameChange({ getValue, model, commit }) { - const repositoryName = getValue(model, 'resources/stashAppscodeComRepository_repo/metadata/name') - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) -} - -// backup blueprint form -function getMongoAnnotations(getValue, model) { - const annotations = getValue(model, '/resources/kubedbComPgpool/metadata/annotations') - return { ...annotations } || {} -} - -function initFromAnnotationValue({ getValue, model }, key) { - const annotations = getMongoAnnotations(getValue, model) - return annotations[key] -} - -function onBackupBlueprintNameChange({ getValue, discriminator, commit, model }) { - const backupBlueprintName = getValue(discriminator, '/backupBlueprintName') - addKubeDbComPgpoolDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/backup-blueprint', - backupBlueprintName, - true, - ) -} - -function onBackupBlueprintScheduleChange({ getValue, discriminator, commit, model }) { - const backupBlueprintSchedule = getValue(discriminator, '/schedule') - addKubeDbComPgpoolDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/schedule', - backupBlueprintSchedule, - true, - ) -} -function initFromAnnotationKeyValue({ getValue, model }, prefix) { - const annotations = getMongoAnnotations(getValue, model) - const newOb = {} - Object.keys(annotations).forEach((key) => { - if (key.startsWith(prefix)) { - const newKey = key.replace(prefix, '') - newOb[newKey] = annotations[key] - } - }) - return newOb -} - -function onTaskParametersChange({ getValue, discriminator, model, commit }) { - const taskParameters = getValue(discriminator, '/taskParameters') - - const taskParamterKeys = Object.keys(taskParameters).map( - (tp) => `params.stash.appscode.com/${tp}`, - ) - const oldAnnotations = getValue(model, '/resources/kubedbComPgpool/metadata/annotations') || {} - const newAnnotations = {} - - const filteredAnnotationKeys = Object.keys(oldAnnotations).filter( - (key) => !taskParamterKeys.includes(key) && !key.startsWith('params.stash.appscode.com/'), - ) - - filteredAnnotationKeys.forEach((key) => { - newAnnotations[key] = oldAnnotations[key] - }) - - Object.keys(taskParameters).forEach((tpk) => { - newAnnotations[`params.stash.appscode.com/${tpk}`] = taskParameters[tpk] - }) - - commit('wizard/model$update', { - path: '/resources/kubedbComPgpool/metadata/annotations', - value: newAnnotations, - }) -} - -function isValueExistInModel({ model, getValue }, path) { - const modelValue = getValue(model, path) - return !!modelValue -} - -function onNamespaceChange({ commit, model, getValue }) { - const namespace = getValue(model, '/metadata/release/namespace') - const agent = getValue(model, '/resources/kubedbComPgpool/spec/monitor/agent') - if (agent === 'prometheus.io') { + function setControlledResources(type) { + const list = ['cpu', 'memory'] + const path = `/resources/autoscalingKubedbComPgpoolAutoscaler/spec/compute/${type}/controlledResources` commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', - value: [namespace], + path: path, + value: list, force: true, }) + return list } -} -function onLabelChange({ commit, model, getValue }) { - const labels = getValue(model, '/resources/kubedbComPgpool/spec/metadata/labels') + function setTrigger(path) { + let value = getValue(model, `/resources/${path}`) + if (value) return value + return 'On' + } - const agent = getValue(model, '/resources/kubedbComPgpool/spec/monitor/agent') + function onTriggerChange(path) { + const value = getValue(discriminator, `/temp/${path}/trigger`) + const modelPath = `/resources/autoscalingKubedbComPgpoolAutoscaler/spec/${path}/trigger` - if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, + path: modelPath, + value: value === 'On' ? 'On' : 'Off', force: true, }) } -} -function onNameChange({ commit, model, getValue }) { - const dbName = getValue(model, '/metadata/release/name') + function setApplyToIfReady() { + return 'IfReady' + } - const agent = getValue(model, '/resources/kubedbComPgpool/spec/monitor/agent') + async function fetchTopologyMachines() { + const instance = hasAnnotations() - const labels = getValue(model, '/resources/kubedbComPgpool/spec/metadata/labels') + 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) - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) + const nodeGroups = resp.data?.spec?.nodeGroups || [] + setDiscriminatorValue('/topologyMachines', nodeGroups) + return nodeGroups + } catch (e) { + console.log(e) + return [] + } + } } - const scheduleBackup = getValue(model, '/resources/stashAppscodeComBackupConfiguration') - - if (scheduleBackup) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_repo') - if (creatingNewRepo) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: `${dbName}-repo`, - force: true, - }) + function setAllowedMachine(type, minmax) { + // For pgpool, the instance format is stored as: "min,max" or as a JSON object like {"pgpool": "min,max"} + let instanceValue = instance + try { + const parsed = JSON.parse(instance) + instanceValue = parsed[type] + } catch (e) { + // If not JSON, use as-is } - } - const prePopulateDatabase = getValue(model, '/resources/stashAppscodeComRestoreSession_init') + const mx = instanceValue?.includes(',') ? instanceValue.split(',')[1] : '' + const mn = instanceValue?.includes(',') ? instanceValue.split(',')[0] : '' + const machineName = minmax === 'min' ? mn : mx - if (prePopulateDatabase) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_init_repo') - if (creatingNewRepo) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: `${dbName}-init-repo`, - force: true, - }) - } - } + // Find the machine details from topologyMachines + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] + const machineData = nodeGroups.find((item) => item.topologyValue === machineName) - // to reset configSecret name field - const hasSecretConfig = getValue(model, '/resources/secret_config') - if (hasSecretConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComPgpool/spec/configSecret/name', - value: `${dbName}-config`, - force: true, - }) + // 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: '', + } } - // to reset shard configSecret name field - const hasSecretShardConfig = getValue(model, '/resources/secret_shard_config') - if (hasSecretShardConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComPgpool/spec/shardTopology/shard/configSecret/name', - value: `${dbName}-shard-config`, - force: true, - }) - } + function getMachines(type, minmax) { + // watchDependency('discriminator#/topologyMachines') + const depends = minmax === 'min' ? 'max' : 'min' + const dependantPath = `/allowedMachine-${type}-${depends}` - // to reset shard configSecret name field - const hasSecretConfigServerConfig = getValue(model, '/resources/secret_configserver_config') - if (hasSecretConfigServerConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComPgpool/spec/shardTopology/configServer/configSecret/name', - value: `${dbName}-configserver-config`, - force: true, - }) - } + // watchDependency(`discriminator#${dependantPath}`) + const dependantMachineObj = getValue(discriminator, dependantPath) + const dependantMachine = dependantMachineObj?.machine || '' - // to reset mongos configSecret name field - const hasSecretMongosConfig = getValue(model, '/resources/secret_mongos_config') - if (hasSecretMongosConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComPgpool/spec/shardTopology/mongos/configSecret/name', - value: `${dbName}-mongos-config`, - force: true, - }) - } -} + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] -function returnFalse() { - return false -} + const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) -function onAgentChange({ commit, model, getValue }) { - const agent = getValue(model, '/resources/kubedbComPgpool/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', - value: [], - force: true, + // 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, + }, + } }) - onNamespaceChange({ commit, model, getValue }) - onLabelChange({ commit, model, getValue }) - } else { - commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') - } -} - -/************************************* Database Secret Section ********************************************/ + const filteredMachine = machines?.filter((item, ind) => + minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, + ) -function getCreateAuthSecret({ model, getValue }) { - const authSecret = getValue(model, '/resources/kubedbComPgpool/spec/authSecret') + return dependantIndex === -1 ? machines : filteredMachine + } - return !authSecret -} + function hasAnnotations() { + const annotations = + getValue(model, '/resources/autoscalingKubedbComPgpoolAutoscaler/metadata/annotations') || {} + const instance = annotations['kubernetes.io/instance-type'] -function showExistingSecretSection({ getValue, watchDependency, discriminator }) { - watchDependency('discriminator#/createAuthSecret') - const hasAuthSecretName = getValue(discriminator, '/createAuthSecret') - return !hasAuthSecretName -} + return !!instance + } -function showPasswordSection({ getValue, watchDependency, discriminator }) { - return !showExistingSecretSection({ - getValue, - watchDependency, - discriminator, - }) -} + function hasNoAnnotations() { + return !hasAnnotations() + } -function setAuthSecretPassword({ model, getValue }) { - const encodedPassword = getValue(model, '/resources/secret_auth/data/password') - return encodedPassword ? decodePassword({}, encodedPassword) : '' -} + function onMachineChange(type) { + const annoPath = '/resources/autoscalingKubedbComPgpoolAutoscaler/metadata/annotations' + const annotations = getValue(model, annoPath) || {} + const instance = annotations['kubernetes.io/instance-type'] -function onAuthSecretPasswordChange({ getValue, discriminator, commit }) { - const stringPassword = getValue(discriminator, '/password') + // Now discriminator values are objects with { machine, cpu, memory } + const minMachineObj = getValue(discriminator, `/allowedMachine-${type}-min`) + const maxMachineObj = getValue(discriminator, `/allowedMachine-${type}-max`) + const minMachine = minMachineObj?.machine || '' + const maxMachine = maxMachineObj?.machine || '' + const minMaxMachine = `${minMachine},${maxMachine}` - if (stringPassword) { - commit('wizard/model$update', { - path: '/resources/secret_auth/data/password', - value: encodePassword({}, stringPassword), - force: true, - }) - commit('wizard/model$update', { - path: '/resources/secret_auth/data/username', - value: encodePassword({}, 'root'), - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/secret_auth') - } -} + // Store as JSON object like MongoDB: {"pgpool": "min,max"} + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + // If not JSON, treat as pgpool value + parsedInstance = {} + } -function disableInitializationSection({ model, getValue, watchDependency }) { - const initialized = getValue(model, '/resources/kubedbComPgpool/spec/init/initialized') - watchDependency('model#/resources/kubedbComPgpool/spec/init/initialized') - return !!initialized -} + parsedInstance[type] = minMaxMachine + annotations['kubernetes.io/instance-type'] = JSON.stringify(parsedInstance) -// eslint-disable-next-line no-empty-pattern -function encodePassword({}, value) { - return btoa(value) -} + // 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/autoscalingKubedbComPgpoolAutoscaler/spec/compute/${type}` -// eslint-disable-next-line no-empty-pattern -function decodePassword({}, value) { - return atob(value) -} + if (minMachine && maxMachine) { + 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 onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/resources/kubedbComPgpool/spec/authSecret') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/resources/secret_auth') + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value } -} -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - if (owner && cluster && namespace) { try { const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, { - params: { - filter: { - items: { - data: { username: null, password: null }, - metadata: { name: null }, - type: null, - }, - }, - }, + params: { filter: { items: { metadata: { name: null } } } }, }, ) - const secrets = (resp && resp.data && resp.data.items) || [] - - const filteredSecrets = secrets.filter((item) => { - const validType = [ - 'kubernetes.io/service-account-token', - 'Opaque', - 'kubernetes.io/basic-auth', - ] - return validType.includes(item.type) - }) + const resources = (resp && resp.data && resp.data.items) || [] - filteredSecrets.map((item) => { + resources.map((item) => { const name = (item.metadata && item.metadata.name) || '' item.text = name item.value = name return true }) - return filteredSecrets + return resources } catch (e) { console.log(e) + return [] } } - return [] -} -//////////////////// custom config ///////////////// -function onConfigurationSourceChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSource') - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_config') - } else { - const value = getValue(model, '/resources/secret_config') - if (!value) { + /****** 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/secret_config', + path: '/resources/kubedbComPgpool/spec/monitor', value: {}, force: true, }) + } else { + commit('wizard/model$delete', '/resources/kubedbComPgpool/spec/monitor') } - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: '/resources/kubedbComPgpool/spec/configSecret/name', - value: configSecretName, + path: '/form/alert/enabled', + value: configureStatus ? 'warning' : 'none', force: true, }) } -} - -function onConfigurationChange({ getValue, commit, discriminator, model }) { - const value = getValue(discriminator, '/configuration') - commit('wizard/model$update', { - path: '/resources/secret_config/stringData/user.conf', - value: value, - force: true, - }) - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComPgpool/spec/configSecret/name', - value: configSecretName, - force: true, - }) -} - -function onConfigurationChangeEdit({ getValue, commit, discriminator, model }) { - const value = getValue(discriminator, '/configuration') - - commit('wizard/model$update', { - path: '/resources/secret_config/data/pgpool.ini', - value: btoa(value), - force: true, - }) - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComPgpool/spec/configSecret/name', - value: configSecretName, - force: true, - }) -} -function setConfigurationSource({ model, getValue }) { - const modelValue = getValue(model, '/resources/secret_config') - if (modelValue) { - return 'create-new-config' + function showCustomizeExporterSection() { + // watchDependency('discriminator#/customizeExporter') + const configureStatus = getValue(discriminator, '/customizeExporter') + return configureStatus } - return 'use-existing-config' -} - -function setSecretConfigNamespace({ getValue, model, watchDependency }) { - watchDependency('model#/metadata/release/namespace') - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} - -function setConfiguration({ model, getValue }) { - return getValue(model, '/resources/secret_config/stringData/user.conf') -} - -function setConfigurationForEdit({ model, getValue }) { - const value = getValue(model, '/resources/secret_config/data/pgpool.ini') - return atob(value) -} - -function setConfigurationFiles({ model, getValue }) { - const value = getValue(model, '/resources/secret_config/data/user.conf') - return atob(value) -} -function onSetCustomConfigChange({ discriminator, getValue, commit }) { - const value = getValue(discriminator, '/setCustomConfig') - - if (value === 'no') { - commit('wizard/model$delete', '/resources/kubedbComPgpool/spec/configSecret') - commit('wizard/model$delete', '/resources/secret_config') + function onCustomizeExporterChange() { + const configureStatus = getValue(discriminator, '/customizeExporter') + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComPgpool/spec/monitor/prometheus/exporter', + value: {}, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/kubedbComPgpool/spec/monitor/prometheus/exporter') + } } -} - -function getOpsRequestUrl({ storeGet, model, getValue, mode }, 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 + `/create-opsrequest-${reqType.toLowerCase()}?namespace=${namespace}` - - if (mode === 'standalone-step') return pathConstructedForKubedb - else - return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/pgpoolopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` -} - -const getAppbinding = async ({ axios, storeGet, getValue, watchDependency, rootModel }) => { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const group = 'appcatalog.appscode.com' - const version = 'v1alpha1' - const resource = 'appbindings' - - watchDependency('rootModel#/databaseRef/namespace') - - const namespace = getValue(rootModel, '/databaseRef/namespace') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}`, - { - params: { - filter: { items: { metadata: { name: null }, type: 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 -} - -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} - -function onRefChange({ discriminator, getValue, commit }) { - const ref = getValue(discriminator, '/pgRef') || {} - commit('wizard/model$update', { - path: '/resources/kubedbComPgpool/spec/database/databaseRef/name', - value: ref.name || '', - force: true, - }) - commit('wizard/model$update', { - path: '/resources/kubedbComPgpool/spec/database/databaseRef/namespace', - value: ref.namespace || '', - force: true, - }) -} - -async function getAppBindings({ axios, storeGet }, type) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const queryParams = { - filter: { - items: { - metadata: { name: null, namespace: null }, - spec: { type: null }, - }, - }, + function isValueExistInModel(path) { + const modelValue = getValue(model, path) || null + return !!modelValue } - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/appcatalog.appscode.com/v1alpha1/appbindings`, - queryParams, - ) - const resources = (resp && resp.data && resp.data.items) || [] - const fileredResources = resources - .filter((item) => item.spec?.type === `kubedb.com/${type}`) - .map((item) => { - const name = item.metadata?.name || '' - const namespace = item.metadata?.namespace || '' - return { - text: `${namespace}/${name}`, - value: { - name: name, - namespace: namespace, - }, - } - }) - return fileredResources - } catch (e) { - console.log(e) - return [] - } -} + // function onNamespaceChange() { + // const namespace = getValue(model, '/metadata/release/namespace') + // const agent = getValue(model, '/resources/kubedbComPgpool/spec/monitor/agent') + // if (agent === 'prometheus.io') { + // commit('wizard/model$update', { + // path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + // value: [namespace], + // force: true, + // }) + // } + // } -///////////////////////// Autoscaler /////////////////// -let autoscaleType = '' -let dbDetails = {} + function onLabelChange() { + const labels = getValue(model, '/resources/kubedbComPgpool/spec/metadata/labels') -function isConsole({ storeGet, commit }) { - const isKube = isKubedb({ storeGet }) + const agent = getValue(model, '/resources/kubedbComPgpool/spec/monitor/agent') - if (isKube) { - const dbName = storeGet('/route/params/name') || '' - commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComPgpoolAutoscaler/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/autoscalingKubedbComPgpoolAutoscaler/metadata/name', - value: modifiedName, - force: true, - }) - const namespace = storeGet('/route/query/namespace') || '' - if (namespace) { + if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComPgpoolAutoscaler/metadata/namespace', - value: namespace, + path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', + value: labels, force: true, }) } } - return !isKube -} - -function isKubedb({ storeGet }) { - return !!storeGet('/route/params/actions') -} + function onAgentChange() { + const agent = getValue(model, '/resources/kubedbComPgpool/spec/monitor/agent') + if (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', + value: [], + force: true, + }) -function showOpsRequestOptions({ model, getValue, watchDependency, storeGet, discriminator }) { - if (isKubedb({ storeGet }) === true) return true - watchDependency('model#/resources/autoscalingKubedbComPgpoolAutoscaler/spec/databaseRef/name') - watchDependency('discriminator#/autoscalingType') - return ( - !!getValue(model, '/resources/autoscalingKubedbComPgpoolAutoscaler/spec/databaseRef/name') && - !!getValue(discriminator, '/autoscalingType') - ) -} + onNamespaceChange() + onLabelChange() + } else { + commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') + } + } -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + 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}` -async function getNamespaces({ axios, storeGet }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + const isKube = !!storeGet('/route/params/actions') - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + if (isKube) return pathConstructedForKubedb + else + return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/pgpoolopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` + } - const resources = (resp && resp.data && resp.data.items) || [] + function onNamespaceChange() { + const namespace = getValue( + model, + '/resources/autoscalingKubedbComPgpoolAutoscaler/metadata/namespace', + ) + if (!namespace) { + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComPgpoolAutoscaler/spec/databaseRef/name', + ) + } + } - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, + function setValueFrom() { + if (isConfigMapTypeValueFrom()) { + return 'configMap' + } else if (isSecretTypeValueFrom()) { + return 'secret' + } else { + return 'input' } - }) -} + } -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - watchDependency('model#/resources/autoscalingKubedbComPgpoolAutoscaler/metadata/namespace') - const namespace = getValue( - model, - '/resources/autoscalingKubedbComPgpoolAutoscaler/metadata/namespace', - ) - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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, + }) + } + } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + // function isEqualToValueFromType(value) { + // //watchDependency('discriminator#/valueFromType') + // const valueFrom = getValue(discriminator, '/valueFromType') + // return valueFrom === value + // } - const resources = (resp && resp.data && resp.data.items) || [] + async function getNamespacedResourceList( + axios, + storeGet, + { namespace, group, version, resource }, + ) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` -async function getDbDetails({ commit, setDiscriminatorValue, axios, storeGet, getValue, model }) { - const owner = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - const namespace = - storeGet('/route/query/namespace') || - getValue(model, '/resources/autoscalingKubedbComPgpoolAutoscaler/metadata/namespace') || - '' - const name = - storeGet('/route/params/name') || - getValue(model, '/resources/autoscalingKubedbComPgpoolAutoscaler/spec/databaseRef/name') || - '' - - if (namespace && name) { + let ans = [] try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/pgpools/${name}`, - ) - dbDetails = resp.data || {} - setDiscriminatorValue('/dbDetails', true) + 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) } - } - - commit('wizard/model$update', { - path: `/metadata/release/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/metadata/release/namespace`, - value: namespace, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComPgpoolAutoscaler/spec/databaseRef/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComPgpoolAutoscaler/metadata/labels`, - value: dbDetails.metadata.labels, - force: true, - }) -} - -async function dbTypeEqualsTo({ watchDependency, commit }, type) { - watchDependency('discriminator#/dbDetails') - const { spec } = dbDetails || {} - const { topology } = spec || {} - let verd = '' - if (topology) verd = 'topology' - else { - verd = 'combined' + return ans } - clearSpecModel({ commit }, verd) - return type === verd && spec -} -function clearSpecModel({ commit }, dbtype) { - if (dbtype === 'standalone') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComPgpoolAutoscaler/spec/${autoscaleType}/cluster`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComPgpoolAutoscaler/spec/${autoscaleType}/sentinel`, - ) - } else if (dbtype === 'cluster') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComPgpoolAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComPgpoolAutoscaler/spec/${autoscaleType}/sentinel`, - ) - } else if (dbtype === 'sentinel') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComPgpoolAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComPgpoolAutoscaler/spec/${autoscaleType}/cluster`, - ) - } -} + async function resourceNames(group, version, resource) { + const namespace = getValue(model, '/metadata/release/namespace') + // watchDependency('model#/metadata/release/namespace') -function initMetadata({ getValue, discriminator, model, commit, storeGet }) { - const dbName = - getValue(model, '/resources/autoscalingKubedbComPgpoolAutoscaler/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/autoscalingKubedbComPgpoolAutoscaler/metadata/name', - value: modifiedName, - force: true, + let resources = await getNamespacedResourceList(axios, storeGet, { + namespace, + group, + version, + resource, }) - // delete the other type object from model - if (type === 'compute') - commit('wizard/model$delete', '/resources/autoscalingKubedbComPgpoolAutoscaler/spec/storage') - if (type === 'storage') - commit('wizard/model$delete', '/resources/autoscalingKubedbComPgpoolAutoscaler/spec/compute') -} - -function onNamespaceChange({ model, getValue, commit }) { - const namespace = getValue( - model, - '/resources/autoscalingKubedbComPgpoolAutoscaler/metadata/namespace', - ) - if (!namespace) { - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComPgpoolAutoscaler/spec/databaseRef/name', - ) - } -} - -function ifScalingTypeEqualsTo( - { storeGet, watchDependency, getValue, discriminator, model }, - type, -) { - watchDependency('discriminator#/autoscalingType') - watchDependency('model#/resources/autoscalingKubedbComPgpoolAutoscaler/spec/databaseRef/name') - - const operation = storeGet('/route/params/actions') || '' - if (operation.length) { - const splitOp = operation.split('-') - if (splitOp.length > 2) autoscaleType = splitOp[2] - } else autoscaleType = getValue(discriminator, '/autoscalingType') || '' - const isDatabaseSelected = !!getValue( - model, - '/resources/autoscalingKubedbComPgpoolAutoscaler/spec/databaseRef/name', - ) - return autoscaleType === type && isDatabaseSelected -} + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } -async function fetchNodeTopology({ axios, storeGet }) { - 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 resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } }) - return mappedList - } catch (e) { - console.log(e) } - return [] -} -function isNodeTopologySelected({ watchDependency, model, getValue }) { - watchDependency( - 'model#/resources/autoscalingKubedbComPgpoolAutoscaler/spec/compute/nodeTopology/name', - ) - const nodeTopologyName = - getValue( + 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/autoscalingKubedbComPgpoolAutoscaler/spec/compute/nodeTopology/name', - ) || '' - return !!nodeTopologyName.length -} + `/resources/kubedbComPgpool/spec/monitor/prometheus/exporter/env/${index}/valueFrom/configMapKeyRef/name`, + ) -function setControlledResources({ commit }, type) { - const list = ['cpu', 'memory'] - const path = `/resources/autoscalingKubedbComPgpoolAutoscaler/spec/compute/${type}/controlledResources` - commit('wizard/model$update', { - path: path, - value: list, - force: true, - }) - return list -} + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/configMapKeyRef/name') -function setTrigger({ model, getValue }, path) { - let value = getValue(model, `/resources/${path}`) - if (value) return value - return 'On' -} + if (!configMapName) return [] -function setApplyToIfReady() { - return 'IfReady' -} + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/configmaps/${configMapName}`, + ) -function handleUnit({ commit, model, getValue }, 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, - }) - } - } -} + const configMaps = (resp && resp.data && resp.data.data) || {} -function setMetadata({ storeGet, mode, commit }) { - const dbname = storeGet('/route/params/name') || '' - const namespace = storeGet('/route/query/namespace') || '' - if (mode === 'standalone-step') { - commit('wizard/model$update', { - path: '/metadata/release/name', - value: dbname, - force: true, - }) - commit('wizard/model$update', { - path: '/metadata/release/namespace', - value: namespace, - force: true, - }) + const configMapKeys = Object.keys(configMaps).map((item) => ({ + text: item, + value: item, + })) + + return configMapKeys + } catch (e) { + console.log(e) + return [] + } } -} -async function fetchTopologyMachines({ axios, getValue, storeGet, model, setDiscriminatorValue }) { - const instance = hasAnnotations({ model, getValue }) + 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') - 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 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) + }) - const nodeGroups = resp.data?.spec?.nodeGroups || [] - setDiscriminatorValue('/topologyMachines', nodeGroups) - return nodeGroups + 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 [] } } -} - -function setAllowedMachine({ model, getValue }, minmax) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComPgpoolAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - const mx = instance?.includes(',') ? instance.split(',')[1] : '' - const mn = instance?.includes(',') ? instance.split(',')[0] : '' - - if (minmax === 'min') return mn - else return mx -} -async function getMachines({ getValue, watchDependency, discriminator }, minmax) { - watchDependency('discriminator#/topologyMachines') - const depends = minmax === 'min' ? 'max' : 'min' - const dependantPath = `/allowedMachine-${depends}` - - watchDependency(`discriminator#${dependantPath}`) - const dependantMachine = getValue(discriminator, dependantPath) + 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/kubedbComPgpool/spec/monitor/prometheus/exporter/env/${index}/valueFrom/secretKeyRef/name`, + ) - const nodeGroups = getValue(discriminator, '/topologyMachines') || [] + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/secretKeyRef/name') - const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) + if (!secretName) return [] - const machines = nodeGroups?.map((item) => { - const subText = `CPU: ${item.allocatable.cpu}, Memory: ${item.allocatable.memory}` - const text = item.topologyValue - return { text, subText, value: item.topologyValue } - }) + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets/${secretName}`, + ) - const filteredMachine = machines?.filter((item, ind) => - minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, - ) + const secret = (resp && resp.data && resp.data.data) || {} - return dependantIndex === -1 ? machines : filteredMachine -} + const secretKeys = Object.keys(secret).map((item) => ({ + text: item, + value: item, + })) -function hasAnnotations({ model, getValue }) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComPgpoolAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] + return secretKeys + } catch (e) { + console.log(e) + return [] + } + } - return !!instance -} + function returnFalse() { + return false + } + + 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 + }) -function hasNoAnnotations({ model, getValue }) { - return !hasAnnotations({ model, getValue }) -} + if (filteredEnv.length) + commit('wizard/model$update', { + path: '/resources/kubedbComPgpool/spec/monitor/prometheus/exporter/env', + value: filteredEnv, + force: true, + }) + } -function onMachineChange({ model, getValue, discriminator, commit }, type) { - const annoPath = '/resources/autoscalingKubedbComPgpoolAutoscaler/metadata/annotations' - const annotations = getValue(model, annoPath) - const instance = annotations['kubernetes.io/instance-type'] + function initEnvArray() { + const env = getValue(model, '/resources/kubedbComPgpool/spec/monitor/prometheus/exporter/env') - const minMachine = getValue(discriminator, '/allowedMachine-min') - const maxMachine = getValue(discriminator, '/allowedMachine-max') - const minMaxMachine = `${minMachine},${maxMachine}` - annotations['kubernetes.io/instance-type'] = minMaxMachine + return env || [] + } - const machines = getValue(discriminator, `/topologyMachines`) || [] - const minMachineObj = machines.find((item) => item.topologyValue === minMachine) - const maxMachineObj = machines.find((item) => item.topologyValue === maxMachine) - const minMachineAllocatable = minMachineObj?.allocatable - const maxMachineAllocatable = maxMachineObj?.allocatable - const allowedPath = `/resources/autoscalingKubedbComPgpoolAutoscaler/spec/compute/${type}` + function isEqualToTemp(value, index) { + //watchDependency('discriminator#/valueFromType') + const valueFrom = getValue(discriminator, `/env/${index}/temp/valueFromType`) + return valueFrom === value + } - 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 initMonitoring() { + const env = + getValue(model, '/resources/kubedbComPgpool/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 { - setMetadata, - isRancherManaged, - handleUnit, - isConsole, - getNamespaces, - getDbs, - isKubedb, - getDbDetails, - dbTypeEqualsTo, - clearSpecModel, - initMetadata, - onNamespaceChange, - ifScalingTypeEqualsTo, - fetchNodeTopology, - isNodeTopologySelected, - setControlledResources, - setTrigger, - setApplyToIfReady, - showOpsRequestOptions, - isVariantAvailable, - fetchJsons, - getAppbinding, - onDatabaseModeChange, - setDatabaseMode, - disableLableChecker, - isEqualToModelPathValue, - getResources, - isEqualToDiscriminatorPath, - setValueFromModel, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - returnTrue, - returnStringYes, - setAddressType, - getPgpoolVersions, - isEqualToDatabaseMode, - setApiGroup, - getIssuerRefsName, - hasIssuerRefName, - hasNoIssuerRefName, - setSSLMode, - showTlsConfigureSection, - onTlsConfigureChange, - getAliasOptions, - showMonitoringSection, - onEnableMonitoringChange, - showCustomizeExporterSection, - onCustomizeExporterChange, - valueExists, - onConfigurationChangeEdit, - setConfigurationForEdit, - initPrePopulateDatabase, - onPrePopulateDatabaseChange, - initDataSource, - onDataSourceChange, - initVolumeType, - onVolumeTypeChange, - showInitializationForm, - showScriptOrStashForm, - showConfigMapOrSecretName, - initializeNamespace, - showRepositorySelectOrCreate, - onInitRepositoryChoiseChange, - initCustomizeRestoreJobRuntimeSettings, - initCustomizeRestoreJobRuntimeSettingsForBackup, - onCustomizeRestoreJobRuntimeSettingsChange, - onCustomizeRestoreJobRuntimeSettingsChangeForBackup, - showRuntimeForm, - getImagePullSecrets, - getBackupConfigsAndAnnotations, - deleteKubeDbComPgpoolDbAnnotation, - addKubeDbComPgpoolDbAnnotation, - initScheduleBackup, - initScheduleBackupForEdit, - onScheduleBackupChange, - showBackupForm, - initBackupInvoker, - onBackupInvokerChange, - showInvokerForm, - initalizeTargetReferenceName, - setInitialRestoreSessionRepo, - initRepositoryChoise, - initRepositoryChoiseForEdit, - setConfigurationForEdit, - onRepositoryChoiseChange, - onRepositoryNameChange, - getMongoAnnotations, - initFromAnnotationValue, - onBackupBlueprintNameChange, - onBackupBlueprintScheduleChange, - initFromAnnotationKeyValue, - onTaskParametersChange, - isValueExistInModel, - onNamespaceChange, - onLabelChange, - onNameChange, - returnFalse, - onAgentChange, - getCreateAuthSecret, - showExistingSecretSection, - showPasswordSection, - setAuthSecretPassword, - onAuthSecretPasswordChange, - disableInitializationSection, - encodePassword, - decodePassword, - onCreateAuthSecretChange, - getSecrets, - onConfigurationSourceChange, - onConfigurationChange, - setConfigurationSource, - setSecretConfigNamespace, - setConfiguration, - setConfigurationFiles, - onSetCustomConfigChange, - getOpsRequestUrl, - onRefChange, - getAppBindings, - getMachines, - setAllowedMachine, - hasAnnotations, - hasNoAnnotations, - fetchTopologyMachines, - onMachineChange, + return { + isConsole, + isKubedb, + showOpsRequestOptions, + isRancherManaged, + getNamespaces, + getDbs, + getDbDetails, + initMetadata, + onNamespaceChange, + fetchNodeTopology, + isNodeTopologySelected, + setControlledResources, + setTrigger, + setApplyToIfReady, + fetchTopologyMachines, + setAllowedMachine, + getMachines, + hasAnnotations, + hasNoAnnotations, + onMachineChange, + onTriggerChange, + + getOpsRequestUrl, + isValueExistInModel, + onEnableMonitoringChange, + showMonitoringSection, + onAgentChange, + getResources, + isEqualToModelPathValue, + onCustomizeExporterChange, + showCustomizeExporterSection, + onLabelChange, + setValueFrom, + onValueFromChange, + resourceNames, + getConfigMapKeys, + getSecrets, + getSecretKeys, + isConfigMapTypeValueFrom, + isSecretTypeValueFrom, + getNamespacedResourceList, + returnFalse, + onEnvArrayChange, + initEnvArray, + isEqualToTemp, + initMonitoring, + } } diff --git a/charts/kubedbcom-postgres-editor-options/ui/create-ui.yaml b/charts/kubedbcom-postgres-editor-options/ui/create-ui.yaml index 0958a1de7e..251833b5cd 100644 --- a/charts/kubedbcom-postgres-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-postgres-editor-options/ui/create-ui.yaml @@ -1,414 +1,430 @@ -steps: -- form: - discriminator: - bundleApiLoaded: - default: false - type: boolean - elements: - - computed: initBundle - if: returnFalse - type: label-element - - disableUnselect: true - fetch: getAdminOptions|databases/Postgres/versions - if: isToggleOn|databases/Postgres/versions - label: - text: labels.database.version - schema: - $ref: schema#/properties/spec/properties/admin/properties/databases/properties/Postgres/properties/versions/properties/default +step: +- type: single-step-form + loader: initBundle + elements: + - type: label-element + label: '' + subtitle: Select the Postgres version you want to deploy on Kubernetes. The chosen version determines the Postgres engine features, compatibility, and runtime behavior of your database cluster. + - disableUnselect: false + loader: getAdminOptions|databases/Postgres/versions + if: + type: function + name: isToggleOn|databases/Postgres/versions + label: Database Version + schema: schema/properties/spec/properties/admin/properties/databases/properties/Postgres/properties/versions/properties/default + type: select + - init: + type: func + value: getDefault|databases/Postgres/mode + loader: getAdminOptions|databases/Postgres/mode + if: + type: function + name: isToggleOn|databases/Postgres/mode + label: Database Mode + isHorizontal: true + watcher: + func: clearArbiterHidden + paths: + - schema/properties/spec/properties/mode + schema: schema/properties/spec/properties/mode + type: radio + - if: + type: function + name: EqualToDatabaseMode|Cluster + label: Replicas + schema: schema/properties/spec/properties/replicas + type: input + - elements: + - type: label-element + label: '' + subtitle: Configure a remote replica to replicate data from an external PostgreSQL source. Select the source database binding for asynchronous replication across clusters or regions. + - loader: getAppBindings + label: RemoteReplica SourceRef + validation: + type: required + schema: schema/properties/spec/properties/remoteReplica/properties/sourceRef type: select - - computed: getDefault|databases/Postgres/mode - fetch: getAdminOptions|databases/Postgres/mode - hasDescription: true - if: isToggleOn|databases/Postgres/mode - label: - text: labels.database.mode - onChange: clearArbiterHidden - schema: - $ref: schema#/properties/spec/properties/mode - type: radio - - if: EqualToDatabaseMode|Cluster - label: - text: labels.replicas - schema: - $ref: schema#/properties/spec/properties/replicas - type: input - - elements: - - fetch: getAppBindings - label: - text: RemoteReplica SourceRef - required: true - schema: - $ref: schema#/properties/spec/properties/remoteReplica/properties/sourceRef - type: select - if: EqualToDatabaseMode|RemoteReplica - type: single-step-form + if: + type: function + name: EqualToDatabaseMode|RemoteReplica + type: block-layout + - elements: + - type: label-element + label: '' + subtitle: Select a machine profile to allocate CPU and memory resources for your database. Choose 'custom' to manually specify resource requirements or select a predefined profile. + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: CPU + loader: setLimits|cpu + watcher: + func: setRequests|cpu + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: Memory + loader: setLimits|memory + watcher: + func: setRequests|memory + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + label: Machine Profile + showLabels: true + type: block-layout + - elements: + - type: horizontal-layout + showLabels: true + customClass: mb-16 + elements: + - loader: getAdminOptions|storageClasses + if: + type: function + name: isToggleOn|storageClasses + label: Storage Class + validation: + type: required + schema: schema/properties/spec/properties/admin/properties/storageClasses/properties/default + type: select + - if: + type: function + name: showStorageSizeField + label: Storage Size + schema: schema/properties/spec/properties/persistence/properties/size + type: input + type: block-layout + - description: Configure Credentials, Deployment Mode etc. + elements: - elements: - - computed: setMachineToCustom - customClass: mt-10 - fetch: getMachineListForOptions - label: - text: labels.machine - schema: - $ref: schema#/properties/spec/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.cpu - onChange: setRequests|cpu - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.memory - onChange: setRequests|memory - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - label: - text: labels.machine_profile - show_label: true - type: single-step-form - - fetch: getAdminOptions|storageClasses - if: isToggleOn|storageClasses - label: - text: labels.storage.class - required: true - schema: - $ref: schema#/properties/spec/properties/admin/properties/storageClasses/properties/default + - type: label-element + label: '' + subtitle: Add custom labels and annotations to your database resources for organization, monitoring, and integration with other Kubernetes tools and services. + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/annotations + label: Labels & Annotations + showLabels: true + type: block-layout + - init: + type: func + value: getDefault|deletionPolicy + customClass: mt-20 + if: + type: function + name: isToggleOn|deletionPolicy + label: Deletion Policy + watcher: + func: setStorageClass + paths: + - schema/properties/spec/properties/deletionPolicy + options: + - description: options.deletionPolicy.delete.description + text: Delete + value: Delete + - description: options.deletionPolicy.halt.description + text: Halt + value: Halt + - description: options.deletionPolicy.wipeOut.description + text: WipeOut + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: DoNotTerminate + value: DoNotTerminate + schema: schema/properties/spec/properties/deletionPolicy type: select - - if: showStorageSizeField - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/persistence/properties/size + - if: + type: function + name: getDefaultValue|spec/admin/authCredential/customize + label: Provide Authentication Credentials? + watcher: + func: onAuthChange + paths: + - temp/createAuthSecret + schema: temp/createAuthSecret + type: switch + - if: + type: function + name: showReferSecretSwitch + label: Refer existing Secret? + watcher: + func: onReferSecretChange + paths: + - temp/referSecret + schema: temp/referSecret + type: switch + - loader: getReferSecrets + if: + type: function + name: showSecretDropdown + label: Secret + schema: schema/properties/spec/properties/authSecret/properties/name + type: select + - if: + type: function + name: showReferSecret + label: Password + schema: schema/properties/spec/properties/authSecret/properties/password type: input - - accordion: true - description: - text: Configure Credentials, Deployment Mode etc. - discriminator: - configDatabase: - default: false - type: boolean - createAuthSecret: - default: false - type: boolean - recovery: - default: false - type: boolean - referSecret: - default: false - type: boolean - elements: - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties + - if: + type: function + name: getDefaultValue|spec/admin/customConfiguration + label: Configure Database? + watcher: + func: clearConfiguration + paths: + - temp/configDatabase + schema: temp/configDatabase + type: switch + - if: + type: function + name: isConfigDatabaseOn + label: Configuration + schema: schema/properties/spec/properties/configuration + type: editor + - init: + type: func + value: getDefault|pointInTimeRecovery + if: + type: function + name: isToggleOn|pointInTimeRecovery + label: Point in-time Recovery? + schema: temp/recovery + type: switch + - elements: + - type: label-element + label: '' + subtitle: Restore your database to a specific point in time by specifying the source database namespace, name, and the exact recovery timestamp for data restoration. + - type: horizontal-layout + showLabels: true + elements: + - label: Namespace + watcher: + func: setPointInTimeRecovery + paths: + - temp/refNamespace + forceRequired: true + validation: + type: required + schema: temp/refNamespace type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties + - label: Name + watcher: + func: setPointInTimeRecovery + paths: + - temp/refDBName + validation: + type: required + schema: temp/refDBName type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - computed: getDefault|deletionPolicy - customClass: mt-20 - if: isToggleOn|deletionPolicy - 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/spec/properties/deletionPolicy - type: select - - if: getDefaultValue|spec/admin/authCredential/customize - label: - text: Provide Authentication Credentials? - onChange: onAuthChange - schema: - $ref: discriminator#/createAuthSecret - type: switch - - if: showReferSecretSwitch - label: - text: Refer existing Secret? - onChange: onReferSecretChange - schema: - $ref: discriminator#/referSecret + - label: Recovery Timestamp + schema: schema/properties/spec/properties/init/properties/archiver/properties/recoveryTimestamp + type: date-time + watcher: + func: onTimestampChange + paths: + - schema/properties/spec/properties/init/properties/archiver/properties/recoveryTimestamp + if: + type: function + name: showRecovery + label: Point in-time Recovery + showLabels: true + type: block-layout + - if: + type: function + name: isToggleOn|deployment + label: Deployment + options: + - description: labels.deployment.shared + text: Shared + value: Shared + - description: labels.deployment.dedicated + text: Dedicated + value: Dedicated + schema: schema/properties/spec/properties/admin/properties/deployment/properties/default + type: radio + - if: + type: function + name: isToggleOn|clusterTier + isHorizontal: true + label: Cluster Tier + options: + - text: General Purpose + value: GeneralPurpose + - text: Memory Optimized + value: MemoryOptimized + - text: CPU Optimized + value: CPUOptimized + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/default + type: radio + - disableUnselect: true + loader: getAdminOptions|clusterTier/placement + if: + type: function + name: isToggleOn|clusterTier/placement + label: Placement + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + type: select + - disableUnselect: true + loader: getNodeTopology + if: + type: function + name: isToggleOn|clusterTier/nodeTopology + label: Node Topology + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + type: select + - elements: + - type: horizontal-layout + showLabels: true + elements: + - label: Standby Mode + options: + - text: Hot + value: Hot + - text: Warm + value: Warm + schema: schema/properties/spec/properties/standbyMode + type: select + - label: Streaming Mode + options: + - text: Synchronous + value: Synchronous + - text: Asynchronous + value: Asynchronous + schema: schema/properties/spec/properties/streamingMode + type: select + if: + type: function + name: EqualToDatabaseMode|Cluster + type: block-layout + label: Advanced Configuration + showLabels: true + type: block-layout + - description: Enable Backup, Monitoring, TLS etc. + elements: + - elements: + - init: + type: func + value: setMonitoring + label: Enable Monitoring? + watcher: + func: updateAlertValue + paths: + - temp/monitoring + schema: temp/monitoring type: switch - - fetch: getReferSecrets - if: showSecretDropdown - label: - text: Secret - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/name + - customClass: mt-10 + if: + type: function + name: showAlerts + label: Alert Options + options: + - text: None + value: none + - text: Critical + value: critical + - text: Warning + value: warning + - text: Info + value: info + schema: schema/properties/form/properties/alert/properties/enabled type: select - - if: showReferSecret - label: - text: labels.password - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/password - type: input - - computed: isConfigAvailable - if: getDefaultValue|spec/admin/customConfiguration - label: - text: Configure Database? - onChange: clearConfiguration - schema: - $ref: discriminator#/configDatabase + if: + type: function + name: isToggleOn|monitoring + type: block-layout + - init: + type: func + value: setBackup + if: + type: function + name: isToggleOn|backup + + label: Enable Backup? + watcher: + func: onBackupSwitch + paths: + - temp/backup + schema: temp/backup + type: switch + - elements: + - disable: showArchiverAlert + label: Enable Archiver? + watcher: + func: onArchiverChange + paths: + - schema/properties/spec/properties/admin/properties/archiver/properties/enable/properties/default + schema: schema/properties/spec/properties/admin/properties/archiver/properties/enable/properties/default type: switch - - if: isConfigDatabaseOn - label: - text: Configuration - schema: - $ref: schema#/properties/spec/properties/configuration - type: editor - - computed: getDefault|pointInTimeRecovery - if: isToggleOn|pointInTimeRecovery - label: - text: Point in-time Recovery? - schema: - $ref: discriminator#/recovery + - if: + type: function + name: showArchiverAlert + label: The selected StorageClass does not support Archiver + type: warning + if: + type: function + name: showArchiver + type: block-layout + - elements: + - if: + type: function + name: isToggleOn|tls + label: Enable TLS? + schema: schema/properties/spec/properties/admin/properties/tls/properties/default type: switch - - discriminator: - refDBName: - type: string - refNamespace: - type: string - elements: - - label: - text: Namespace - onChange: setPointInTimeRecovery - required: true - schema: - $ref: discriminator#/refNamespace - type: input - - label: - text: Name - onChange: setPointInTimeRecovery - required: true - schema: - $ref: discriminator#/refDBName - type: input - - customClass: mt-10 - label: - text: Recovery Timestamp - schema: - $ref: schema#/properties/spec/properties/init/properties/archiver/properties/recoveryTimestamp - type: input - if: showRecovery - label: - text: Point in-time Recovery - schema: - $ref: schema#/properties/spec/properties/init/properties/archiver - show_label: true - type: single-step-form - - hasDescription: true - if: isToggleOn|deployment - label: - text: labels.deployment.name - options: - - description: labels.deployment.shared - text: Shared - value: Shared - - description: labels.deployment.dedicated - text: Dedicated - value: Dedicated - schema: - $ref: schema#/properties/spec/properties/admin/properties/deployment/properties/default - type: radio - - if: isToggleOn|clusterTier - isHorizontal: true - label: - text: labels.clusterTier - options: - - text: General Purpose - value: GeneralPurpose - - text: Memory Optimized - value: MemoryOptimized - - text: CPU Optimized - value: CPUOptimized - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/default - type: radio - - disableUnselect: true - fetch: getAdminOptions|clusterTier/placement - if: isToggleOn|clusterTier/placement - label: - text: labels.placement - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default - type: select - - disableUnselect: true - fetch: getNodeTopology - if: isToggleOn|clusterTier/nodeTopology - label: - text: labels.nodeTopology - refresh: true - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default - type: select - - if: EqualToDatabaseMode|Cluster - label: - text: Standby Mode - options: - - text: Hot - value: Hot - - text: Warm - value: Warm - schema: - $ref: schema#/properties/spec/properties/standbyMode - type: select - - if: EqualToDatabaseMode|Cluster - label: - text: Streaming Mode - options: - - text: Synchronous - value: Synchronous - - text: Asynchronous - value: Asynchronous - schema: - $ref: schema#/properties/spec/properties/streamingMode + - loader: getAdminOptions|clusterIssuers + if: + type: function + name: showIssuer + label: Cluster Issuers + validation: + type: required + schema: schema/properties/spec/properties/admin/properties/clusterIssuers/properties/default type: select - hideForm: true - label: - text: Advanced Configuration - show_label: true - type: single-step-form - - accordion: true - description: - text: Enable Backup, Monitoring, TLS etc. - discriminator: - backup: - default: false - type: boolean - elements: - - discriminator: - monitoring: - default: false - type: boolean - elements: - - computed: setMonitoring - label: - text: labels.enable_monitoring - onChange: updateAlertValue - schema: - $ref: discriminator#/monitoring - type: switch - - customClass: mt-10 - if: showAlerts - label: - text: labels.alert.options - options: - - text: None - value: none - - text: Critical - value: critical - - text: Warning - value: warning - - text: Info - value: info - schema: - $ref: schema#/properties/form/properties/alert/properties/enabled - sortable: true - type: select - if: isToggleOn|monitoring - type: single-step-form - - computed: setBackup - if: isToggleOn|backup - label: - text: Enable Backup? - onChange: onBackupSwitch - schema: - $ref: discriminator#/backup + type: block-layout + - elements: + - if: + type: function + name: isToggleOn|expose + label: Expose via Gateway? + schema: schema/properties/spec/properties/admin/properties/expose/properties/default type: switch - - elements: - - disabled: showArchiverAlert - label: - text: Enable Archiver? - onChange: onArchiverChange - schema: - $ref: schema#/properties/spec/properties/admin/properties/archiver/properties/enable/properties/default - type: switch - - alertInfo: - show: true - type: neutral - if: showArchiverAlert - label: - text: The selected StorageClass does not support Archiver - type: label-element - if: showArchiver - type: single-step-form - - elements: - - if: isToggleOn|tls - label: - text: Enable TLS? - schema: - $ref: schema#/properties/spec/properties/admin/properties/tls/properties/default - type: switch - - fetch: getAdminOptions|clusterIssuers - if: showIssuer - label: - text: labels.clusterIssuers - required: true - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterIssuers/properties/default - type: select - type: single-step-form - - elements: - - if: isToggleOn|expose - label: - text: Expose via Gateway? - schema: - $ref: schema#/properties/spec/properties/admin/properties/expose/properties/default - type: switch - type: single-step-form - if: showAdditionalSettings - label: - text: Additional Options - show_label: true - type: single-step-form - type: single-step-form + type: block-layout + if: + type: function + name: showAdditionalSettings + label: Additional Options + showLabels: true + type: block-layout id: options - title: steps.0.label + # title: steps.0.label type: multi-step-form diff --git a/charts/kubedbcom-postgres-editor-options/ui/functions.js b/charts/kubedbcom-postgres-editor-options/ui/functions.js index 0ce2a12bbd..921b3d885d 100644 --- a/charts/kubedbcom-postgres-editor-options/ui/functions.js +++ b/charts/kubedbcom-postgres-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -319,1306 +321,1391 @@ const modeDetails = { }, } -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], + setDiscriminatorValue('bundleApiLoaded', false) + setDiscriminatorValue('configDatabase', false) + setDiscriminatorValue('createAuthSecret', false) + setDiscriminatorValue('recovery', false) + setDiscriminatorValue('referSecret', false) + setDiscriminatorValue('refDBName', '') + setDiscriminatorValue('refNamespace', '') + setDiscriminatorValue('backup', false) + setDiscriminatorValue('monitoring', false) + + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } + + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, }, - }, - ) - const projects = resp?.data?.status?.projects - if (projects) { - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - namespaces = projectsNamespace - } else { - namespaces = resp?.data?.status?.namespaces || [] + ) + const projects = resp?.data?.status?.projects + if (projects) { + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + namespaces = projectsNamespace + } else { + namespaces = resp?.data?.status?.namespaces || [] + } + return namespaces + } catch (e) { + console.log(e) + return [] } - return namespaces - } catch (e) { - console.log(e) - return [] } -} -function showRecovery({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/recovery') - const isRecoveryOn = getValue(discriminator, '/recovery') || '' - return isRecoveryOn -} + function showRecovery() { + // watchDependency('discriminator#/recovery') + const isRecoveryOn = getValue(discriminator, '/recovery') || '' + return isRecoveryOn + } -function updateAlertValue({ commit, model, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const alert = isMonitorEnabled ? 'warning' : 'none' - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: alert, - force: true, - }) - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} + function updateAlertValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const alert = isMonitorEnabled ? 'warning' : 'none' + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: alert, + force: true, + }) + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: agent, + force: true, + }) + } -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } -function showAuthSecretField({ discriminator, getValue, watchDependency }) { - return !showAuthPasswordField({ - discriminator, - getValue, - watchDependency, - }) -} + function showAuthSecretField() { + return !showAuthPasswordField() + } -async function getResources({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + 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) || [] + 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 -} + resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true + }) + return resources + } -async function getPostgresVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + async function getPostgresVersions(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, + const queryParams = { + filter: { + items: { + metadata: { name: null }, + spec: { version: null, deprecated: null }, + }, }, - }, - } + } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: queryParams, + }, + ) - const resources = (resp && resp.data && resp.data.items) || [] + const resources = (resp && resp.data && resp.data.items) || [] - // keep only non deprecated versions - const filteredPostgresVersions = resources.filter((item) => item.spec && !item.spec.deprecated) + // keep only non deprecated versions + const filteredPostgresVersions = resources.filter((item) => item.spec && !item.spec.deprecated) - filteredPostgresVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredPostgresVersions -} + filteredPostgresVersions.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + const specVersion = (item.spec && item.spec.version) || '' + item.text = `${name} (${specVersion})` + item.value = name + return true + }) + return filteredPostgresVersions + } -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/spec/authSecret/name') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/spec/authSecret/password') + function onCreateAuthSecretChange() { + const createAuthSecret = getValue(discriminator, '/createAuthSecret') + if (createAuthSecret) { + commit('wizard/model$delete', '/spec/authSecret/name') + } else if (createAuthSecret === false) { + commit('wizard/model$delete', '/spec/authSecret/password') + } } -} -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, + 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') + + 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 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) - }) + 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 -} + filteredSecrets.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true + }) + return filteredSecrets + } -function getMachineListForOptions({ model, getValue }) { - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') let array = [] + function getMachineListForOptions() { + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') - if (available.length) { - array = available.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - else { - let subText = '', - text = '' - const machineData = machinesFromPreset.find((val) => val.id === machine) - if (machineData) { - subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` - text = machineData.name ? machineData.name : machineData.id - } - return { text, subText, value: machine } - } - }) - } else { - array = machineList - .map((machine) => { + if (available.length) { + array = available.map((machine) => { if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + else { + let subText = '', + text = '' + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + text = machineData.name ? machineData.name : machineData.id + } + return { text, subText, value: machine } + } }) - .filter((val) => !!val) + } else { + array = machineList + .map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { text, subText, value: machine } + }) + .filter((val) => !!val) + } + return array } - return array -} -function setLimits({ model, getValue, commit, watchDependency }, resource, type) { - const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' - watchDependency(`model#${path}`) - const selectedMachine = getValue(model, path) || 'custom' - const reqCommitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - const comparePath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - - const resourceValue = getValue(model, comparePath) - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - - let cpu = '', - memory = '' - if (available.length && selectedMachine !== 'custom') { - const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) - if (machineData) { - cpu = machineData.limits.cpu - memory = machineData.limits.memory + function setLimits(resource, type) { + const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' + // watchDependency(`model#${path}`) + const selectedMachine = getValue(model, path) || 'custom' + const reqCommitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + const comparePath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + + const resourceValue = getValue(model, comparePath) + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + let cpu = '', + memory = '' + if (available.length && selectedMachine !== 'custom') { + const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) + if (machineData) { + cpu = machineData.limits.cpu + memory = machineData.limits.memory + } + } else { + if (selectedMachine === 'custom') { + cpu = resourceValue + memory = resourceValue + } else { + cpu = machines[selectedMachine].resources.limits.cpu + memory = machines[selectedMachine].resources.limits.memory + } } - } else { - if (selectedMachine === 'custom') { - cpu = resourceValue - memory = resourceValue + + if (resource === 'memory') { + commit('wizard/model$update', { + path: reqCommitPath, + value: memory, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: memory, + force: true, + }) + return memory } else { - cpu = machines[selectedMachine].resources.limits.cpu - memory = machines[selectedMachine].resources.limits.memory + commit('wizard/model$update', { + path: reqCommitPath, + value: cpu, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: cpu, + force: true, + }) + return cpu } } - if (resource === 'memory') { - commit('wizard/model$update', { - path: reqCommitPath, - value: memory, - force: true, - }) + function setRequests(resource, type) { + const modelPath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + + const fullpath = `/spec/podResources/machine` + const modelPathValue = getValue(model, fullpath) + commit('wizard/model$update', { - path: comparePath, - value: memory, + path: commitPath, + value: val, force: true, }) - return memory - } else { - commit('wizard/model$update', { - path: reqCommitPath, - value: cpu, - force: true, + + if (modelPathValue === 'custom') { + return + } + let commitCpuMemory, ModelPathValue + if (resource && type) { + const fullPath = `/spec/${type}/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/${type}/podResources/resources/requests/${resource}` + } else { + const fullPath = `/spec/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/podResources/resources/requests/${resource}` + } + let cpuMemoryValue + array.forEach((item) => { + if (item.value === ModelPathValue) { + // Parse subText like "CPU: 2, Memory: 2Gi" + const subText = item.subText || '' + if (resource === 'cpu') { + // Extract CPU value + const cpuMatch = subText.match(/CPU:\s*([^,]+)/) + cpuMemoryValue = cpuMatch ? cpuMatch[1].trim() : '' + } else if (resource === 'memory') { + // Extract Memory value + const memoryMatch = subText.match(/Memory:\s*(.+)/) + cpuMemoryValue = memoryMatch ? memoryMatch[1].trim() : '' + } + } }) commit('wizard/model$update', { - path: comparePath, - value: cpu, + path: commitCpuMemory, + value: cpuMemoryValue, force: true, }) - return cpu + return cpuMemoryValue } -} -function setRequests({ getValue, model, commit }, resource) { - const modelPath = `/spec/podResources/resources/requests/${resource}` - const val = getValue(model, modelPath) - commitPath = `/spec/podResources/resources/limits/${resource}` - commit('wizard/model$update', { - path: commitPath, - value: val, - force: true, - }) -} + function setMachineToCustom() { + const machine = getValue(model, '/spec/admin/machineProfiles/default') + return machine || 'custom' + } -function setMachineToCustom({ getValue, model }) { - const machine = getValue(model, '/spec/admin/machineProfiles/default') - return machine || 'custom' -} + async function fetchJsons() { + let ui = {} + let language = {} + let functions = {} + const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart -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) + } - 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, + } } - return { - ui: ui.data || {}, - language: language.data || {}, - functions, + function updateAgentValue(val) { + commit('wizard/model$update', { + path: '/spec/monitoring/agent', + value: val ? 'prometheus.io/operator' : '', + force: true, + }) + + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: val ? 'warning' : 'none', + force: true, + }) } -} -function updateAgentValue({ commit }, val) { - commit('wizard/model$update', { - path: '/spec/monitoring/agent', - value: val ? 'prometheus.io/operator' : '', - force: true, - }) - - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: val ? 'warning' : 'none', - force: true, - }) -} -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function getCreateNameSpaceUrl() { + 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + const domain = storeGet('/domain') || '' + if (domain.includes('bb.test')) { + return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } } -} - -const ifCapiProviderIsNotEmpty = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/provider') - const val = getValue(model, '/form/capi/provider') - if (val) return true -} -const showMultiselectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') + const ifCapiProviderIsNotEmpty = () => { + // watchDependency('model#/form/capi/provider') + const val = getValue(model, '/form/capi/provider') + if (val) return true + } - if (val === 'capz' && ifDedicated({ model, getValue })) return true -} + const showMultiselectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') -const showSelectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') - if (val !== 'capz' && ifDedicated({ model, getValue })) return true -} + if (val === 'capz' && ifDedicated()) return true + } -const ifDedicated = ({ model, getValue }) => { - const val = getValue(model, 'form/capi/dedicated') - if (val) return true -} + const showSelectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') + if (val !== 'capz' && ifDedicated()) return true + } -const dedicatedOnChange = ({ model, getValue, commit }) => { - const val = getValue(model, 'form/capi/dedicated') - if (!val) { - commit('wizard/model$delete', 'form/capi/zones') - commit('wizard/model$delete', 'form/capi/sku') + const ifDedicated = () => { + const val = getValue(model, 'form/capi/dedicated') + if (val) return true } -} -const ifZones = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/zones') - watchDependency('model#/form/capi/dedicated') - const zones = getValue(model, 'form/capi/zones') || [] - const isDedicated = getValue(model, 'form/capi/dedicated') - if (zones.length && isDedicated) return true -} + const dedicatedOnChange = () => { + const val = getValue(model, 'form/capi/dedicated') + if (!val) { + commit('wizard/model$delete', 'form/capi/zones') + commit('wizard/model$delete', 'form/capi/sku') + } + } -const zonesOnChange = ({ model, getValue, commit }) => { - const zones = getValue(model, 'form/capi/zones') || [] - if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') -} + const ifZones = () => { + // watchDependency('model#/form/capi/zones') + // watchDependency('model#/form/capi/dedicated') + const zones = getValue(model, 'form/capi/zones') || [] + const isDedicated = getValue(model, 'form/capi/dedicated') + if (zones.length && isDedicated) return true + } -async function getZones({ storeGet, axios, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const isDedicated = getValue(model, 'form/capi/dedicated') - if (isDedicated) { - try { - const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) - const val = resp.data.map((item) => { - return { value: item, text: item } - }) - return val - } catch (e) { - console.log(e) - return [] - } + const zonesOnChange = () => { + const zones = getValue(model, 'form/capi/zones') || [] + if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') } -} -async function getSKU({ storeGet, axios, model, getValue, watchDependency }) { - watchDependency('model#/form/capi/zones') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const zones = getValue(model, 'form/capi/zones') || [] - if (zones.length) { - try { - let url = `clustersv2/${owner}/${cluster}/vms?` - if (typeof zones === 'string') { - url += `zones=${encodeURIComponent(zones)}` - } else { - zones.forEach((item) => { - url += `zones=${encodeURIComponent(item)}&` + async function getZones() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const isDedicated = getValue(model, 'form/capi/dedicated') + if (isDedicated) { + try { + const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) + const val = resp.data.map((item) => { + return { value: item, text: item } }) - url = url.slice(0, -1) + return val + } catch (e) { + console.log(e) + return [] } - const resp = await axios.get(url) - const val = resp.data.map((item) => { - return { - value: item.name, - text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb]`, - } - }) - return val - } catch (e) { - console.log(e) - return [] } } -} - -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} - -function setStorageClass({ model, getValue, commit, watchDependency, discriminator }) { - const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' - let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' - const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] - const suffix = '-retain' - const simpleClassList = storageClassList.filter((item) => { - return !item.endsWith(suffix) - }) - const retainClassList = storageClassList.filter((item) => { - return item.endsWith(suffix) - }) - - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] - } else { - storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + async function getSKU() { + // watchDependency('model#/form/capi/zones') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const zones = getValue(model, 'form/capi/zones') || [] + if (zones.length) { + try { + let url = `clustersv2/${owner}/${cluster}/vms?` + if (typeof zones === 'string') { + url += `zones=${encodeURIComponent(zones)}` + } else { + zones.forEach((item) => { + url += `zones=${encodeURIComponent(item)}&` + }) + url = url.slice(0, -1) + } + const resp = await axios.get(url) + const val = resp.data.map((item) => { + return { + value: item.name, + text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb]`, + } + }) + return val + } catch (e) { + console.log(e) + return [] + } + } } - const isChangeable = isToggleOn( - { getValue, model, watchDependency, discriminator }, - 'storageClasses', - ) - if (isChangeable && storageClass) { - commit('wizard/model$update', { - path: '/spec/admin/storageClasses/default', - value: storageClass, - force: true, - }) + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false } -} -function showAlerts({ watchDependency, model, getValue, discriminator }) { - watchDependency('discriminator#/monitoring') - const isMonitorEnabled = getValue(discriminator, '/monitoring') - return ( - isMonitorEnabled && isToggleOn({ getValue, model, watchDependency, discriminator }, 'alert') - ) -} + function setStorageClass() { + const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' + let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' + const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] + const suffix = '-retain' -function onBackupSwitch({ discriminator, getValue, commit }) { - const isBackupOn = getValue(discriminator, '/backup') - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: isBackupOn ? 'KubeStash' : '', - force: true, - }) -} + const simpleClassList = storageClassList.filter((item) => { + return !item.endsWith(suffix) + }) + const retainClassList = storageClassList.filter((item) => { + return item.endsWith(suffix) + }) -function clearArbiterHidden({ commit }) { - commit('wizard/model$update', { - path: `/spec/arbiter/enabled`, - value: false, - force: true, - }) - - commit('wizard/model$update', { - path: `/spec/hidden/enabled`, - value: false, - force: true, - }) -} + if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { + storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] + } else { + storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + } -let placement = [] -let versions = [] -let storageClass = [] -let clusterIssuers = [] -let nodetopologiesShared = [] -let nodetopologiesDedicated = [] -let features = [] -let namespaces = [] -async function initBundle({ commit, model, getValue, axios, storeGet, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - - let db = getValue(model, '/metadata/resource/kind') - db = db.toLowerCase() - let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` - const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - - try { - const resp = await axios.get(url) - features = resp.data.features || [] - placement = resp.data.placementpolicies || [] - versions = resp.data.versions || [] - storageClass = resp.data.storageclasses || [] - clusterIssuers = resp.data.clusterissuers || [] - nodetopologiesDedicated = resp.data.dedicated || [] - nodetopologiesShared = resp.data.shared || [] - - const response = await axios.get(annotationUrl) - const annotations = response.data?.metadata?.annotations || {} - const uidRange = annotations['openshift.io/sa.scc.uid-range'] - if (uidRange) { - const val = uidRange.split('/')[0] + const isChangeable = isToggleOn('storageClasses') + if (isChangeable && storageClass) { commit('wizard/model$update', { - path: '/spec/openshift/securityContext/runAsUser', - value: val, + path: '/spec/admin/storageClasses/default', + value: storageClass, force: true, }) } - } catch (e) { - console.log(e) } - commit('wizard/model$update', { - path: '/spec/deletionPolicy', - value: getDefault({ getValue, model }, 'deletionPolicy'), - force: true, - }) - - if (!getValue(model, `/spec/admin/databases/Postgres/mode/toggle`)) { - let defMode = getDefault({ getValue, model }, 'databases/Postgres/mode') || '' - if (defMode === '') { - const arr = getValue(model, '/spec/databases/Postgres/mode/available') || [] - if (arr.length) defMode = arr[0] - } - commit('wizard/model$update', { - path: '/spec/mode', - value: defMode, - force: true, - }) + function showAlerts() { + // watchDependency('discriminator#/monitoring') + const isMonitorEnabled = getValue(discriminator, '/monitoring') + return isMonitorEnabled && isToggleOn('alert') } - if (!features.includes('tls')) { + function onBackupSwitch() { + const isBackupOn = getValue(discriminator, '/backup') commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: false, + path: '/spec/backup/tool', + value: isBackupOn ? 'KubeStash' : '', force: true, }) } - if (!features.includes('binding')) { + + function clearArbiterHidden() { commit('wizard/model$update', { - path: '/spec/admin/expose/default', + path: `/spec/arbiter/enabled`, value: false, force: true, }) - } - if (!features.includes('monitoring')) { - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: 'none', - force: true, - }) - } - if (!features.includes('backup')) { + commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', + path: `/spec/hidden/enabled`, value: false, force: true, }) - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: '', - force: true, - }) } - namespaces = getNamespaces({ axios, storeGet }) - setDiscriminatorValue('/bundleApiLoaded', true) -} -function fetchNamespaces({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return namespaces -} + let placement = [] + let versions = [] + let storageClass = [] + let clusterIssuers = [] + let nodetopologiesShared = [] + let nodetopologiesDedicated = [] + let features = [] + let namespaces = [] + async function initBundle() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + + let db = getValue(model, '/metadata/resource/kind') + db = db.toLowerCase() + let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` + const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` -async function getRecoveryNames({ getValue, model, watchDependency, storeGet, axios }, type) { - watchDependency(`model#/spec/init/archiver/${type}/namespace`) - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/spec/init/archiver/${type}/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${namespace}/repositories` - if (type === 'encryptionSecret') - url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - const options = [] - if (namespace) { try { const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) + features = resp.data.features || [] + placement = resp.data.placementpolicies || [] + versions = resp.data.versions || [] + storageClass = resp.data.storageclasses || [] + clusterIssuers = resp.data.clusterissuers || [] + nodetopologiesDedicated = resp.data.dedicated || [] + nodetopologiesShared = resp.data.shared || [] + + const response = await axios.get(annotationUrl) + const annotations = response.data?.metadata?.annotations || {} + const uidRange = annotations['openshift.io/sa.scc.uid-range'] + if (uidRange) { + const val = uidRange.split('/')[0] + commit('wizard/model$update', { + path: '/spec/openshift/securityContext/runAsUser', + value: val, + force: true, + }) + } } catch (e) { console.log(e) } - } - return options -} - -function fetchOptions({ model, getValue, commit }, type) { - let kind = getValue(model, '/metadata/resource/kind') - - let returnArray = [] - if (type === 'clusterTier/placement') { - returnArray = placement - } else if (type === `databases/${kind}/versions`) { - returnArray = versions - } else if (type === 'storageClasses') { - returnArray = storageClass - } else if (type === 'clusterIssuers') { - returnArray = clusterIssuers - } - if (returnArray.length === 1) { - const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: path, - value: returnArray[0], + path: '/spec/deletionPolicy', + value: getDefault('deletionPolicy'), force: true, }) - } - - return returnArray -} - -let archiverMap = [] -let archiverCalled = false - -function getAdminOptions({ getValue, model, watchDependency, axios, storeGet, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') - - if (type === 'storageClasses' && !archiverCalled) { - getArchiverName({ axios, storeGet }) - } - - const options = getValue(model, `/spec/admin/${type}/available`) || [] - if (options.length === 0) { - return fetchOptions({ model, getValue, commit }, type) - } - if (type.endsWith('/mode')) { - return ( - options?.map((item) => ({ - description: modeDetails[item]?.description || '', - text: modeDetails[item]?.text || '', - value: item, - })) || [] - ) - } - return options -} - -function showArchiver({ getValue, model }) { - return checkIfFeatureOn({ getValue, model }, 'archiver') -} - -async function getArchiverName({ axios, storeGet }) { - try { - archiverCalled = true - const params = storeGet('/route/params') - const { user, cluster, group, resource } = params - const url = `/clusters/${user}/${cluster}/proxy/storage.k8s.io/v1/storageclasses` - const resp = await axios.get(url) - - resp.data?.items?.forEach((item) => { - const annotations = item.metadata?.annotations - const classname = item.metadata?.name - const annotationKeyToFind = `${resource}.${group}/archiver` - archiverMap.push({ storageClass: classname, annotation: annotations[annotationKeyToFind] }) - return resp.data - }) - } catch (e) { - console.log(e) - } -} - -function onArchiverChange({ model, getValue, commit }) { - const isArchiverOn = getValue(model, '/spec/admin/archiver/enable/default') - const stClass = getValue(model, '/spec/admin/storageClasses/default') - const found = archiverMap.find((item) => item.storageClass === stClass) - const via = getValue(model, '/spec/admin/archiver/via') - - if (!isArchiverOn) { - commit('wizard/model$update', { - path: '/spec/archiverName', - value: '', - force: true, - }) - } else { - if (via === 'VolumeSnapshotter') { + if (!getValue(model, `/spec/admin/databases/Postgres/mode/toggle`)) { + let defMode = getDefault('databases/Postgres/mode') || '' + if (defMode === '') { + const arr = getValue(model, '/spec/databases/Postgres/mode/available') || [] + if (arr.length) defMode = arr[0] + } commit('wizard/model$update', { - path: '/spec/archiverName', - value: found.annotation, + path: '/spec/mode', + value: defMode, force: true, }) - } else { - const kind = getValue(model, '/metadata/resource/kind') + } + + if (!features.includes('tls')) { commit('wizard/model$update', { - path: '/spec/archiverName', - value: kind.toLowerCase(), + path: '/spec/admin/tls/default', + value: false, + force: true, + }) + } + if (!features.includes('binding')) { + commit('wizard/model$update', { + path: '/spec/admin/expose/default', + value: false, + force: true, + }) + } + if (!features.includes('monitoring')) { + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: 'none', + force: true, + }) + } + if (!features.includes('backup')) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: '', force: true, }) } + namespaces = getNamespaces() + setDiscriminatorValue('/bundleApiLoaded', true) } -} -function showArchiverAlert({ watchDependency, model, getValue, commit }) { - watchDependency('model#/spec/admin/storageClasses/default') + function fetchNamespaces() { + // watchDependency('discriminator#/bundleApiLoaded') + return namespaces + } - const mode = getValue(model, '/spec/mode') - if (mode === 'Standalone') return false + async function getRecoveryNames(type) { + // watchDependency(`model#/spec/init/archiver/${type}/namespace`) + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/spec/init/archiver/${type}/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${namespace}/repositories` + if (type === 'encryptionSecret') + url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` + const options = [] + if (namespace) { + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + } + return options + } - const via = getValue(model, '/spec/admin/archiver/via') + function fetchOptions(type) { + let kind = getValue(model, '/metadata/resource/kind') + + let returnArray = [] + if (type === 'clusterTier/placement') { + returnArray = placement + } else if (type === `databases/${kind}/versions`) { + returnArray = versions + } else if (type === 'storageClasses') { + returnArray = storageClass + } else if (type === 'clusterIssuers') { + returnArray = clusterIssuers + } - if (via === 'VolumeSnapshotter') { - // toggle archiver to false when storageClass annotation not found - const stClass = getValue(model, '/spec/admin/storageClasses/default') - const found = archiverMap.find((item) => item.storageClass === stClass) - const show = !found?.annotation - if (show) { + if (returnArray.length === 1) { + const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, + path: path, + value: returnArray[0], force: true, }) - return true - } else onArchiverChange({ model, getValue, commit }) - } else onArchiverChange({ model, getValue, commit }) - return false -} + } -function checkIfFeatureOn({ getValue, model }, type) { - let val = getValue(model, `/spec/admin/${type}/toggle`) - if (type === 'backup' || type === 'archiver') { - val = getValue(model, `/spec/admin/${type}/enable/toggle`) + return returnArray } - const backupVal = getValue(model, '/spec/backup/tool') - if (type === 'backup') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } else if (type === 'tls') { - return features.includes('tls') && val - } else if (type === 'expose') { - return features.includes('binding') && val - } else if (type === 'monitoring') { - return features.includes('monitoring') && val - } else if (type === 'archiver') { - return features.includes('backup') && val + let archiverMap = [] + let archiverCalled = false + + function getAdminOptions(type) { + // watchDependency('discriminator#/bundleApiLoaded') + + if (type === 'storageClasses' && !archiverCalled) { + getArchiverName() + } + + const options = getValue(model, `/spec/admin/${type}/available`) || [] + if (options.length === 0) { + return fetchOptions(type) + } + if (type.endsWith('/mode')) { + return ( + options?.map((item) => ({ + description: modeDetails[item]?.description || '', + text: modeDetails[item]?.text || '', + value: item, + })) || [] + ) + } + return options } -} -function isToggleOn({ getValue, model, discriminator, watchDependency, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') - watchDependency('model#/spec/admin/deployment/default') - const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') - let deploymentType = getValue(model, `/spec/admin/deployment/default`) - if (type === 'tls' || type === 'backup' || type === 'expose' || type === 'monitoring') { - return checkIfFeatureOn({ getValue, model }, type) - } else if ( - type === 'clusterTier' || - type === 'clusterTier/placement' || - type === 'clusterTier/nodeTopology' - ) { - if (deploymentType === 'Dedicated' && bundleApiLoaded) return true - else return false - } else if (type === 'deployment') { - const deploymentType = getValue(model, '/spec/admin/deployment/default') - if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + function showArchiver() { + return checkIfFeatureOn('archiver') + } + + async function getArchiverName() { + try { + archiverCalled = true + const params = storeGet('/route/params') + const { user, cluster, group, resource } = params + const url = `/clusters/${user}/${cluster}/proxy/storage.k8s.io/v1/storageclasses` + const resp = await axios.get(url) + + resp.data?.items?.forEach((item) => { + const annotations = item.metadata?.annotations + const classname = item.metadata?.name + const annotationKeyToFind = `${resource}.${group}/archiver` + archiverMap.push({ storageClass: classname, annotation: annotations[annotationKeyToFind] }) + return resp.data + }) + } catch (e) { + console.log(e) + } + } + + function onArchiverChange() { + const isArchiverOn = getValue(model, '/spec/admin/archiver/enable/default') + + const stClass = getValue(model, '/spec/admin/storageClasses/default') + const found = archiverMap.find((item) => item.storageClass === stClass) + const via = getValue(model, '/spec/admin/archiver/via') + + if (!isArchiverOn) { commit('wizard/model$update', { - path: '/spec/admin/deployment/default', - value: 'Shared', + path: '/spec/archiverName', + value: '', force: true, }) + } else { + if (via === 'VolumeSnapshotter') { + commit('wizard/model$update', { + path: '/spec/archiverName', + value: found.annotation, + force: true, + }) + } else { + const kind = getValue(model, '/metadata/resource/kind') + commit('wizard/model$update', { + path: '/spec/archiverName', + value: kind.toLowerCase(), + force: true, + }) + } } - return ( - getValue(model, `/spec/admin/${type}/toggle`) && - nodetopologiesDedicated.length && - bundleApiLoaded - ) - } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded -} + } -async function getNodeTopology({ model, getValue, axios, storeGet, watchDependency }) { - watchDependency('model#/spec/admin/deployment/default') - watchDependency('model#/spec/admin/clusterTier/default') - const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' - const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' - let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + function showArchiverAlert() { + // watchDependency('model#/spec/admin/storageClasses/default') - const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + const mode = getValue(model, '/spec/mode') + if (mode === 'Standalone') return false - if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared - else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + const via = getValue(model, '/spec/admin/archiver/via') - const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) - return filteredList -} + if (via === 'VolumeSnapshotter') { + // toggle archiver to false when storageClass annotation not found + const stClass = getValue(model, '/spec/admin/storageClasses/default') + const found = archiverMap.find((item) => item.storageClass === stClass) + const show = !found?.annotation + if (show) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + return true + } else onArchiverChange() + } else onArchiverChange() + return false + } -function filterNodeTopology(list, tier, provider) { - // first filter the list from value that exists from the filtered list got from API - const filteredlist = list + let backupToolInitialValue = '' + function checkIfFeatureOn(type) { + let val = getValue(model, `/spec/admin/${type}/toggle`) + if (type === 'backup' || type === 'archiver') { + val = getValue(model, `/spec/admin/${type}/enable/toggle`) + } + const backupVal = getValue(model, '/spec/backup/tool') + if (type === 'backup') { + if (backupToolInitialValue === '') { + backupToolInitialValue = + features.includes('backup') && backupVal === 'KubeStash' && val ? 'on' : 'off' + return features.includes('backup') && backupVal === 'KubeStash' && val + } else { + if (backupToolInitialValue === 'on') { + return true + } else { + return false + } + } + } else if (type === 'tls') { + return features.includes('tls') && val + } else if (type === 'expose') { + return features.includes('binding') && val + } else if (type === 'monitoring') { + return features.includes('monitoring') && val + } else if (type === 'archiver') { + return features.includes('backup') && val + } + } - // filter the list based on clusterTier - if (provider === 'EKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('c') - else if (tier === 'MemoryOptimized') return item.startsWith('r') - else return !item.startsWith('c') && !item.startsWith('r') - }) - } else if (provider === 'AKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - else - return ( - !(item.startsWith('f') || item.startsWith('fx')) && - !( + function isToggleOn(type) { + // watchDependency('discriminator#/bundleApiLoaded') + // watchDependency('model#/spec/admin/deployment/default') + const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') + let deploymentType = getValue(model, `/spec/admin/deployment/default`) + if (type === 'tls' || type === 'backup' || type === 'expose' || type === 'monitoring') { + return checkIfFeatureOn(type) + } else if ( + type === 'clusterTier' || + type === 'clusterTier/placement' || + type === 'clusterTier/nodeTopology' + ) { + if (deploymentType === 'Dedicated' && bundleApiLoaded) return true + else return false + } else if (type === 'deployment') { + const deploymentType = getValue(model, '/spec/admin/deployment/default') + if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + commit('wizard/model$update', { + path: '/spec/admin/deployment/default', + value: 'Shared', + force: true, + }) + } + return ( + getValue(model, `/spec/admin/${type}/toggle`) && + nodetopologiesDedicated.length && + bundleApiLoaded + ) + } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded + } + + async function getNodeTopology() { + // watchDependency('model#/spec/admin/deployment/default') + // watchDependency('model#/spec/admin/clusterTier/default') + const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' + const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' + let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + + const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + + if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared + else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + + const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) + return filteredList + } + + function filterNodeTopology(list, tier, provider) { + // first filter the list from value that exists from the filtered list got from API + const filteredlist = list + + // filter the list based on clusterTier + if (provider === 'EKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('c') + else if (tier === 'MemoryOptimized') return item.startsWith('r') + else return !item.startsWith('c') && !item.startsWith('r') + }) + } else if (provider === 'AKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('e') || item.startsWith('eb') || item.startsWith('ec') || item.startsWith('m') || item.startsWith('d') ) - ) - }) - } else if (provider === 'GKE') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') - return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - else - return ( - !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && - !( + else + return ( + !(item.startsWith('f') || item.startsWith('fx')) && + !( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + ) + }) + } else if (provider === 'GKE') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') + return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('x4') || item.startsWith('m1') || item.startsWith('m2') || item.startsWith('m3') ) - ) - }) - } else return filteredlist -} + else + return ( + !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && + !( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + ) + }) + } else return filteredlist + } -function returnFalse() { - return false -} + function returnFalse() { + return false + } -function isConfigDatabaseOn({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configDatabase') - return getValue(discriminator, '/configDatabase') -} + function isConfigDatabaseOn() { + // watchDependency('discriminator#/configDatabase') + return getValue(discriminator, '/configDatabase') + } -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} + function notEqualToDatabaseMode(mode) { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + return modelPathValue && modelPathValue !== mode + } -function showStorageSizeField({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - const validType = [] - return !validType.includes(modelPathValue) -} + function showStorageSizeField() { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + const validType = [] + return !validType.includes(modelPathValue) + } -function showHidden({ watchDependency, model, getValue }) { - watchDependency('model#/spec/hidden/enabled') - const isHiddenOn = getValue(model, '/spec/hidden/enabled') || '' - const notStandalone = notEqualToDatabaseMode({ model, getValue, watchDependency }, 'Standalone') - return isHiddenOn && notStandalone -} + function showHidden() { + // watchDependency('model#/spec/hidden/enabled') + const isHiddenOn = getValue(model, '/spec/hidden/enabled') || '' + const notStandalone = notEqualToDatabaseMode('Standalone') + return isHiddenOn && notStandalone + } -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} + function showArbiter() { + // watchDependency('model#/spec/arbiter/enabled') + const isArbiterOn = getValue(model, '/spec/arbiter/enabled') || '' + const notStandalone = notEqualToDatabaseMode('Standalone') + return isArbiterOn && notStandalone + } -function showArbiter({ watchDependency, model, getValue }) { - watchDependency('model#/spec/arbiter/enabled') - const isArbiterOn = getValue(model, '/spec/arbiter/enabled') || '' - const notStandalone = notEqualToDatabaseMode({ model, getValue, watchDependency }, 'Standalone') - return isArbiterOn && notStandalone -} + function clearConfiguration() { + const configOn = getValue(discriminator, '/configDatabase') -function clearConfiguration({ discriminator, getValue, commit }) { - const configOn = getValue(discriminator, '/configDatabase') + if (!configOn) { + commit('wizard/model$delete', '/spec/configuration') + } + } - if (!configOn) { - commit('wizard/model$delete', '/spec/configuration') + function showIssuer() { + // watchDependency('model#/spec/admin/tls/default') + const isTlsEnabled = getValue(model, '/spec/admin/tls/default') + const isIssuerToggleEnabled = isToggleOn('clusterIssuers') + return isTlsEnabled && isIssuerToggleEnabled } -} -function showIssuer({ model, getValue, watchDependency, discriminator }) { - watchDependency('model#/spec/admin/tls/default') - const isTlsEnabled = getValue(model, '/spec/admin/tls/default') - const isIssuerToggleEnabled = isToggleOn( - { getValue, model, watchDependency, discriminator }, - 'clusterIssuers', - ) - return isTlsEnabled && isIssuerToggleEnabled -} + function onAuthChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/spec/authSecret/password', + value: '', + force: true, + }) + } -function onAuthChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/authSecret/password', - value: '', - force: true, - }) -} + function setMonitoring() { + const agent = getValue(model, '/spec/admin/monitoring/agent') || '' + return !!agent + } -function setMonitoring({ getValue, model }) { - const agent = getValue(model, '/spec/admin/monitoring/agent') || '' - return !!agent -} + function setBackup() { + const backup = getValue(model, '/spec/backup/tool') + const val = getValue(model, '/spec/admin/backup/enable/default') + return backup === 'KubeStash' && features.includes('backup') && val + } -function setBackup({ model, getValue }) { - const backup = getValue(model, '/spec/backup/tool') - const val = getValue(model, '/spec/admin/backup/enable/default') - return backup === 'KubeStash' && features.includes('backup') && val -} + function isMachineCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue === 'custom' + } -function isMachineCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue === 'custom' -} + function isMachineNotCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue !== 'custom' && !!modelPathValue + } -function isMachineNotCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue !== 'custom' && !!modelPathValue -} + function EqualToDatabaseMode(mode) { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + return modelPathValue && modelPathValue === mode + } -function EqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue === mode -} + function showAdditionalSettings() { + // watchDependency('discriminator#/bundleApiLoaded') + return features.length + } -function showAdditionalSettings({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return features.length -} + function getDefault(type) { + const val = getValue(model, `/spec/admin/${type}/default`) || '' + return val + } -function getDefault({ getValue, model }, type) { - const val = getValue(model, `/spec/admin/${type}/default`) || '' - return val -} + function convertToLocal(input) { + const date = new Date(input) -function convertToLocal(input) { - const date = new Date(input) + if (isNaN(date.getTime())) { + return null + } - if (isNaN(date.getTime())) { - return null + return date.toString() } - return date.toString() -} + function convertToUTC(localTime) { + const date = new Date(localTime) + if (isNaN(date.getTime())) return -function getComponentLogStats(snapshot) { - if (!snapshot || !snapshot.status || !snapshot.status.components) { - return null + const utcString = date.toISOString() + return utcString } - const components = snapshot.status.components - const appKind = snapshot.spec?.appRef?.kind + function onTimestampChange() { + const localTime = getValue(model, '/spec/init/archiver/recoveryTimestamp') + if (!localTime) return - if (appKind === 'MongoDB') { - for (const [key, value] of Object.entries(components)) { - if (key.endsWith('0') && value.logStats) { - return value.logStats - } + const utcString = convertToUTC(localTime) + + // Only update if the value is valid & not already in UTC format + if (utcString && localTime !== utcString) { + commit('wizard/model$update', { + path: '/spec/init/archiver/recoveryTimestamp', + value: utcString, + force: true, + }) } } - if (components['wal'] && components['wal'].logStats) { - return components['wal'].logStats - } + function getComponentLogStats(snapshot) { + if (!snapshot || !snapshot.status || !snapshot.status.components) { + return null + } - return null -} + const components = snapshot.status.components + const appKind = snapshot.spec?.appRef?.kind -async function setPointInTimeRecovery({ commit, axios, storeGet, discriminator, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const refNamespace = getValue(discriminator, '/refNamespace') - const refDBName = getValue(discriminator, '/refDBName') + if (appKind === 'MongoDB') { + for (const [key, value] of Object.entries(components)) { + if (key.endsWith('0') && value.logStats) { + return value.logStats + } + } + } - try { - const repositoriesUrl = `clusters/${owner}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${refNamespace}/repositories/${refDBName}-full` - const snapshotsUrl = `clusters/${owner}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${refNamespace}/snapshots/${refDBName}-incremental-snapshot` - const repositoriesResp = await axios.get(repositoriesUrl) - const snapshotsResp = await axios.get(snapshotsUrl) + if (components['wal'] && components['wal'].logStats) { + return components['wal'].logStats + } - commit('wizard/model$update', { - path: `/spec/init/archiver/encryptionSecret/name`, - value: repositoriesResp.data?.spec.encryptionSecret.name, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/encryptionSecret/namespace`, - value: repositoriesResp.data?.spec.encryptionSecret.namespace, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/fullDBRepository/name`, - value: `${refDBName}-full`, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/fullDBRepository/namespace`, - value: `${refNamespace}`, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/manifestRepository/name`, - value: `${refDBName}-manifest`, - force: true, - }) - commit('wizard/model$update', { - path: `/spec/init/archiver/manifestRepository/namespace`, - value: `${refNamespace}`, - force: true, - }) + return null + } - const resp = getComponentLogStats(snapshotsResp.data) + async function setPointInTimeRecovery() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const refNamespace = getValue(discriminator, '/refNamespace') + const refDBName = getValue(discriminator, '/refDBName') - commit('wizard/model$update', { - path: `/spec/init/archiver/recoveryTimestamp`, - value: convertToLocal(resp?.end), - force: true, - }) - commit('wizard/model$update', { - path: `/minDate`, - value: convertToLocal(resp?.start), - force: true, - }) - commit('wizard/model$update', { - path: `/maxDate`, - value: convertToLocal(resp?.end), - force: true, - }) - } catch (e) { - commit('wizard/model$update', { - path: `/spec/init/archiver/recoveryTimestamp`, - value: '', - force: true, - }) - commit('wizard/model$update', { - path: `/minDate`, - value: '', - force: true, - }) - commit('wizard/model$update', { - path: `/maxDate`, - value: '', - force: true, - }) - console.log(e) - } -} + try { + const repositoriesUrl = `clusters/${owner}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${refNamespace}/repositories/${refDBName}-full` + const snapshotsUrl = `clusters/${owner}/${cluster}/proxy/storage.kubestash.com/v1alpha1/namespaces/${refNamespace}/snapshots/${refDBName}-incremental-snapshot` + const repositoriesResp = await axios.get(repositoriesUrl) + const snapshotsResp = await axios.get(snapshotsUrl) -function isConfigAvailable({ getValue, model }) { - const val = getValue(model, '/spec/configuration') - return val !== '' -} + commit('wizard/model$update', { + path: `/spec/init/archiver/encryptionSecret/name`, + value: repositoriesResp.data?.spec.encryptionSecret.name, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/encryptionSecret/namespace`, + value: repositoriesResp.data?.spec.encryptionSecret.namespace, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/fullDBRepository/name`, + value: `${refDBName}-full`, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/fullDBRepository/namespace`, + value: `${refNamespace}`, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/manifestRepository/name`, + value: `${refDBName}-manifest`, + force: true, + }) + commit('wizard/model$update', { + path: `/spec/init/archiver/manifestRepository/namespace`, + value: `${refNamespace}`, + force: true, + }) -async function getReferSecrets({ getValue, model, storeGet, axios, discriminator }) { - const referSecret = getValue(discriminator, '/referSecret') - if (!referSecret) { - return [] - } + const resp = getComponentLogStats(snapshotsResp.data) - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/metadata/release/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` + commit('wizard/model$update', { + path: `/spec/init/archiver/recoveryTimestamp`, + value: convertToUTC(resp?.end), + force: true, + }) + commit('wizard/model$update', { + path: `/minDate`, + value: convertToUTC(resp?.start), + force: true, + }) + commit('wizard/model$update', { + path: `/maxDate`, + value: convertToUTC(resp?.end), + force: true, + }) + } catch (e) { + pointIntimeError = + e.response?.data?.message || 'Invalid name / namespace for recovery timestamp' + commit('wizard/model$update', { + path: `/spec/init/archiver/recoveryTimestamp`, + value: '', + force: true, + }) + commit('wizard/model$update', { + path: `/minDate`, + value: '', + force: true, + }) + commit('wizard/model$update', { + path: `/maxDate`, + value: '', + force: true, + }) + commit('wizard/model$delete', '/spec/init/archiver/encryptionSecret') + commit('wizard/model$delete', '/spec/init/archiver/fullDBRepository') + commit('wizard/model$delete', '/spec/init/archiver/manifestRepository') + console.log(e) + } + } - const options = [] - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) - } catch (e) { - console.log(e) + let pointIntimeError = '' + function pointInTimeErrorCheck() { + if (pointIntimeError.length) return pointIntimeError + return } - return options -} -function showAuthPasswordField({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + async function getReferSecrets() { + const referSecret = getValue(discriminator, '/referSecret') + if (!referSecret) { + return [] + } -function showSecretDropdown({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/metadata/release/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` -function showReferSecret({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/createAuthSecret') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue -} + const options = [] + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + return options + } -function getDefaultValue({ getValue, model }, path) { - const val = getValue(model, `/${path}`) || '' - return val -} + function showAuthPasswordField() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !modelPathValue && showReferSecret() + } -function showReferSecretSwitch({ model, getValue, watchDependency, discriminator }) { - const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showSecretDropdown() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !!modelPathValue && showReferSecret() + } -function onReferSecretChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) -} + function showReferSecret() { + const modelPathValue = getValue(discriminator, '/createAuthSecret') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue + } -async function getAppBindings({ commit, axios, storeGet, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function getDefaultValue(path) { + const val = getValue(model, `/${path}`) || '' + return val + } - const queryParams = { - filter: { - items: { - metadata: { name: null, namespace: null }, - spec: { type: null }, - }, - }, + function showReferSecretSwitch() { + const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue && showReferSecret() } - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/appcatalog.appscode.com/v1alpha1/appbindings`, - { - params: queryParams, - }, - ) - const resources = (resp && resp.data && resp.data.items) || [] + function onReferSecretChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + } - const fileredResources = resources - .filter((item) => item.spec?.type === 'kubedb.com/postgres') - .map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const namespace = (item.metadata && item.metadata.namespace) || '' - return { - text: `${namespace}/${name}`, - value: { name, namespace }, - } - }) - return fileredResources - } catch (e) { - console.log(e) - return [] + async function getAppBindings() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + + const queryParams = { + filter: { + items: { + metadata: { name: null, namespace: null }, + spec: { type: null }, + }, + }, + } + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/appcatalog.appscode.com/v1alpha1/appbindings`, + { + params: queryParams, + }, + ) + + const resources = (resp && resp.data && resp.data.items) || [] + + const fileredResources = resources + .filter((item) => item.spec?.type === 'kubedb.com/postgres') + .map((item) => { + const name = (item.metadata && item.metadata.name) || '' + const namespace = (item.metadata && item.metadata.namespace) || '' + return { + text: `${namespace}/${name}`, + value: { name, namespace }, + } + }) + return fileredResources + } catch (e) { + console.log(e) + return [] + } } -} -return { - showReferSecretSwitch, - onReferSecretChange, - getDefaultValue, - isRancherManaged, - showSecretDropdown, - showReferSecret, - getReferSecrets, - isConfigAvailable, - setPointInTimeRecovery, - getRecoveryNames, - fetchNamespaces, - showRecovery, - initBundle, - returnFalse, - EqualToDatabaseMode, - onAuthChange, - clearConfiguration, - clearArbiterHidden, - isMachineNotCustom, - isMachineCustom, - getAdminOptions, - isToggleOn, - showAlerts, - onBackupSwitch, - getNodeTopology, - filterNodeTopology, - showIssuer, - setMonitoring, - updateAlertValue, - getNamespaces, - isVariantAvailable, - fetchJsons, - showAuthPasswordField, - notEqualToDatabaseMode, - showStorageSizeField, - returnFalse, - isEqualToModelPathValue, - showAuthSecretField, - getResources, - showHidden, - notEqualToDatabaseMode, - showArbiter, - notEqualToDatabaseMode, - isConfigDatabaseOn, - getPostgresVersions, - onCreateAuthSecretChange, - getSecrets, - getMachineListForOptions, - setLimits, - setRequests, - setMachineToCustom, - updateAgentValue, - getCreateNameSpaceUrl, - ifCapiProviderIsNotEmpty, - ifDedicated, - dedicatedOnChange, - ifZones, - zonesOnChange, - getZones, - getSKU, - showMultiselectZone, - showSelectZone, - setStorageClass, - setBackup, - showAdditionalSettings, - getDefault, - onArchiverChange, - showArchiverAlert, - showArchiver, - getAppBindings, + return { + showReferSecretSwitch, + onReferSecretChange, + getDefaultValue, + isRancherManaged, + showSecretDropdown, + showReferSecret, + getReferSecrets, + setPointInTimeRecovery, + pointInTimeErrorCheck, + getRecoveryNames, + fetchNamespaces, + showRecovery, + initBundle, + returnFalse, + EqualToDatabaseMode, + onAuthChange, + clearConfiguration, + clearArbiterHidden, + isMachineNotCustom, + isMachineCustom, + getAdminOptions, + isToggleOn, + showAlerts, + onBackupSwitch, + getNodeTopology, + filterNodeTopology, + showIssuer, + setMonitoring, + updateAlertValue, + getNamespaces, + isVariantAvailable, + fetchJsons, + showAuthPasswordField, + notEqualToDatabaseMode, + showStorageSizeField, + returnFalse, + isEqualToModelPathValue, + showAuthSecretField, + getResources, + showHidden, + notEqualToDatabaseMode, + showArbiter, + notEqualToDatabaseMode, + isConfigDatabaseOn, + getPostgresVersions, + onCreateAuthSecretChange, + getSecrets, + getMachineListForOptions, + setLimits, + setRequests, + setMachineToCustom, + updateAgentValue, + getCreateNameSpaceUrl, + ifCapiProviderIsNotEmpty, + ifDedicated, + dedicatedOnChange, + ifZones, + zonesOnChange, + getZones, + getSKU, + showMultiselectZone, + showSelectZone, + setStorageClass, + setBackup, + showAdditionalSettings, + getDefault, + onArchiverChange, + showArchiverAlert, + showArchiver, + getAppBindings, + onTimestampChange, + } } diff --git a/charts/kubedbcom-postgres-editor/ui/edit-ui.yaml b/charts/kubedbcom-postgres-editor/ui/edit-ui.yaml index 8b20bac058..cde79a6ad0 100644 --- a/charts/kubedbcom-postgres-editor/ui/edit-ui.yaml +++ b/charts/kubedbcom-postgres-editor/ui/edit-ui.yaml @@ -1,1375 +1,734 @@ -steps: -- form: - elements: - - disabled: true - label: - text: labels.database.name - onChange: onNameChange - schema: - $ref: schema#/properties/metadata/properties/release/properties/name - type: input - - disabled: true - fetch: getResources|core|v1|namespaces - label: - text: labels.namespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/metadata/properties/release/properties/namespace - type: select - - disableUnselect: true - disabled: true - fetch: getPostgresVersions|catalog.kubedb.com|v1alpha1|postgresversions - label: - text: labels.database.version - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/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/kubedbComPostgres/properties/metadata/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/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/kubedbComPostgres/properties/metadata/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/properties/metadata/properties/annotations/additionalProperties - type: input - - hasDescription: true - label: - text: labels.deletionPolicy - 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/kubedbComPostgres/properties/spec/properties/deletionPolicy - type: radio - - disabled: true - label: - text: labels.secret - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/properties/spec/properties/authSecret/properties/name - type: input - - fetch: getClientAuthModes - label: - text: labels.client_auth_mode - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/properties/spec/properties/clientAuthMode - type: radio - type: single-step-form - id: basic - title: steps.0.label -- form: - elements: - - alias: reusable_alert - chart: - name: uibytebuildersdev-component-alert - version: v0.29.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 +type: multi-step-form +step: + - type: single-step-form + id: backupconfiguration + # label: Backup + schema: schema/ elements: - - if: isEqualToDatabaseMode|Cluster - label: - text: labels.to_update_replicas - type: label-element - - customClass: mb-20 - if: isEqualToDatabaseMode|Cluster - label: - text: labels.create_opsrequest - type: anchor - url: - params: - cluster: - $ref: store#/route/params/cluster - dbname: - $ref: model#/metadata/release/name - domain: - $ref: store#/domain - group: - $ref: model#/metadata/resource/group - kind: - $ref: model#/metadata/resource/kind - namespace: - $ref: model#/metadata/release/namespace - owner: - $ref: store#/route/params/user - resource: - $ref: model#/metadata/resource/name - version: - $ref: model#/metadata/resource/version - path: ${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/postgresopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=HorizontalScaling - - computed: setDatabaseMode - disabled: true - hasDescription: true - label: - text: labels.database.mode - onChange: deleteDatabaseModePath + - type: radio + label: Schedule a Backup? + schema: temp/properties/scheduleBackup + isHorizontal: true options: - - description: options.database.mode.Standalone.description - text: options.database.mode.Standalone.label - value: Standalone - - description: options.database.mode.Cluster.description - text: options.database.mode.Cluster.label - value: Cluster - schema: - $ref: discriminator#/activeDatabaseMode - type: radio - - disabled: true - if: isEqualToDatabaseMode|Cluster - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/properties/spec/properties/replicas - type: input - - disabled: true - elements: - - fetch: getStorageClassNames - label: - text: labels.storage.class - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/properties/spec/properties/storage/properties/storageClassName - type: select - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/properties/spec/properties/storage/properties/resources/properties/requests/properties/storage - type: input - type: single-step-form - - disabled: true - elements: - - label: - text: labels.standbyMode - options: - - text: options.standbyMode.hot - value: Hot - - text: options.standbyMode.warm - value: Warm - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/properties/spec/properties/standbyMode - type: radio - - elements: - - customClass: mt-10 - label: - text: labels.electionTick - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/properties/spec/properties/leaderElection/properties/electionTick - type: input - - label: - text: labels.heartbeatTick - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/properties/spec/properties/leaderElection/properties/heartbeatTick - type: input - - label: - text: labels.maximumLagBeforeFailover - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/properties/spec/properties/leaderElection/properties/maximumLagBeforeFailover - type: input - - label: - text: labels.period - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/properties/spec/properties/leaderElection/properties/period - type: input - hideForm: true - label: - text: labels.leaderElection - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/properties/spec/properties/leaderElection - show_label: true - type: single-step-form - if: isEqualToDatabaseMode|Cluster - type: single-step-form - type: single-step-form - id: topology - title: steps.1.label -- form: - discriminator: - configureTLS: - default: true - type: boolean - elements: - - label: - text: labels.to_update_tls - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - params: - cluster: - $ref: store#/route/params/cluster - dbname: - $ref: model#/metadata/release/name - domain: - $ref: store#/domain - group: - $ref: model#/metadata/resource/group - kind: - $ref: model#/metadata/resource/kind - namespace: - $ref: model#/metadata/release/namespace - owner: - $ref: store#/route/params/user - resource: - $ref: model#/metadata/resource/name - version: - $ref: model#/metadata/resource/version - path: ${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/postgresopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=ReconfigureTLS - - computed: isValueExistInModel|/resources/kubedbComPostgres/spec/tls - disabled: true - label: - text: labels.enable_tls - onChange: onTlsConfigureChange - schema: - $ref: discriminator#/configureTLS - type: switch - - disabled: true + - text: 'Yes' + value: 'yes' + - text: 'No' + value: 'no' + if: + type: function + name: showScheduleBackup + init: + type: func + value: initScheduleBackupForEdit + watcher: + func: onScheduleBackupChange + paths: + - temp/properties/scheduleBackup + - type: block-layout + label: Backup Form + showLabels: false + loader: initBackupData + if: + type: function + name: showBackupForm elements: - - computed: setSSLMode - label: - text: labels.ssl_mode - options: - - text: allow - value: allow - - text: prefer - value: prefer - - text: require - value: require - - text: verify-ca - value: verify-ca - - text: verify-full - value: verify-full - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/properties/spec/properties/sslMode - type: select - - elements: - - computed: setApiGroup - disabled: true - label: - text: labels.api_group - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup - type: input - - label: - text: labels.kind + - type: radio + label: Select Backup Type + schema: temp/properties/backupType + isHorizontal: true options: - - text: Issuer - value: Issuer - - text: ClusterIssuer - value: ClusterIssuer - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/properties/spec/properties/tls/properties/issuerRef/properties/kind - type: select - - allowUserDefinedOption: true - fetch: getIssuerRefsName - label: - text: labels.name - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/properties/spec/properties/tls/properties/issuerRef/properties/name - type: select - label: - text: labels.issuer_ref - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/properties/spec/properties/tls/properties/issuerRef - type: single-step-form - - alias: reusable_certificates - chart: - name: uibytebuildersdev-component-certificates - version: v0.29.0 - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/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: + - text: BackupConfig + value: BackupConfig + description: 'Create, Delete or Modify BackupConfig' + - text: BackupBlueprint + value: BackupBlueprint + description: Enable/Disable BackupBlueprint + if: + type: function + name: isBackupDataLoadedTrue + init: + type: func + value: setBackupType + loader: getTypes + watcher: + func: onBackupTypeChange + paths: + - temp/properties/backupType + - type: block-layout + label: Config + if: + type: function + name: isBackupType|BackupConfig + elements: + - type: select + label: Select Context + schema: temp/properties/backupConfigContext + validation: + type: required + loader: getContext + watcher: + func: onContextChange + paths: + - temp/properties/backupConfigContext + - type: select + label: Select BackupConfig + schema: temp/properties/config + validation: + type: required + if: + type: function + name: showConfigList + loader: getConfigList + watcher: + func: onConfigChange + paths: + - temp/properties/config + - type: input + label: Schedule + schema: temp/properties/schedule + validation: + type: required + if: + type: function + name: showSchedule + loader: + name: getDefaultSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions + watchPaths: + - temp/properties/config + watcher: + func: onInputChangeSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions|schedule + paths: + - temp/properties/schedule + - type: switch + label: Paused + fullwidth: true + schema: schema/properties/resources/properties/coreKubestashComBackupConfiguration/properties/spec/properties/paused + if: + type: function + name: showPause + watcher: + func: setPausedValue + paths: + - temp/properties/config + init: + type: func + value: setPausedValue + - type: block-layout + label: Blueprint + if: + type: function + name: isBackupType|BackupBlueprint + elements: + - type: switch + label: Enable Backup Blueprint + fullwidth: true + schema: temp/properties/blueprintEnabled + init: + type: func + value: setBlueprintSwitch + watcher: + func: onBlueprintChange + paths: + - temp/properties/blueprintEnabled + - type: block-layout + label: Archiver + if: + type: function + name: isBackupType|Archiver + elements: + - type: switch + label: Enable Archiver + fullwidth: true + schema: temp/properties/archiverEnabled + init: + type: func + value: setArchiverSwitch + watcher: + func: onArchiverChange + paths: + - temp/properties/archiverEnabled + + - type: single-step-form + id: compute-autoscaler + loader: getDbDetails elements: - - disabled: disableInitializationSection - discriminator: - prePopulateDatabase: - type: string - elements: - - computed: initPrePopulateDatabase - label: - text: labels.prePopulateDatabase - onChange: onPrePopulateDatabaseChange + - type: block-layout + if: + type: function + name: isConsole + elements: + - type: input + label: Name + schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/metadata/properties/name + - type: select + label: Select Namespace + loader: getNamespaces + if: + type: function + name: isRancherManaged + schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/metadata/properties/namespace + - type: select + label: Select Db + loader: getPostgresDbs + validation: + type: required + refresh: true + schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/databaseRef/properties/name + watcher: + func: initMetadata + paths: + - schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/databaseRef/properties/name + + - type: radio + if: + type: function + name: isConsole + label: Select Type + validation: + type: required + schema: temp/properties/autoscalingType + watcher: + func: initMetadata + paths: + - temp/properties/autoscalingType 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 + - text: Compute + value: compute + description: Scale your CPU Memory based on resource usage + - text: Storage + value: storage + description: Expand your database size based on volume usage + + - type: block-layout + showLabels: false + loader: fetchTopologyMachines 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/kubedbComPostgres/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/kubedbComPostgres/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/kubedbComPostgres/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 + # postgres mode + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComPostgresAutoscaler/spec/compute/postgres/trigger + schema: temp/properties/compute/properties/postgres/properties/trigger + watcher: + func: onTriggerChange|compute/postgres + paths: + - temp/properties/compute/properties/postgres/properties/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/properties/podLifeTimeThreshold + customClass: width-300 + - type: block-layout + label: Postgres + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres 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.29.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 + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|postgres|min + loader: + name: getMachines|postgres|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-max + watcher: + func: onMachineChange|postgres + paths: + - temp/properties/allowedMachine-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|postgres|max + loader: + name: getMachines|postgres|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-min + watcher: + func: onMachineChange|postgres + paths: + - temp/properties/allowedMachine-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|postgres + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/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/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/properties/containerControlledValues + - type: block-layout + label: In Memory Storage + showLabels: true + if: + type: function + name: showStorageMemoryOption + # schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/properties/inMemoryStorage + elements: + - type: threshold-input + label: Scaling Factor Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/properties/inMemoryStorage/properties/scalingFactorPercentage + - type: threshold-input + label: Usage Threshold Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/properties/inMemoryStorage/properties/usageThresholdPercentage + + - type: block-layout + label: Node Topology + if: + type: function + name: hasNoAnnotations + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/nodeTopology 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.29.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/kubedbComPostgres/properties/spec/properties/init/properties/waitForInitialRestore - type: switch - if: showInitializationForm - type: single-step-form - type: single-step-form - type: single-step-form - id: initialization - title: steps.3.label -- form: - discriminator: - repoInitialSelectionStatus: - type: string - scheduleBackup: - default: "yes" - type: string - elements: - - computed: initScheduleBackupForEdit - if: showScheduleBackup - 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: - backupType: - type: string - isBackupDataLoaded: - default: false - type: boolean - elements: - - computed: initBackupData - if: returnFalse - type: input - - computed: setBackupType - fetch: getTypes - hasDescription: true - if: isBackupDataLoadedTrue - label: - text: Select Backup Type - onChange: onBackupTypeChange - schema: - $ref: discriminator#/backupType - type: radio - - discriminator: - backupConfigContext: - type: string - config: - type: string - paused: - default: false - type: boolean - schedule: - type: string - elements: - - fetch: getContext - label: - text: Select Context - onChange: onContextChange - required: true - schema: - $ref: discriminator#/backupConfigContext - type: select - - fetch: getConfigList - if: showConfigList - label: - text: Select BackupConfig - onChange: onConfigChange - required: true - schema: - $ref: discriminator#/config - type: select - - computed: getDefaultSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions - if: showSchedule - label: - text: Schedule - onChange: onInputChangeSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions|schedule - required: true - schema: - $ref: discriminator#/schedule - type: input - - if: showPause - label: - text: Paused - schema: - $ref: schema#/properties/resources/properties/coreKubestashComBackupConfiguration/properties/spec/properties/paused - type: switch - if: isBackupType|BackupConfig - type: single-step-form - - discriminator: - blueprintEnabled: - default: false - type: boolean - elements: - - computed: setBlueprintSwitch - label: - text: Enable Backup Blueprint - onChange: onBlueprintChange - schema: - $ref: discriminator#/blueprintEnabled - type: switch - if: isBackupType|BackupBlueprint - type: single-step-form - - discriminator: - archiverEnabled: - default: false - type: boolean - elements: - - computed: setArchiverSwitch - label: - text: Enable Archiver - onChange: onArchiverChange - schema: - $ref: discriminator#/archiverEnabled - type: switch - if: isBackupType|Archiver - 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 + - type: select + label: Select NodeTopology + loader: fetchNodeTopology + schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name + - type: threshold-input + label: ScaleUp Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage + - type: threshold-input + label: ScaleDown Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage + + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + # schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/opsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: storage-autoscaler elements: - - label: - text: labels.to_update_exporter_resources - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - function: getOpsRequestUrl|VerticalScaling - - computed: isValueExistInModel|/resources/kubedbComPostgres/spec/monitor - label: - text: labels.enable_monitoring - onChange: onEnableMonitoringChange - schema: - $ref: discriminator#/enableMonitoring - type: switch - - discriminator: - customizeExporter: - default: true - type: boolean + - type: block-layout + showLabels: false 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/kubedbComPostgres/properties/spec/properties/monitor/properties/agent - type: radio - - elements: - - label: - text: labels.scrapping_interval - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval - type: input - if: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComPostgres/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/kubedbComPostgres/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/kubedbComPostgres/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: - - if: returnFalse - label: - text: labels.resources - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/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/kubedbComPostgres/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/kubedbComPostgres/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup - type: input - - label: - text: labels.port - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/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/kubedbComPostgres/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args/items - type: input - label: - text: labels.args - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args - type: list-input-form - - alias: reusable_env - chart: - name: uibytebuildersdev-component-env - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/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: - - elements: - - alias: pod_template_standalone - chart: - name: uibytebuildersdev-component-pod-template - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - functionCallbacks: - isEditWizard: - $ref: functions#/returnTrue - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/properties/spec/properties/podTemplate - type: reusable-element - type: single-step-form - 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.29.0 - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/properties/spec/properties/serviceTemplates - type: reusable-element - type: single-step-form - id: networking - title: steps.7.label -- form: - elements: - - elements: - - discriminator: - configuration: - type: string - configurationSource: - default: use-existing-config - type: string - elements: - - label: - text: labels.to_update_config - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - params: - cluster: - $ref: store#/route/params/cluster - dbname: - $ref: model#/metadata/release/name - domain: - $ref: store#/domain - group: - $ref: model#/metadata/resource/group - kind: - $ref: model#/metadata/resource/kind - namespace: - $ref: model#/metadata/release/namespace - owner: - $ref: store#/route/params/user - resource: - $ref: model#/metadata/resource/name - version: - $ref: model#/metadata/resource/version - path: ${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/postgresopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=Reconfigure - - disabled: true - label: - text: labels.custom_config - onChange: onConfigurationSourceChange + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComPostgresAutoscaler/spec/storage/postgres/trigger + schema: temp/properties/storage/properties/postgres/properties/trigger + watcher: + func: onTriggerChange|storage/postgres + paths: + - temp/properties/storage/properties/postgres/properties/trigger + - type: label-element + 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: select + label: Mode + description: Select how the storage expansion should be handled. 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 - disabled: true - fetch: getSecrets - if: isEqualToDiscriminatorPath|use-existing-config|/configurationSource - label: - text: labels.name - schema: - $ref: schema#/properties/resources/properties/kubedbComPostgres/properties/spec/properties/configSecret/properties/name - type: select - type: single-step-form - type: single-step-form - type: single-step-form - id: custom-config - title: steps.8.label -- form: + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/storage/properties/postgres/properties/expansionMode + - type: block-layout + label: Postgres + showLabels: true + elements: + - type: threshold-input + label: UsageThreshold (%) + subtitle: Set the threshold percentage of storage usage to trigger scaling. + schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/storage/properties/postgres/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/storage/properties/postgres/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComPostgres/spec/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComPostgresAutoscaler/spec/storage/postgres/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/storage/properties/postgres/properties/scalingRules + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/storage/properties/postgres/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComPostgresAutoscaler/spec/storage/postgres/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/storage/properties/postgres/properties/upperBound + - type: block-layout + label: OpsRequest Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: monitoring + loader: initMonitoring elements: - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: Select Namespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getPostgresDbs - label: - text: Select Db - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: Select Type - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - discriminator: - topologyMachines: - default: [] - type: array + - type: label-element + label: To update Exporter Resource section click on Create OpsRequest + - type: anchor + label: Create OpsRequest + schema: temp/properties/opsRequestUrl + init: + type: func + value: getOpsRequestUrl|scale-vertically + - type: switch + label: Enable Monitoring + fullwidth: true + schema: temp/properties/enableMonitoring + init: + type: func + value: isValueExistInModel|/resources/kubedbComPostgres/spec/monitor + watcher: + func: onEnableMonitoringChange + paths: + - temp/properties/enableMonitoring + - type: block-layout + if: + type: function + name: showMonitoringSection elements: - - fetch: fetchTopologyMachines - if: returnFalse - schema: - $ref: discriminator#/topologyMachines - type: input - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComPostgresAutoscaler/spec/compute/postgres/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-max: - type: string - allowedMachine-min: - type: string - elements: - - computed: setAllowedMachine|min - disableUnselect: true - fetch: getMachines|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|postgres - schema: - $ref: discriminator#/properties/allowedMachine-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|max - disableUnselect: true - fetch: getMachines|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|postgres - schema: - $ref: discriminator#/properties/allowedMachine-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|postgres - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/properties/controlledResources - type: multiselect - - label: - text: Container Controlled Values - options: - - RequestsAndLimits - - RequestsOnly - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/properties/containerControlledValues - type: select - - elements: - - label: - text: ScalingFactor Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/properties/inMemoryStorage/properties/scalingFactorPercentage - type: input - - label: - text: Usage Threshold Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/properties/inMemoryStorage/properties/usageThresholdPercentage - type: input - label: - text: In Memory Storage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres/properties/inMemoryStorage - show_label: true - type: single-step-form - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres - type: single-step-form - label: - text: Postgres - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres - show_label: true - type: single-step-form - - elements: - - fetch: fetchNodeTopology - label: - text: Select NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name - type: select - - if: isNodeTopologySelected - label: - text: ScaleUp Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage - type: input - - if: isNodeTopologySelected - label: - text: ScaleDown Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage - type: input - if: hasNoAnnotations - label: - text: NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/nodeTopology - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: OpsRequest Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: compute-autoscaler - title: steps.9.label -- form: - elements: - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: Select Namespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getPostgresDbs - label: - text: Select Db - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: Select Type - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComPostgresAutoscaler/spec/storage/postgres/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/storage/properties/postgres/properties/trigger - type: select - - label: - text: Expansion Mode + - type: radio + label: Select a Monitoring Method + schema: schema/properties/resources/properties/kubedbComPostgres/properties/spec/properties/monitor/properties/agent + isHorizontal: true options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/storage/properties/postgres/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/storage/properties/postgres/properties/usageThreshold - type: input - - label: - text: Scaling Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/storage/properties/postgres/properties/scalingThreshold - type: input - - addFormLabel: Scaling Rules - element: + - text: Prometheus Operator + value: prometheus.io/operator + description: Inject metric exporter sidecar and creates a ServiceMonitor + - text: Custom ServiceMonitor + value: prometheus.io + description: Injects the metric exporter sidecar and let you customize ServiceMonitor + - text: Custom Scrapper + value: prometheus.io/builtin + description: Inject metric exporter sidecar and add Prometheus annotations to the stats Service + init: + type: static + value: prometheus.io/operator + watcher: + func: onAgentChange + paths: + - schema/properties/resources/properties/kubedbComPostgres/properties/spec/properties/monitor/properties/agent + - type: block-layout + label: ServiceMonitor Configuration + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComPostgres/spec/monitor/agent + elements: + - label: Scrapping Interval + schema: schema/properties/resources/properties/kubedbComPostgres/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval + type: input + - type: block-layout + label: Service Monitor + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComPostgres/spec/monitor/agent + elements: + - type: array-object-form + label: Endpoints + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/endpoints + buttonClass: is-light is-outlined elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/storage/properties/postgres/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/storage/properties/postgres/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComPostgresAutoscaler/spec/storage/postgres/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/storage/properties/postgres/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComPostgresAutoscaler/spec/storage/postgres/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/storage/properties/postgres/properties/upperBound - type: input - label: - text: Postgres - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/compute/properties/postgres - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: OpsRequest Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComPostgresAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: storage-autoscaler - title: steps.10.label -- form: - discriminator: - binding: - default: false - type: boolean + - type: switch + label: Honor labels + fullwidth: true + schema: honorLabels + - type: input + label: Interval + schema: interval + validation: + type: required + - type: input + label: Path + schema: path + validation: + type: required + - type: input + label: Port + schema: port + validation: + type: required + - type: select + multiple: true + label: Match Namespaces + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/namespaceSelector/properties/matchNames + loader: getResources|core|v1|namespaces + if: + type: function + name: returnFalse + - type: block-layout + showLabels: false + # schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector + if: + type: function + name: returnFalse + elements: + - type: object-item + label: Labels + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector/properties/matchLabels + - type: object-item + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/metadata/properties/labels + label : Labels + buttonClass: is-light is-outlined + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComPostgres/spec/monitor/agent + # individualItemDisabilityCheck: disableLableChecker + - type: label-element + label: Exporter Configuration + schema: '' + - type: switch + label: Customize Exporter Sidecar + fullwidth: true + schema: temp/properties/customizeExporter + init: + type: static + value: true + watcher: + func: onCustomizeExporterChange + paths: + - temp/properties/customizeExporter + - type: block-layout + label: Customer Exporter Section + showLabels: false + if: + type: function + name: showCustomizeExporterSection + elements: + - type: machine-compare + label: Resources + schema: schema/properties/resources/properties/kubedbComPostgres/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/resources + if: + type: function + name: returnFalse + - type: label-element + label: Security Context + schema: '' + - type: input + schema: schema/properties/resources/properties/kubedbComPostgres/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsUser + label: Run as User + - type: input + schema: schema/properties/resources/properties/kubedbComPostgres/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup + label: Run as Group + - type: input + schema: schema/properties/resources/properties/kubedbComPostgres/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/port + label: Port + - type: array-item-form + label: Args + schema: schema/properties/resources/properties/kubedbComPostgres/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args + buttonClass: is-light is-outlined + init: + type: static + value: ['--compatible-mode'] + element: + type: input + label: Args + # isSubsection: true + - type: block-layout + label: Metadata + showLabels: false + elements: + - type: array-object-form + init: + type: func + value: initEnvArray + label: Environment Variables + buttonClass: is-light is-outlined + watcher: + func: onEnvArrayChange + paths: + - temp/properties/env + schema: temp/properties/env + elements: + - type: input + label: Name + schema: name + validation: + type: required + - type: radio + label: Value From + schema: temp/properties/valueFromType + validation: + type: required + init: + type: func + value: setValueFrom + options: + - text: Input + value: input + - text: Secret + value: secret + - text: ConfigMap + value: configMap + watcher: + func: onValueFromChange + paths: + - temp/properties/valueFromType + - type: input + label: Value + schema: value + validation: + type: required + if: + name: isEqualToTemp|input + type: function + - type: select + if: + type: function + name: isEqualToTemp|configMap + label: ConfigMap Name + schema: valueFrom/properties/configMapKeyRef/properties/name + loader: + name: resourceNames|core|v1|configmaps + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: ConfigMap Key + schema: valueFrom/properties/configMapKeyRef/properties/key + if: + type: function + name: isEqualToTemp|configMap + loader: + name: getConfigMapKeys + watchPaths: + - schema/resources/kubedbComPostgres/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/configMapKeyRef/name + - schema/metadata/release/namespace + - type: select + label: Secret Name + schema: valueFrom/properties/secretKeyRef/properties/name + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecrets + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: Secret Key + schema: valueFrom/properties/secretKeyRef/properties/key + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecretKeys + watchPaths: + - schema/resources/kubedbComPostgres/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/secretKeyRef/name + - schema/metadata/release/namespace + + - type: single-step-form + id: binding elements: - - computed: isBindingAlreadyOn - label: - text: Expose Database - onChange: addOrRemoveBinding - schema: - $ref: discriminator#/properties/binding - type: switch - type: single-step-form - id: binding - title: Gateway Binding -type: multi-step-form + - type: switch + label: Expose Database + schema: temp/properties/binding + fullwidth: true + init: + type: func + value: isBindingAlreadyOn + watcher: + func: addOrRemoveBinding + paths: + - temp/properties/binding \ No newline at end of file diff --git a/charts/kubedbcom-postgres-editor/ui/functions.js b/charts/kubedbcom-postgres-editor/ui/functions.js index 2b184023c9..de023a6bc9 100644 --- a/charts/kubedbcom-postgres-editor/ui/functions.js +++ b/charts/kubedbcom-postgres-editor/ui/functions.js @@ -1,2821 +1,1584 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + // ************************* common functions ******************************************** // eslint-disable-next-line no-empty-pattern -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 disableLableChecker({ itemCtx }) { - const { key } = itemCtx - if (key.startsWith('app.kubernetes.io') || key.includes('helm')) return true - else return false -} - -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} - -async function getResources({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, + /********** 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', '') + + /****** Backup Configuration *********/ + + function initScheduleBackupForEdit() { + const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( + getValue, + model, ) - const resources = (resp && resp.data && resp.data.items) || [] + initRepositoryChoiseForEdit() - 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 [] + if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' + else return 'no' } -} - -function isEqualToDiscriminatorPath( - { discriminator, getValue, watchDependency }, - value, - discriminatorPath, -) { - watchDependency('discriminator#' + discriminatorPath) - const discriminatorValue = getValue(discriminator, discriminatorPath) - return discriminatorValue === value -} - -function setValueFromModel({ getValue, model }, path) { - return getValue(model, path) -} - -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 } }, - }, - }) + function initScheduleBackup() { + const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( + getValue, + model, + ) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' + else return 'no' } - return ans -} + function onScheduleBackupChange() { + const scheduleBackup = getValue(discriminator, '/scheduleBackup') -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + if (scheduleBackup === 'no') { + // delete stashAppscodeComBackupConfiguration + commit('wizard/model$delete', '/resources/stashAppscodeComBackupConfiguration') + commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') + // delete annotation from kubedbComPostgres annotation + deleteKubeDbComPostgresDbAnnotation() + } else { + const { isBluePrint } = getBackupConfigsAndAnnotations(getValue, model) - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` + // create stashAppscodeComBackupConfiguration and initialize it if not exists - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }) + const dbName = getValue(model, '/metadata/release/name') - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + 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, + }) + } + } } - return ans -} - -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - 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) - }) + function valueExists(value, getValue, path) { + const val = getValue(value, path) + if (val) return true + else return false } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + function getBackupConfigsAndAnnotations(getValue, model) { + const stashAppscodeComBackupConfiguration = getValue( + model, + '/resources/stashAppscodeComBackupConfiguration', + ) + const kubedbComPostgresAnnotations = + getValue(model, '/resources/kubedbComPostgres/metadata/annotations') || {} -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) - - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) - } + const isBluePrint = Object.keys(kubedbComPostgresAnnotations).some( + (k) => + k === 'stash.appscode.com/backup-blueprint' || + k === 'stash.appscode.com/schedule' || + k.startsWith('params.stash.appscode.com/'), + ) - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' return { - text: name, - value: name, + stashAppscodeComBackupConfiguration, + isBluePrint, } - }) -} - -function returnTrue() { - return true -} - -function returnStringYes() { - return 'yes' -} - -// ************************* Basic Info ********************************************** -async function getPostgresVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, - }, - }, } - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) - - const resources = (resp && resp.data && resp.data.items) || [] - - // keep only non deprecated versions - const filteredMongoDbVersions = resources.filter((item) => item.spec && !item.spec.deprecated) - - filteredMongoDbVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true + function deleteKubeDbComPostgresDbAnnotation() { + const annotations = getValue(model, '/resources/kubedbComPostgres/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] }) - return filteredMongoDbVersions - } catch (e) { - console.log(e) - return [] - } -} - -// ************************* Auth Secret Field ****************************************** -function showAuthPasswordField({ model, getValue, watchDependency }) { - watchDependency('model#/resources') - const modelPathValue = getValue(model, '/resources') - return !!( - modelPathValue && - modelPathValue.secret && - modelPathValue.secret.metadata && - modelPathValue.secret.metadata.name && - !showAuthSecretField({ model, getValue, watchDependency }) - ) -} - -function showAuthSecretField({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComPostgres/spec') - const modelPathValue = getValue(model, '/resources/kubedbComPostgres/spec') - return !!(modelPathValue && modelPathValue.authSecret && modelPathValue.authSecret.name) -} - -function showNewSecretCreateField({ model, getValue, watchDependency, commit }) { - const resp = - !showAuthSecretField({ model, getValue, watchDependency }) && - !showAuthPasswordField({ model, getValue, watchDependency }) - const secret = getValue(model, '/resources/secret_auth') - if (resp && !secret) { commit('wizard/model$update', { - path: '/resources/secret_auth', - value: { - data: { - password: '', - }, - }, - force: true, + path: '/resources/kubedbComPostgres/metadata/annotations', + value: filteredAnnotations, }) } - return resp -} -function getClientAuthModes({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComPostgres/spec/version') + function showBackupForm() { + const scheduleBackup = getValue(discriminator, '/scheduleBackup') + // watchDependency('discriminator#/scheduleBackup') + if (scheduleBackup === 'yes') return true + else return false + } - const version = getValue(model, '/resources/kubedbComPostgres/spec/version') - // major version section from version - const major = parseInt(version && version.split('.')[0]) + 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 = {} + let showStoragememory = false + + 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/kubedbComPostgres') + initialDbMetadata = objectCopy(dbResource.metadata) + initialArchiver = dbResource.spec?.archiver ? objectCopy(dbResource.spec?.archiver) : undefined - const options = ['md5', 'cert'] + // 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 - if (major >= 11) { - options.push('scram') - } + let url = `/clusters/${user}/${cluster}/helm/packageview/values?name=${chartName}&sourceApiGroup=${sourceApiGroup}&sourceKind=${sourceKind}&sourceNamespace=${sourceNamespace}&sourceName=${sourceName}&version=${chartVersion}&format=json` - return options.map((item) => ({ text: item, value: item })) -} + if (spoke) + url = `/clusters/${user}/${spoke}/helm/packageview/values?name=${chartName}&sourceApiGroup=${sourceApiGroup}&sourceKind=${sourceKind}&sourceNamespace=${sourceNamespace}&sourceName=${sourceName}&version=${chartVersion}&format=json` -function onVersionChange({ model, getValue, commit }) { - const version = getValue(model, '/resources/kubedbComPostgres/spec/version') - const major = parseInt(version && version.split('.')[0]) - const defaultValue = major >= 11 ? 'scram' : 'md5' + const resp = await axios.get(url) - commit('wizard/model$update', { - path: '/resources/kubedbComPostgres/spec/clientAuthMode', - value: defaultValue, - force: true, - }) -} + valuesFromWizard = objectCopy(resp.data?.resources?.coreKubestashComBackupConfiguration) || {} + } catch (e) { + console.log(e) + } -// ********************* Database Mode *********************** -function setDatabaseMode({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/resources/kubedbComPostgres/spec/replicas') - watchDependency('model#/resources/kubedbComPostgres/spec/replicas') + // 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) + } + } - if (modelPathValue > 1) { - return 'Cluster' - } else { - return 'Standalone' - } -} + // 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, + ) -let storageClassList = [] -async function getStorageClassNames({ axios, storeGet, commit, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + // 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, + ) - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/storage.k8s.io/v1/storageclasses`, - { - params: { - filter: { items: { metadata: { name: null, annotations: null } } }, - }, - }, - ) + // set backup switch here + isBackupOn = !!config - const resources = (resp && resp.data && resp.data.items) || [] + // set initial data from stash-presets + const stashPreset = storeGet('/backup/stashPresets') + if (stashPreset) { + const { retentionPolicy, encryptionSecret, schedule, storageRef } = stashPreset - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) + const tempBackends = valuesFromWizard.spec?.backends + tempBackends[0]['storageRef'] = storageRef + tempBackends[0]['retentionPolicy'] = retentionPolicy + valuesFromWizard.spec['backends'] = tempBackends - storageClassList = resources - const initialStorageClass = getValue( - model, - '/resources/kubedbComPostgres/spec/storage/storageClassName', - ) - if (!initialStorageClass) setStorageClass({ model, getValue, commit }) - return resources -} + 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}` -function setStorageClass({ model, getValue, commit }) { - const deletionPolicy = getValue(model, '/resources/kubedbComPostgres/spec/deletionPolicy') || '' - let storageClass = - getValue(model, '/resources/kubedbComPostgres/spec/storage/storageClassName') || '' - const suffix = '-retain' + tempSessions[0]['repositories'] = tempRepositories + tempSessions[0]['scheduler']['schedule'] = schedule + valuesFromWizard.spec['sessions'] = tempSessions + } - const simpleClassList = storageClassList.filter((item) => { - return !item.metadata?.name?.endsWith(suffix) - }) + 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, + } - const retainClassList = storageClassList.filter((item) => { - return item.metadata?.name?.endsWith(suffix) - }) + setDiscriminatorValue('isBackupDataLoaded', true) + } - const defaultSimpleList = simpleClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] - ) - }) + function isBackupDataLoadedTrue() { + // watchDependency('discriminator#/isBackupDataLoaded') + return !!getValue(discriminator, '/isBackupDataLoaded') + } - const defaultRetainList = retainClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] - ) - }) - - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - if (simpleClassList.length > 1) { - const found = defaultSimpleList.length ? defaultSimpleList[0] : simpleClassList[0] - storageClass = found.value - } else if (simpleClassList.length === 1) { - storageClass = simpleClassList[0]?.value - } else { - const found = defaultRetainList.length - ? defaultRetainList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found - } - } else { - if (retainClassList.length > 1) { - const found = defaultRetainList.length ? defaultRetainList[0] : retainClassList[0] - storageClass = found.value - } else if (retainClassList.length === 1) { - storageClass = retainClassList[0]?.value - } else { - const found = defaultSimpleList.length - ? defaultSimpleList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found + 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 } - if (storageClass) { + function onBackupTypeChange() { + const type = getValue(discriminator, '/backupType') commit('wizard/model$update', { - path: '/resources/kubedbComPostgres/spec/storage/storageClassName', - value: storageClass, + path: '/backupType', + value: type, force: true, }) - } -} - -function deleteDatabaseModePath({ discriminator, getValue, commit, model }) { - const mode = getValue(discriminator, '/activeDatabaseMode') - if (mode === 'Cluster') { - replicas = getValue(model, '/resources/kubedbComPostgres/spec/replicas') - if (!replicas) { + if (!isBackupOnModel) { + commit('wizard/model$delete', '/resources/coreKubestashComBackupConfiguration') + } else { commit('wizard/model$update', { - path: '/resources/kubedbComPostgres/spec/replicas', - value: 3, + path: '/resources/coreKubestashComBackupConfiguration', + value: objectCopy(initialModel), force: true, }) } - } else if (mode === 'Standalone') { - commit('wizard/model$delete', '/resources/kubedbComPostgres/spec/replicas') - commit('wizard/model$delete', '/resources/kubedbComPostgres/spec/standbyMode') - commit('wizard/model$delete', '/resources/kubedbComPostgres/spec/leaderElectiion') + commit('wizard/model$delete', '/context') + commit('wizard/model$update', { + path: '/resources/kubedbComPostgres', + value: objectCopy(dbResource), + force: true, + }) } -} - -function isEqualToDatabaseMode({ getValue, watchDependency, discriminator }, value) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - return mode === value -} - -// ************************** TLS ******************************88 - -function setApiGroup() { - return 'cert-manager.io' -} -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - watchDependency('model#/resources/kubedbComPostgres/spec/tls/issuerRef/apiGroup') - watchDependency('model#/resources/kubedbComPostgres/spec/tls/issuerRef/kind') - watchDependency('model#/metadata/release/namespace') - const apiGroup = getValue(model, '/resources/kubedbComPostgres/spec/tls/issuerRef/apiGroup') - const kind = getValue(model, '/resources/kubedbComPostgres/spec/tls/issuerRef/kind') - const namespace = getValue(model, '/metadata/release/namespace') + function isBackupType(type) { + // watchDependency('discriminator#/backupType') + const selectedType = getValue(discriminator, '/backupType') - let url - if (kind === 'Issuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/namespaces/${namespace}/issuers` - } else if (kind === 'ClusterIssuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/clusterissuers` + return selectedType === type } - if (!url) return [] + function setBlueprintSwitch() { + const annotations = initialDbMetadata?.annotations - try { - const resp = await axios.get(url) + return !!( + annotations['blueprint.kubestash.com/name'] && + annotations['blueprint.kubestash.com/namespace'] + ) + } - const resources = (resp && resp.data && resp.data.items) || [] + function onBlueprintChange() { + const blueprintSwitch = getValue(discriminator, '/blueprintEnabled') + if (blueprintSwitch) addLabelAnnotation('annotations') + else deleteLabelAnnotation('annotations') + } - 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 setArchiverSwitch() { + const archiver = dbResource?.spec?.archiver + return !!archiver } -} -async function hasIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await getIssuerRefsName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) + function onArchiverChange() { + const archiverSwitch = getValue(discriminator, '/archiverEnabled') + const path = 'resources/kubedbComPostgres/spec/archiver' + if (archiverSwitch) { + commit('wizard/model$update', { + path: path, + value: initialArchiver ? initialArchiver : archiverObjectToCommit, + }) + } else { + commit('wizard/model$delete', path) + } + } - return !!(resp && resp.length) -} + function addLabelAnnotation(type) { + const obj = objectCopy(initialDbMetadata[type]) -async function hasNoIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await hasIssuerRefName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) + 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' + } - return !resp -} + commit('wizard/model$update', { + path: `/resources/kubedbComPostgres/metadata/${type}`, + value: obj, + force: true, + }) + } -function setSSLMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComPostgres/spec/sslMode') - return val || 'require' -} + function deleteLabelAnnotation(type) { + const obj = initialDbMetadata[type] -function showTlsConfigureSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configureTLS') - const configureStatus = getValue(discriminator, '/configureTLS') - return configureStatus -} + if (type === 'annotations') { + delete obj['blueprint.kubestash.com/name'] + delete obj['blueprint.kubestash.com/namespace'] + } else delete obj['kubedb.com/archiver'] -function onTlsConfigureChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/configureTLS') - if (configureStatus) { commit('wizard/model$update', { - path: '/resources/kubedbComPostgres/spec/tls', - value: { issuerRef: {}, certificates: [] }, + path: `/resources/kubedbComPostgres/metadata/${type}`, + value: obj, force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComPostgres/spec/tls') - commit('wizard/model$delete', '/resources/kubedbComPostgres/spec/sslMode') } -} - -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} -/****** Monitoring *********/ - -function showMonitoringSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/enableMonitoring') - const configureStatus = getValue(discriminator, '/enableMonitoring') - return configureStatus -} + function getContext() { + if (isBackupOn) return ['Create', 'Delete', 'Modify'] + return ['Create'] + } -function onEnableMonitoringChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/enableMonitoring') - if (configureStatus) { + function onContextChange() { + const context = getValue(discriminator, '/backupConfigContext') commit('wizard/model$update', { - path: '/resources/kubedbComPostgres/spec/monitor', - value: {}, + path: '/context', + value: context, force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComPostgres/spec/monitor') + if (context === 'Create') { + commit('wizard/model$update', { + path: '/resources/coreKubestashComBackupConfiguration', + value: valuesFromWizard, + force: true, + }) + } + if (context === 'Delete') setDiscriminatorValue('hidePreviewFromWizard', true) + else setDiscriminatorValue('hidePreviewFromWizard', undefined) } - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: configureStatus ? 'warning' : 'none', - force: true, - }) -} + 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 showCustomizeExporterSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/customizeExporter') - const configureStatus = getValue(discriminator, '/customizeExporter') - return configureStatus -} + function onConfigChange() { + const configName = getValue(discriminator, '/config') + const configs = objectCopy(backupConfigurationsFromStore) + const configDetails = configs?.find((item) => item?.metadata?.name === configName) -function onCustomizeExporterChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/customizeExporter') - if (configureStatus) { commit('wizard/model$update', { - path: '/resources/kubedbComPostgres/spec/monitor/prometheus/exporter', - value: {}, + path: '/resources/coreKubestashComBackupConfiguration', + value: configDetails, force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComPostgres/spec/monitor/prometheus/exporter') } -} -// ********************************* Initialization & Backup ************************************* -const stashAppscodeComRestoreSession_init = { - spec: { - repository: { - name: '', - }, - rules: [ - { - snapshots: ['latest'], - }, - ], - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} -const initScript = { - scriptPath: '', - secret: { - secretName: '', - }, -} -const stashAppscodeComRepository_init_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const stashAppscodeComRepository_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const restoreSessionInitRunTimeSettings = { - container: { - resources: { - requests: { - cpu: '', - memory: '', - }, - limits: { - cpu: '', - memory: '', - }, - }, - nice: { - adjustment: null, - }, - ionice: { - class: null, - classData: null, - }, - securityContext: { - privileged: false, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - env: [], - envFrom: [], - }, - pod: { - serviceAccountName: '', - imagePullSecrets: [], - securityContext: { - fsGroup: null, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - }, -} + function showPause() { + // watchDependency('discriminator#/backupConfigContext') + // watchDependency('discriminator#/config') + const contex = getValue(discriminator, '/backupConfigContext') + const configName = getValue(discriminator, '/config') + return !!configName && contex === 'Modify' + } -const stashAppscodeComBackupConfiguration = { - spec: { - repository: { - name: '', - }, - retentionPolicy: { - keepLast: 5, - name: 'keep-last-5', - prune: true, - }, - schedule: '*/5 * * * *', - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} + 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 disableInitializationSection({ model, getValue, watchDependency }) { - const initialized = getValue(model, '/resources/kubedbComPostgres/spec/init/initialized') - watchDependency('model#/resources/kubedbComPostgres/spec/init/initialized') - return !!initialized -} + function showConfigList() { + // watchDependency('discriminator#/backupConfigContext') + const contex = getValue(discriminator, '/backupConfigContext') + return contex === 'Modify' || contex === 'Delete' + } -function valueExists(value, getValue, path) { - const val = getValue(value, path) - if (val) return true - else return false -} + 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 initPrePopulateDatabase({ getValue, model }) { - const waitForInitialRestore = getValue( - model, - '/resources/kubedbComPostgres/spec/init/waitForInitialRestore', - ) - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - const script = getValue(model, '/resources/kubedbComPostgres/spec/init/script') + function showScheduleBackup() { + const operationQuery = storeGet('/route/params/actions') || '' + const isBackupOperation = operationQuery === 'edit-self-backupconfiguration' ? true : false + return !isBackupOperation + } - return waitForInitialRestore || !!stashAppscodeComRestoreSession_init || !!script ? 'yes' : 'no' -} + 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 onPrePopulateDatabaseChange({ commit, getValue, discriminator, model }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - if (prePopulateDatabase === 'no') { - // delete related properties - commit('wizard/model$update', { - path: '/resources/kubedbComPostgres/spec/init/waitForInitialRestore', - value: false, - }) - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - commit('wizard/model$delete', '/resources/kubedbComPostgres/spec/init/script') - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else { - const dbName = getValue(model, '/metadata/release/name') - // set stashAppscodeComRestoreSession_init if it doesn't exist - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { + 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: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - force: true, + path: modelPath, + value: session, }) + } + } + + 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/kubedbComPostgres/metadata/labels') + const bindingValues = { + apiVersion: 'catalog.appscode.com/v1alpha1', + kind: 'PostgresBinding', + metadata: { + labels, + name: dbName, + namespace: dbNamespace, + }, + spec: { + sourceRef: { + name: dbName, + namespace: dbNamespace, + }, + }, + } + if (value) { commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, + path: '/resources/catalogAppscodeComPostgresBinding', + value: bindingValues, force: true, }) + } else { + commit('wizard/model$delete', '/resources/catalogAppscodeComPostgresBinding') } } -} -function initDataSource({ getValue, model }) { - const script = getValue(model, '/resources/kubedbComPostgres/spec/init/script') - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) + function isBindingAlreadyOn() { + const value = getValue(model, '/resources') + const keys = Object.keys(value) + const isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComPostgresBinding') + return isExposeBinding + } - if (script) return 'script' - else if (stashAppscodeComRestoreSession_init) return 'stashBackup' - else return undefined -} + function objectCopy(obj) { + const temp = JSON.stringify(obj) + return JSON.parse(temp) + } -function onDataSourceChange({ commit, getValue, discriminator, model }) { - const dataSource = getValue(discriminator, '/dataSource') + /****** Compute Autoscaller *********/ - commit('wizard/model$update', { - path: '/resources/kubedbComPostgres/spec/init/waitForInitialRestore', - value: dataSource === 'stashBackup', - force: true, - }) + let autoscaleType = '' + let dbDetails = {} + let instance = '' - if (dataSource === 'script') { - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') + async function getDbDetails() { + const annotations = getValue( + model, + '/resources/autoscalingKubedbComPostgresAutoscaler/metadata/annotations', + ) + instance = annotations?.['kubernetes.io/instance-type'] + + const owner = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + + const namespace = + storeGet('/route/query/namespace') || + getValue(model, '/resources/autoscalingKubedbComPostgresAutoscaler/metadata/namespace') || + '' + const name = + storeGet('/route/params/name') || + getValue(model, '/resources/autoscalingKubedbComPostgresAutoscaler/spec/databaseRef/name') || + '' + + if (namespace && name) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/postgreses/${name}`, + ) + dbDetails = resp.data || {} + showStoragememory = dbDetails?.spec?.storageEngine === 'inMemory' + console.log('showStoragememory', showStoragememory) + + setDiscriminatorValue('/dbDetails', true) + } catch (e) { + console.log(e) + } + } - // create a new script if there is no script property - if (!valueExists(model, getValue, '/resources/kubedbComPostgres/spec/init/script')) - commit('wizard/model$update', { - path: '/resources/kubedbComPostgres/spec/init/script', - value: initScript, - }) - } else if (dataSource === 'stashBackup') { - commit('wizard/model$delete', '/resources/kubedbComPostgres/spec/init/script') + commit('wizard/model$update', { + path: `/metadata/release/name`, + value: name, + force: true, + }) + commit('wizard/model$update', { + path: `/metadata/release/namespace`, + value: namespace, + force: true, + }) + commit('wizard/model$update', { + path: `/resources/autoscalingKubedbComPostgresAutoscaler/spec/databaseRef/name`, + value: name, + force: true, + }) + commit('wizard/model$update', { + path: `/resources/autoscalingKubedbComPostgresAutoscaler/metadata/labels`, + value: dbDetails.metadata.labels, + force: true, + }) + } - // create a new stashAppscodeComRestoreSession_init if there is no stashAppscodeComRestoreSession_init property - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - const dbName = getValue(model, '/metadata/release/name') + function isKubedb() { + return !!storeGet('/route/params/actions') + } - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - }) + function isConsole() { + const isKube = isKubedb() + if (isKube) { + const dbName = storeGet('/route/params/name') || '' commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', + path: '/resources/autoscalingKubedbComPostgresAutoscaler/spec/databaseRef/name', value: dbName, force: true, }) - } - } -} - -// // for script -function initVolumeType({ getValue, model }) { - const configMap = getValue(model, '/resources/kubedbComPostgres/spec/init/script/configMap/name') - const secret = getValue(model, '/resources/kubedbComPostgres/spec/init/script/secret/secretName') - - if (configMap) return 'configMap' - else if (secret) return 'secret' - else return undefined -} - -function onVolumeTypeChange({ commit, getValue, discriminator, model }) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - if (sourceVolumeType === 'configMap') { - // add configMap object and delete secret object - commit('wizard/model$delete', '/resources/kubedbComPostgres/spec/init/script/secret') - - if (!valueExists(model, getValue, '/resources/kubedbComPostgres/spec/init/script/configMap')) { + 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/kubedbComPostgres/spec/init/script/configMap', - value: { - name: '', - }, + path: '/resources/autoscalingKubedbComPostgresAutoscaler/metadata/name', + value: modifiedName, + force: true, }) + const namespace = storeGet('/route/query/namespace') || '' + if (namespace) { + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComPostgresAutoscaler/metadata/namespace', + value: namespace, + force: true, + }) + } } - } else if (sourceVolumeType === 'secret') { - // delete configMap object and add secret object - commit('wizard/model$delete', '/resources/kubedbComPostgres/spec/init/script/configMap') - if (!valueExists(model, getValue, '/resources/kubedbComPostgres/spec/init/script/secret')) { - commit('wizard/model$update', { - path: '/resources/kubedbComPostgres/spec/init/script/secret', - value: { - secretName: '', - }, - }) - } + return !isKube } -} - -function showInitializationForm({ getValue, discriminator, watchDependency }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - watchDependency('discriminator#/prePopulateDatabase') - return prePopulateDatabase === 'yes' -} - -function showScriptOrStashForm({ getValue, discriminator, watchDependency }, value) { - const dataSource = getValue(discriminator, '/dataSource') - watchDependency('discriminator#/dataSource') - return dataSource === value -} - -function showConfigMapOrSecretName({ getValue, discriminator, watchDependency }, value) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - watchDependency('discriminator#/sourceVolumeType') - return sourceVolumeType === value -} -// for stash backup -function initializeNamespace({ getValue, model }) { - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} + async function getNamespaces() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function showRepositorySelectOrCreate({ getValue, discriminator, watchDependency }, value) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, + }) - return repositoryChoise === value -} + const resources = (resp && resp.data && resp.data.items) || [] -function onInitRepositoryChoiseChange({ getValue, discriminator, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - if (repositoryChoise === 'select') { - // delete stashAppscodeComRepository_init_repo from model - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else if (repositoryChoise === 'create') { - // add stashAppscodeComRepository_init_repo to model - commit('wizard/model$update', { - path: 'resources/stashAppscodeComRepository_init_repo', - value: stashAppscodeComRepository_init_repo, + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } }) + } - const repositoryName = `${getValue(model, '/metadata/release/name')}-init-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: repositoryName, - }) + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found } -} -function initCustomizeRestoreJobRuntimeSettings({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} + // function onNamespaceChange() { + // const namespace = getValue(model, '/metadata/release/namespace') + // const agent = getValue(model, '/resources/kubedbComPostgres/spec/monitor/agent') + // if (agent === 'prometheus.io') { + // commit('wizard/model$update', { + // path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + // value: [namespace], + // force: true, + // }) + // } + // } -function initCustomizeRestoreJobRuntimeSettingsForBackup({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} + async function getPostgresDbs() { + // watchDependency('model#/resources/autoscalingKubedbComPostgresAutoscaler/metadata/namespace') + const namespace = getValue( + model, + '/resources/autoscalingKubedbComPostgresAutoscaler/metadata/namespace', + ) + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function onCustomizeRestoreJobRuntimeSettingsChange({ commit, getValue, discriminator, model }) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/postgreses`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - value: restoreSessionInitRunTimeSettings, - }) - } + + 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 onCustomizeRestoreJobRuntimeSettingsChangeForBackup({ - commit, - getValue, - discriminator, - model, -}) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - ) { - // set new value + function initMetadata() { + const dbName = + getValue(model, '/resources/autoscalingKubedbComPostgresAutoscaler/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/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - value: {}, + path: '/resources/autoscalingKubedbComPostgresAutoscaler/metadata/name', + value: modifiedName, force: true, }) - } - } -} - -function showRuntimeForm({ discriminator, getValue, watchDependency }, value) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - watchDependency('discriminator#/customizeRestoreJobRuntimeSettings') - return customizeRestoreJobRuntimeSettings === value -} -async function getImagePullSecrets({ getValue, model, watchDependency, axios, storeGet }) { - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') + // delete the other type object from vuex wizard model + if (type === 'compute') + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComPostgresAutoscaler/spec/storage', + ) + if (type === 'storage') + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComPostgresAutoscaler/spec/compute', + ) + } - let resources = await getNamespacedResourceList(axios, storeGet, { - namespace, - group: 'core', - version: 'v1', - resource: 'secrets', - }) + async function fetchTopologyMachines() { + const instance = hasAnnotations() - resources = resources.filter((item) => { - const validType = ['kubernetes.io/dockerconfigjson'] - return validType.includes(item.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) - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: { name: name }, + 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' + } -// FOR Backup Configuration + function onTriggerChange(type) { + const trigger = getValue(discriminator, `/${type}/trigger`) + const commitPath = `/resources/autoscalingKubedbComPostgresAutoscaler/spec/${type}/trigger` -// schedule bakcup + commit('wizard/model$update', { + path: commitPath, + value: trigger ? 'On' : 'Off', + force: true, + }) + } -function getBackupConfigsAndAnnotations(getValue, model) { - const stashAppscodeComBackupConfiguration = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration', - ) - const kubedbComPostgresAnnotations = - getValue(model, '/resources/kubedbComPostgres/metadata/annotations') || {} - - const isBluePrint = Object.keys(kubedbComPostgresAnnotations).some( - (k) => - k === 'stash.appscode.com/backup-blueprint' || - k === 'stash.appscode.com/schedule' || - k.startsWith('params.stash.appscode.com/'), - ) + function hasAnnotations() { + const annotations = + getValue(model, '/resources/autoscalingKubedbComPostgresAutoscaler/metadata/annotations') || + {} + const instance = annotations['kubernetes.io/instance-type'] - return { - stashAppscodeComBackupConfiguration, - isBluePrint, + return !!instance } -} -function deleteKubeDbComPostgresDbAnnotation(getValue, model, commit) { - const annotations = getValue(model, '/resources/kubedbComPostgres/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/kubedbComPostgres/metadata/annotations', - value: filteredAnnotations, - }) -} + function setAllowedMachine(minmax) { + const mx = instance?.includes(',') ? instance.split(',')[1] : '' + const mn = instance?.includes(',') ? instance.split(',')[0] : '' + const machineName = minmax === 'min' ? mn : mx -function addKubeDbComPostgresDbAnnotation(getValue, model, commit, key, value, force) { - const annotations = getValue(model, '/resources/kubedbComPostgres/metadata/annotations') || {} + // Find the machine details from topologyMachines + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] + const machineData = nodeGroups.find((item) => item.topologyValue === machineName) - if (annotations[key] === undefined) { - annotations[key] = value - } else if (force) { - annotations[key] = value + // 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: '', + } } - commit('wizard/model$update', { - path: '/resources/kubedbComPostgres/metadata/annotations', - value: annotations, - force: true, - }) -} + function getMachines(minmax) { + // watchDependency('discriminator#/topologyMachines') + const depends = minmax === 'min' ? 'max' : 'min' + const dependantPath = `/allowedMachine-${depends}` -function initScheduleBackupForEdit({ getValue, model, setDiscriminatorValue }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) + // watchDependency(`discriminator#${dependantPath}`) + const dependantMachineObj = getValue(discriminator, dependantPath) + const dependantMachine = dependantMachineObj?.machine || '' - initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} + const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) -function initScheduleBackup({ getValue, model }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) + // 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, + }, + } + }) - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} + const filteredMachine = machines?.filter((item, ind) => + minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, + ) -function onScheduleBackupChange({ commit, getValue, discriminator, model }) { - const scheduleBackup = getValue(discriminator, '/scheduleBackup') + return dependantIndex === -1 ? machines : filteredMachine + } - if (scheduleBackup === 'no') { - // delete stashAppscodeComBackupConfiguration - commit('wizard/model$delete', '/resources/stashAppscodeComBackupConfiguration') - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') - // delete annotation from kubedbComPostgres annotation - deleteKubeDbComPostgresDbAnnotation(getValue, model, commit) - } else { - const { isBluePrint } = getBackupConfigsAndAnnotations(getValue, model) + function onMachineChange(type) { + const annoPath = '/resources/autoscalingKubedbComPostgresAutoscaler/metadata/annotations' + const annotations = getValue(model, annoPath) || {} + const instance = annotations['kubernetes.io/instance-type'] - // create stashAppscodeComBackupConfiguration and initialize it if not exists + // 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 - const dbName = getValue(model, '/metadata/release/name') + // 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/autoscalingKubedbComPostgresAutoscaler/spec/compute/${type}` - if ( - !valueExists(model, getValue, '/resources/stashAppscodeComBackupConfiguration') && - !isBluePrint - ) { + if (minMachine && maxMachine && instance !== minMaxMachine) { commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration', - value: stashAppscodeComBackupConfiguration, + path: `${allowedPath}/maxAllowed`, + value: maxMachineAllocatable, + force: true, }) commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, + path: `${allowedPath}/minAllowed`, + value: minMachineAllocatable, + force: true, + }) + commit('wizard/model$update', { + path: annoPath, + value: { ...annotations }, force: true, }) } } -} -// backup form -function showBackupForm({ getValue, discriminator, watchDependency }) { - const scheduleBackup = getValue(discriminator, '/scheduleBackup') - watchDependency('discriminator#/scheduleBackup') + function hasNoAnnotations() { + return !hasAnnotations() + } - if (scheduleBackup === 'yes') return true - else return false -} + function setControlledResources(type) { + const list = ['cpu', 'memory'] + const path = `/resources/autoscalingKubedbComPostgresAutoscaler/spec/compute/${type}/controlledResources` + commit('wizard/model$update', { + path: path, + value: list, + force: true, + }) + return list + } -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({ commit, storeGet, axios, getValue, model, setDiscriminatorValue }) { - // 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/kubedbComPostgres') - 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}` + 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 archAnnotation = resp.data?.metadata?.annotations - const annotationKeyToFind = `${resource}.${group}/archiver` - if (archAnnotation[annotationKeyToFind]) { - isArchiverAvailable = true - archiverObjectToCommit = { - ref: { - name: archAnnotation[annotationKeyToFind], - namespace: 'kubedb', - }, - } - } + 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 [] } - // 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, - ) + function isNodeTopologySelected() { + // watchDependency( + // 'model#/resources/autoscalingKubedbComPostgresAutoscaler/spec/compute/nodeTopology/name', + // ) + const nodeTopologyName = + getValue( + model, + '/resources/autoscalingKubedbComPostgresAutoscaler/spec/compute/nodeTopology/name', + ) || '' + return !!nodeTopologyName.length + } - // 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, + function showOpsRequestOptions() { + if (isKubedb() === true) return true + // watchDependency('model#/resources/autoscalingKubedbComPostgresAutoscaler/spec/databaseRef/name') + // watchDependency('discriminator#/autoscalingType') + return ( + !!getValue( + model, + '/resources/autoscalingKubedbComPostgresAutoscaler/spec/databaseRef/name', + ) && !!getValue(discriminator, '/autoscalingType') ) + } - // 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 + function setApplyToIfReady() { + return 'IfReady' } - 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, + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value } - setDiscriminatorValue('isBackupDataLoaded', true) -} + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function isBackupDataLoadedTrue({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/isBackupDataLoaded') - return !!getValue(discriminator, '/isBackupDataLoaded') -} + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) -async function setBackupType() { - return 'BackupConfig' -} + const resources = (resp && resp.data && resp.data.items) || [] -async 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?.replicas !== 1 && isArchiverAvailable) { - arr.push({ - description: 'Enable/Disable Archiver', - text: 'Archiver', - value: 'Archiver', - }) + 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 [] + } } - return arr -} -function onBackupTypeChange({ commit, getValue, discriminator }) { - 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') + async function getNamespacedResourceList( + axios, + storeGet, + { namespace, group, version, resource }, + ) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - commit('wizard/model$update', { - path: '/resources/kubedbComPostgres', - value: objectCopy(dbResource), - force: true, - }) -} + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` -function isBackupType({ watchDependency, getValue, discriminator }, type) { - watchDependency('discriminator#/backupType') - const selectedType = getValue(discriminator, '/backupType') + let ans = [] + try { + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) - return selectedType === type -} + const items = (resp && resp.data && resp.data.items) || [] + ans = items + } catch (e) { + console.log(e) + } -function setBlueprintSwitch() { - const annotations = initialDbMetadata?.annotations + return ans + } - return !!( - annotations['blueprint.kubestash.com/name'] && annotations['blueprint.kubestash.com/namespace'] - ) -} + /****** Monitoring *********/ -function onBlueprintChange({ getValue, discriminator, commit, model, storeGet }) { - const blueprintSwitch = getValue(discriminator, '/blueprintEnabled') - if (blueprintSwitch) addLabelAnnotation(commit, storeGet, 'annotations') - else deleteLabelAnnotation(commit, 'annotations') -} + function showMonitoringSection() { + // watchDependency('discriminator#/enableMonitoring') + const configureStatus = getValue(discriminator, '/enableMonitoring') + return configureStatus + } -function setArchiverSwitch() { - const archiver = dbResource?.spec?.archiver - return !!archiver -} + function onEnableMonitoringChange() { + const configureStatus = getValue(discriminator, '/enableMonitoring') + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComPostgres/spec/monitor', + value: {}, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/kubedbComPostgres/spec/monitor') + } -function onArchiverChange({ getValue, discriminator, commit, model, storeGet }) { - const archiverSwitch = getValue(discriminator, '/archiverEnabled') - const path = 'resources/kubedbComPostgres/spec/archiver' - if (archiverSwitch) { + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: path, - value: initialArchiver ? initialArchiver : archiverObjectToCommit, + path: '/form/alert/enabled', + value: configureStatus ? 'warning' : 'none', + force: true, }) - } else { - commit('wizard/model$delete', path) } -} - -function addLabelAnnotation(commit, storeGet, 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' + function showCustomizeExporterSection() { + // watchDependency('discriminator#/customizeExporter') + const configureStatus = getValue(discriminator, '/customizeExporter') + return configureStatus } - commit('wizard/model$update', { - path: `/resources/kubedbComPostgres/metadata/${type}`, - value: obj, - force: true, - }) -} + function onCustomizeExporterChange() { + const configureStatus = getValue(discriminator, '/customizeExporter') + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComPostgres/spec/monitor/prometheus/exporter', + value: {}, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/kubedbComPostgres/spec/monitor/prometheus/exporter') + } + } -function deleteLabelAnnotation(commit, type) { - const obj = initialDbMetadata[type] + function isValueExistInModel(path) { + const modelValue = getValue(model, path) + return !!modelValue + } - if (type === 'annotations') { - delete obj['blueprint.kubestash.com/name'] - delete obj['blueprint.kubestash.com/namespace'] - } else delete obj['kubedb.com/archiver'] + function setValueFromDbDetails(path) { + const value = getValue(model, path) + return value + } - commit('wizard/model$update', { - path: `/resources/kubedbComPostgres/metadata/${type}`, - value: obj, - force: true, - }) -} + function onLabelChange() { + const labels = getValue(model, '/resources/kubedbComPostgres/spec/metadata/labels') -function getContext() { - if (isBackupOn) return ['Create', 'Delete', 'Modify'] - return ['Create'] -} + const agent = getValue(model, '/resources/kubedbComPostgres/spec/monitor/agent') -function onContextChange({ getValue, discriminator, commit, model }) { - 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 (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', + value: labels, + force: true, + }) + } } -} -function getConfigList({ storeGet }) { - 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({ getValue, discriminator, commit, storeGet, model }) { - const configName = getValue(discriminator, '/config') - const configs = objectCopy(backupConfigurationsFromStore) - const configDetails = configs?.find((item) => item?.metadata?.name === configName) + function onAgentChange() { + const agent = getValue(model, '/resources/kubedbComPostgres/spec/monitor/agent') + if (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', + value: [], + force: true, + }) - commit('wizard/model$update', { - path: '/resources/coreKubestashComBackupConfiguration', - value: configDetails, - force: true, - }) -} + onNamespaceChange() + onLabelChange() + } else { + commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') + } + } -function showPause({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/backupConfigContext') - watchDependency('discriminator#/config') - const contex = getValue(discriminator, '/backupConfigContext') - const configName = getValue(discriminator, '/config') - return !!configName && contex === 'Modify' -} + 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') -function showConfigList({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/backupConfigContext') - const contex = getValue(discriminator, '/backupConfigContext') - return contex === 'Modify' || contex === 'Delete' -} - -function showSchedule({ watchDependency, getValue, discriminator }) { - 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 getNamespaceArray() { - return namespaceList -} - -// invoker form -function initBackupInvoker() { - return 'backupConfiguration' -} - -function onBackupInvokerChange({ getValue, discriminator, commit, model, storeGet }) { - const kind = storeGet('/resource/layout/result/resource/kind') - const backupInvoker = getValue(discriminator, '/backupInvoker') - const annotations = getValue(model, '/resources/kubedbComPostgres/metadata/annotations') - - // get name namespace labels to set in db resource when backup is not enabled initially + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }, + ) - if (backupInvoker === 'backupConfiguration') { - commit('wizard/model$update', { - path: '/resources/coreKubestashComBackupConfiguration', - value: initialModel, - force: true, - }) + const secrets = (resp && resp.data && resp.data.items) || [] - if ( - !dbResource.metadata?.annotations?.['blueprint.kubestash.com/name'] && - !dbResource.metadata?.annotations?.['blueprint.kubestash.com/namespace'] - ) { - delete annotations['blueprint.kubestash.com/name'] - delete annotations['blueprint.kubestash.com/namespace'] - commit('wizard/model$update', { - path: '/resources/kubedbComPostgres/metadata/annotations', - value: annotations, - force: true, + const filteredSecrets = secrets.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) }) - } - } else if (backupInvoker === 'backupBlueprint') { - if (!isBackupOn) { - commit('wizard/model$delete', '/resources/coreKubestashComBackupConfiguration') - } - annotations['blueprint.kubestash.com/name'] = `${kind.toLowerCase()}-blueprint` - annotations['blueprint.kubestash.com/namespace'] = 'kubedb' - commit('wizard/model$update', { - path: '/resources/kubedbComPostgres/metadata/annotations', - value: annotations, - force: true, - }) - } -} - -function showInvokerForm({ getValue, discriminator, watchDependency }, value) { - const backupInvoker = getValue(discriminator, '/backupInvoker') - watchDependency('discriminator#/backupInvoker') - - return backupInvoker === value -} - -// backup configuration form -function initalizeTargetReferenceName({ getValue, model, watchDependency }) { - const databaseName = getValue(model, '/metadata/release/name') - watchDependency('model#/metadata/release/name') - - return databaseName -} - -// restore session repository -function setInitialRestoreSessionRepo({ getValue, model }) { - const value = getValue(model, 'resources/stashAppscodeComRepository_init_repo') - return value ? 'create' : 'select' -} - -// backup config repository -function initRepositoryChoise({ getValue, model }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - if (stashAppscodeComRepository_repo) return 'create' - else return 'select' -} - -function initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' - setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) - - return repoInitialSelectionStatus -} -function onRepositoryChoiseChange({ getValue, discriminator, watchDependency, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - if (repositoryChoise === 'select') { - // delete the stashAppscodeComRepository_repo - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') - } else if (repositoryChoise === 'create') { - // create new stashAppscodeComRepository_repo - if (!valueExists(model, getValue, '/resources/stashAppscodeComRepository_repo')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRepository_repo', - value: stashAppscodeComRepository_repo, + filteredSecrets.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true }) - const repositoryName = `${getValue(model, '/metadata/release/name')}-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) - } - } -} - -function onRepositoryNameChange({ getValue, model, commit }) { - const repositoryName = getValue(model, 'resources/stashAppscodeComRepository_repo/metadata/name') - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) -} - -// backup blueprint form -function getMongoAnnotations(getValue, model) { - const annotations = getValue(model, '/resources/kubedbComPostgres/metadata/annotations') - return { ...annotations } || {} -} - -function initFromAnnotationValue({ getValue, model }, key) { - const annotations = getMongoAnnotations(getValue, model) - return annotations[key] -} - -function onBackupBlueprintNameChange({ getValue, discriminator, commit, model }) { - const backupBlueprintName = getValue(discriminator, '/backupBlueprintName') - addKubeDbComPostgresDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/backup-blueprint', - backupBlueprintName, - true, - ) -} - -function onBackupBlueprintScheduleChange({ getValue, discriminator, commit, model }) { - const backupBlueprintSchedule = getValue(discriminator, '/schedule') - addKubeDbComPostgresDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/schedule', - backupBlueprintSchedule, - true, - ) -} - -function initFromAnnotationKeyValue({ getValue, model }, prefix) { - const annotations = getMongoAnnotations(getValue, model) - const newOb = {} - Object.keys(annotations).forEach((key) => { - if (key.startsWith(prefix)) { - const newKey = key.replace(prefix, '') - newOb[newKey] = annotations[key] + return filteredSecrets + } catch (e) { + console.log(e) + return [] } - }) - return newOb -} - -function onTaskParametersChange({ getValue, discriminator, model, commit }) { - const taskParameters = getValue(discriminator, '/taskParameters') - - const taskParamterKeys = Object.keys(taskParameters).map( - (tp) => `params.stash.appscode.com/${tp}`, - ) - const oldAnnotations = getValue(model, '/resources/kubedbComPostgres/metadata/annotations') || {} - const newAnnotations = {} - - const filteredAnnotationKeys = Object.keys(oldAnnotations).filter( - (key) => !taskParamterKeys.includes(key) && !key.startsWith('params.stash.appscode.com/'), - ) - - filteredAnnotationKeys.forEach((key) => { - newAnnotations[key] = oldAnnotations[key] - }) - - Object.keys(taskParameters).forEach((tpk) => { - newAnnotations[`params.stash.appscode.com/${tpk}`] = taskParameters[tpk] - }) - - commit('wizard/model$update', { - path: '/resources/kubedbComPostgres/metadata/annotations', - value: newAnnotations, - }) -} - -function isValueExistInModel({ model, getValue }, path) { - const modelValue = getValue(model, path) - return !!modelValue -} - -function onNamespaceChange({ commit, model, getValue }) { - const namespace = getValue(model, '/metadata/release/namespace') - const agent = getValue(model, '/resources/kubedbComPostgres/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', - value: [namespace], - force: true, - }) } -} -function onLabelChange({ commit, model, getValue }) { - const labels = getValue(model, '/resources/kubedbComPostgres/spec/metadata/labels') + 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 agent = getValue(model, '/resources/kubedbComPostgres/spec/monitor/agent') + const isKube = !!storeGet('/route/params/actions') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) + if (isKube) return pathConstructedForKubedb + else + return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/postgresopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` } -} - -function onNameChange({ commit, model, getValue }) { - const dbName = getValue(model, '/metadata/release/name') - const agent = getValue(model, '/resources/kubedbComPostgres/spec/monitor/agent') - - const labels = getValue(model, '/resources/kubedbComPostgres/spec/metadata/labels') - - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) + function onNamespaceChange() { + const namespace = getValue( + model, + '/resources/autoscalingKubedbComPostgresAutoscaler/metadata/namespace', + ) + if (!namespace) { + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComPostgresAutoscaler/spec/databaseRef/name', + ) + } } - const scheduleBackup = getValue(model, '/resources/stashAppscodeComBackupConfiguration') - - if (scheduleBackup) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_repo') - if (creatingNewRepo) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: `${dbName}-repo`, - force: true, - }) + function setValueFrom() { + if (isConfigMapTypeValueFrom()) { + return 'configMap' + } else if (isSecretTypeValueFrom()) { + return 'secret' + } else { + return 'input' } } - const prePopulateDatabase = getValue(model, '/resources/stashAppscodeComRestoreSession_init') - - if (prePopulateDatabase) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_init_repo') - if (creatingNewRepo) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: `${dbName}-init-repo`, - force: true, - }) + 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, + }) } } - // to reset configSecret name field - const hasSecretConfig = getValue(model, '/resources/secret_config') - if (hasSecretConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComPostgres/spec/configSecret/name', - value: `${dbName}-config`, - force: true, - }) - } -} + // function isEqualToValueFromType(value) { + // //watchDependency('discriminator#/valueFromType') + // const valueFrom = getValue(discriminator, '/valueFromType') + // return valueFrom === value + // } -function returnFalse() { - return false -} + async function resourceNames(group, version, resource) { + const namespace = getValue(model, '/metadata/release/namespace') + // watchDependency('model#/metadata/release/namespace') -function onAgentChange({ commit, model, getValue }) { - const agent = getValue(model, '/resources/kubedbComPostgres/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', - value: [], - force: true, + let resources = await getNamespacedResourceList(axios, storeGet, { + namespace, + group, + version, + resource, }) - onNamespaceChange({ commit, model, getValue }) - onLabelChange({ commit, model, getValue }) - } else { - commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') - } -} - -/************************************* Database Secret Section ********************************************/ - -function getCreateAuthSecret({ model, getValue }) { - const authSecret = getValue(model, '/resources/kubedbComPostgres/spec/authSecret') - - return !authSecret -} - -function showExistingSecretSection({ getValue, watchDependency, discriminator }) { - watchDependency('discriminator#/createAuthSecret') - - const hasAuthSecretName = getValue(discriminator, '/createAuthSecret') - return !hasAuthSecretName -} - -function showPasswordSection({ getValue, watchDependency, discriminator }) { - return !showExistingSecretSection({ - getValue, - watchDependency, - discriminator, - }) -} - -function setAuthSecretPassword({ model, getValue }) { - const encodedPassword = getValue(model, '/resources/secret_auth/data/password') - return encodedPassword ? decodePassword({}, encodedPassword) : '' -} - -function onAuthSecretPasswordChange({ getValue, discriminator, commit }) { - const stringPassword = getValue(discriminator, '/password') + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } - if (stringPassword) { - commit('wizard/model$update', { - path: '/resources/secret_auth/data/password', - value: encodePassword({}, stringPassword), - force: true, - }) - commit('wizard/model$update', { - path: '/resources/secret_auth/data/username', - value: encodePassword({}, 'postgres'), - force: true, + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } }) - } else { - commit('wizard/model$delete', '/resources/secret_auth') } -} - -// eslint-disable-next-line no-empty-pattern -function encodePassword({}, value) { - return btoa(value) -} - -// eslint-disable-next-line no-empty-pattern -function decodePassword({}, value) { - return atob(value) -} - -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/resources/kubedbComPostgres/spec/authSecret') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/resources/secret_auth') - } -} -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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 } }, - }, - }, + 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/kubedbComPostgres/spec/monitor/prometheus/exporter/env/${index}/valueFrom/configMapKeyRef/name`, ) + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/configMapKeyRef/name') - 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 [] - } -} + if (!configMapName) return [] -//////////////////////////////////////// Service Monitor ////////////////////////////////////////////////////// + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/configmaps/${configMapName}`, + ) -//////////////////// service monitor /////////////////// + const configMaps = (resp && resp.data && resp.data.data) || {} -function isEqualToServiceMonitorType({ rootModel, watchDependency }, value) { - watchDependency('rootModel#/spec/type') - return rootModel && rootModel.spec && rootModel.spec.type === value -} + const configMapKeys = Object.keys(configMaps).map((item) => ({ + text: item, + value: item, + })) -//////////////////// custom config ///////////////// -function onConfigurationSourceChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSource') - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_config') - } else { - const value = getValue(model, '/resources/secret_config') - if (!value) { - commit('wizard/model$update', { - path: '/resources/secret_config', - value: {}, - force: true, - }) + return configMapKeys + } catch (e) { + console.log(e) + return [] } - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComPostgres/spec/configSecret/name', - value: configSecretName, - force: true, - }) } -} - -function onConfigurationChange({ getValue, commit, discriminator, model }) { - const value = getValue(discriminator, '/configuration') - commit('wizard/model$update', { - path: '/resources/secret_config/stringData/user.conf', - value: value, - force: true, - }) - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComPostgres/spec/configSecret/name', - value: configSecretName, - force: true, - }) -} - -function setConfigurationSource({ model, getValue }) { - const modelValue = getValue(model, '/resources/secret_config') - if (modelValue) { - return 'create-new-config' - } - return 'use-existing-config' -} - -function setSecretConfigNamespace({ getValue, model, watchDependency }) { - watchDependency('model#/metadata/release/namespace') - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} -function setConfiguration({ model, getValue }) { - return getValue(model, '/resources/secret_config/stringData/user.conf') -} - -function setConfigurationFiles({ model, getValue }) { - const value = getValue(model, '/resources/secret_config/data/user.conf') - return atob(value) -} - -function onSetCustomConfigChange({ discriminator, getValue, commit }) { - const value = getValue(discriminator, '/setCustomConfig') - - if (value === 'no') { - commit('wizard/model$delete', '/resources/kubedbComPostgres/spec/configSecret') - commit('wizard/model$delete', '/resources/secret_config') - } -} + 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/kubedbComPostgres/spec/monitor/prometheus/exporter/env/${index}/valueFrom/secretKeyRef/name`, + ) -function getOpsRequestUrl({ storeGet, model, getValue, mode }, 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 + `/create-opsrequest-${reqType.toLowerCase()}?namespace=${namespace}` - - if (mode === 'standalone-step') return pathConstructedForKubedb - else - return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/postgresopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` -} + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/secretKeyRef/name') -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + if (!secretName) return [] - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } -} + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets/${secretName}`, + ) -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} + const secret = (resp && resp.data && resp.data.data) || {} -function showScheduleBackup({ storeGet }) { - const operationQuery = storeGet('/route/params/actions') || '' - const isBackupOperation = operationQuery === 'edit-self-backupconfiguration' ? true : false - return !isBackupOperation -} + const secretKeys = Object.keys(secret).map((item) => ({ + text: item, + value: item, + })) -function showBackupOptions({ discriminator, getValue, watchDependency }, backup) { - const backupEnabled = getValue(discriminator, '/backupEnabled') - if (backupEnabled) { - if (backup === 'alert') return true - else return false - } else { - if (backup === 'alert') return false - else return true + return secretKeys + } catch (e) { + console.log(e) + return [] + } } -} - -function isBlueprintOption({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/blueprintOptions') - const blueprintOptions = getValue(discriminator, '/blueprintOptions') - return blueprintOptions === value -} - -function ifUsagePolicy({ discriminator, getValue, watchDependency, model }, value) { - watchDependency( - 'model#/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', - ) - const usagePolicy = getValue( - model, - '/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', - ) - return usagePolicy === value -} - -async function getBlueprints({ getValue, model, setDiscriminatorValue, axios, storeGet }, backup) { - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const url = `clusters/${username}/${clusterName}/proxy/core.kubestash.com/v1alpha1/backupblueprints` - try { - const resp = await axios.get(url) - let data = resp.data.items - return data - } catch (e) { - console.log(e) + function isBindingAlreadyOn() { + const value = getValue(model, '/resources') + const keys = Object.keys(value) + const isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComPostgresBinding') + return isExposeBinding } -} - -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} -async function fetchNamespaces({ axios, storeGet }) { - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const group = storeGet('/route/params/group') - const version = storeGet('/route/params/version') - const resource = storeGet('/route/params/resource') - - const url = `clusters/${username}/${clusterName}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews` - - try { - const resp = await axios.post(url, { - _recurringCall: false, - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', + 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/kubedbComPostgres/metadata/labels') + const bindingValues = { + apiVersion: 'catalog.appscode.com/v1alpha1', + kind: 'PostgresBinding', + metadata: { + labels, + name: dbName, + namespace: dbNamespace, + }, spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], + sourceRef: { + name: dbName, + namespace: dbNamespace, + }, }, - }) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] - } - } catch (e) { - console.log(e) - } - return [] -} - -async function fetchNames( - { getValue, axios, storeGet, watchDependency, discriminator }, - version, - type, - discriminatorName, -) { - watchDependency(`discriminator#/${discriminatorName}`) - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const namespace = getValue(discriminator, `${discriminatorName}`) - const url = - type !== 'secrets' - ? `clusters/${username}/${clusterName}/proxy/storage.kubestash.com/${version}/namespaces/${namespace}/${type}` - : `clusters/${username}/${clusterName}/proxy/core/${version}/namespaces/${namespace}/${type}` - try { - if (namespace) { - const resp = await axios.get(url) - let data = resp.data.items - if (type === 'secrets') data = data.filter((ele) => !!ele.data['RESTIC_PASSWORD']) - data = data.map((ele) => ele.metadata.name) - return data } - } catch (e) { - console.log(e) - } - return [] -} - -function initBlueprint() { - return 'create' -} -function initUsagePolicy() { - return 'Same' -} - -function onInputChange( - { getValue, discriminator, commit, model }, - modelPath, - field, - subfield, - discriminatorName, -) { - const value = getValue(discriminator, `/${discriminatorName}`) - const backends = getValue(model, modelPath) || [] - if (field !== 'encryptionSecret') backends[0][field][subfield] = value - else backends[0]['repositories'][0][field][subfield] = value - commit('wizard/model$update', { - path: modelPath, - value: backends, - }) -} -function setFileValueFromStash({ getValue, commit, model }, modelPath, field, subfield, value) { - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') backends[0][field][subfield] = value - else backends[0]['repositories'][0][field][subfield] = value - commit('wizard/model$update', { - path: modelPath, - value: backends, - }) -} - -function onInputChangeSchedule( - { getValue, discriminator, commit, model }, - modelPath, - discriminatorName, -) { - const value = getValue(discriminator, `/${discriminatorName}`) - const session = getValue(model, modelPath) - session[0].scheduler.schedule = value - commit('wizard/model$update', { - path: modelPath, - value: session, - }) -} - -function setInitSchedule({ getValue, commit, model }, modelPath, value) { - const session = getValue(model, modelPath) - session[0].scheduler.schedule = value - commit('wizard/model$update', { - path: modelPath, - value: session, - }) -} -function getDefault({ getValue, model }, modelPath, field, subfield) { - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') return backends[0][field][subfield] - else { - return backends[0]['repositories'][0][field][subfield] - } -} - -function getDefaultSchedule({ getValue, model, watchDependency }, modelPath) { - watchDependency('discriminator#/config') - const session = getValue(model, modelPath) - return session?.length ? session[0]?.scheduler.schedule : '' -} - -//////////////////// Auto scaler ///////////////// -let autoscaleType = '' -let dbDetails = {} - -function isConsole({ storeGet, commit }) { - const isKube = isKubedb({ storeGet }) - - if (isKube) { - const dbName = storeGet('/route/params/name') || '' - commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComPostgresAutoscaler/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/autoscalingKubedbComPostgresAutoscaler/metadata/name', - value: modifiedName, - force: true, - }) - const namespace = storeGet('/route/query/namespace') || '' - if (namespace) { + if (value) { commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComPostgresAutoscaler/metadata/namespace', - value: namespace, + path: '/resources/catalogAppscodeComPostgresBinding', + value: bindingValues, force: true, }) + } else { + commit('wizard/model$delete', '/resources/catalogAppscodeComPostgresBinding') } } - return !isKube -} - -function isKubedb({ storeGet }) { - return !!storeGet('/route/params/actions') -} - -function showOpsRequestOptions({ model, getValue, watchDependency, storeGet, discriminator }) { - if (isKubedb({ storeGet }) === true) return true - watchDependency('model#/resources/autoscalingKubedbComPostgresAutoscaler/spec/databaseRef/name') - watchDependency('discriminator#/autoscalingType') - return ( - !!getValue(model, '/resources/autoscalingKubedbComPostgresAutoscaler/spec/databaseRef/name') && - !!getValue(discriminator, '/autoscalingType') - ) -} - -async function getDbDetails({ axios, storeGet, getValue, model, setDiscriminatorValue, commit }) { - const owner = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - - const namespace = - storeGet('/route/query/namespace') || - getValue(model, '/resources/autoscalingKubedbComPostgresAutoscaler/metadata/namespace') || - '' - const name = - storeGet('/route/params/name') || - getValue(model, '/resources/autoscalingKubedbComPostgresAutoscaler/spec/databaseRef/name') || - '' - - if (namespace && name) { - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/postgreses/${name}`, - ) - dbDetails = resp.data || {} - - setDiscriminatorValue('/dbDetails', true) - } catch (e) { - console.log(e) - } + function returnFalse() { + return false } - commit('wizard/model$update', { - path: `/metadata/release/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/metadata/release/namespace`, - value: namespace, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComPostgresAutoscaler/spec/databaseRef/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComPostgresAutoscaler/metadata/labels`, - value: dbDetails.metadata.labels, - force: true, - }) -} - -async function dbTypeEqualsTo( - { watchDependency, getValue, commit, discriminator }, - mongoType, - type, -) { - watchDependency('discriminator#/dbDetails') - autoscaleType = type - const dbDetailsSuccess = getValue(discriminator, '/dbDetails') - - if (!dbDetailsSuccess) return false - - const { spec } = dbDetails || {} - const { shardTopology, replicaSet } = spec || {} - let verd = '' - if (shardTopology) verd = 'sharded' - else { - if (replicaSet) verd = 'replicaSet' - else verd = 'standalone' - } - clearSpecModel({ commit }, verd) - return mongoType === verd -} - -async function getNamespaces({ axios, storeGet }) { - 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 getPostgresDbs({ axios, storeGet, model, getValue, watchDependency }) { - watchDependency('model#/resources/autoscalingKubedbComPostgresAutoscaler/metadata/namespace') - const namespace = getValue( - model, - '/resources/autoscalingKubedbComPostgresAutoscaler/metadata/namespace', - ) - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/postgreses`, - { - 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 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 initMetadata({ getValue, discriminator, model, commit, storeGet }) { - const dbName = - getValue(model, '/resources/autoscalingKubedbComPostgresAutoscaler/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/autoscalingKubedbComPostgresAutoscaler/metadata/name', - value: modifiedName, - force: true, - }) - - // delete the other type object from vuex wizard model - if (type === 'compute') - commit('wizard/model$delete', '/resources/autoscalingKubedbComPostgresAutoscaler/spec/storage') - if (type === 'storage') - commit('wizard/model$delete', '/resources/autoscalingKubedbComPostgresAutoscaler/spec/compute') -} - -function onNamespaceChange({ model, getValue, commit }) { - const namespace = getValue( - model, - '/resources/autoscalingKubedbComPostgresAutoscaler/metadata/namespace', - ) - if (!namespace) { - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComPostgresAutoscaler/spec/databaseRef/name', - ) - } -} - -function ifScalingTypeEqualsTo( - { storeGet, watchDependency, getValue, discriminator, model }, - type, -) { - watchDependency('discriminator#/autoscalingType') - watchDependency('model#/resources/autoscalingKubedbComPostgresAutoscaler/spec/databaseRef/name') - - const operation = storeGet('/route/params/actions') || '' - if (operation.length) { - const splitOp = operation.split('-') - if (splitOp.length > 2) autoscaleType = splitOp[2] - } else autoscaleType = getValue(discriminator, '/autoscalingType') || '' - const isDatabaseSelected = !!getValue( - model, - '/resources/autoscalingKubedbComPostgresAutoscaler/spec/databaseRef/name', - ) - return autoscaleType === type && isDatabaseSelected -} - -async function fetchNodeTopology({ axios, storeGet }) { - 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, getValue }) { - watchDependency( - 'model#/resources/autoscalingKubedbComPostgresAutoscaler/spec/compute/nodeTopology/name', - ) - const nodeTopologyName = - getValue( - model, - '/resources/autoscalingKubedbComPostgresAutoscaler/spec/compute/nodeTopology/name', - ) || '' - return !!nodeTopologyName.length -} - -function setControlledResources({ commit }, type) { - const list = ['cpu', 'memory'] - const path = `/resources/autoscalingKubedbComPostgresAutoscaler/spec/compute/${type}/controlledResources` - commit('wizard/model$update', { - path: path, - value: list, - force: true, - }) - return list -} - -function setTrigger({ model, getValue }, path) { - let value = getValue(model, `/resources/${path}`) - if (value) return value - return 'On' -} - -function setApplyToIfReady() { - return 'IfReady' -} -function handleUnit({ commit, model, getValue }, 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' + 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 } } } - if (!isNaN(threshold)) { - threshold += 'pc' - } - updatedValue.push({ threshold, appliesUpto }) + return ret }) - if (JSON.stringify(updatedValue) !== JSON.stringify(value)) { - commit('wizard/model$update', { - path: `/resources/${path}`, - value: updatedValue, - force: true, - }) - } - } else { - if (!isNaN(value)) { - value += 'Gi' + + if (filteredEnv.length) commit('wizard/model$update', { - path: `/resources/${path}`, - value: value, + path: '/resources/kubedbComPostgres/spec/monitor/prometheus/exporter/env', + value: filteredEnv, force: true, }) - } } -} - -function objectCopy(obj) { - const temp = JSON.stringify(obj) - return JSON.parse(temp) -} -function isBindingAlreadyOn({ model, getValue }) { - const value = getValue(model, '/resources') - const keys = Object.keys(value) - isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComPostgresBinding') - return isExposeBinding -} + function initEnvArray() { + const env = getValue(model, '/resources/kubedbComPostgres/spec/monitor/prometheus/exporter/env') -async function addOrRemoveBinding({ commit, model, getValue, discriminator }) { - const value = getValue(discriminator, `/binding`) - const dbName = getValue(model, '/metadata/release/name') - const dbNamespace = getValue(model, '/metadata/release/namespace') - const labels = getValue(model, '/resources/kubedbComPostgres/metadata/labels') - const bindingValues = { - apiVersion: 'catalog.appscode.com/v1alpha1', - kind: 'PostgresBinding', - metadata: { - labels, - name: dbName, - namespace: dbNamespace, - }, - spec: { - sourceRef: { - name: dbName, - namespace: dbNamespace, - }, - }, + return env || [] } - if (value) { - await commit('wizard/model$update', { - path: '/resources/catalogAppscodeComPostgresBinding', - value: bindingValues, - force: true, - }) - } else { - await commit('wizard/model$delete', '/resources/catalogAppscodeComPostgresBinding') - } -} - -async function fetchTopologyMachines({ axios, getValue, storeGet, model, setDiscriminatorValue }) { - const instance = hasAnnotations({ model, getValue }) - - 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 isEqualToTemp(value, index) { + //watchDependency('discriminator#/valueFromType') + const valueFrom = getValue(discriminator, `/env/${index}/temp/valueFromType`) + return valueFrom === value } -} - -function setAllowedMachine({ model, getValue }, minmax) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComPostgresAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - const mx = instance?.includes(',') ? instance.split(',')[1] : '' - const mn = instance?.includes(',') ? instance.split(',')[0] : '' - - if (minmax === 'min') return mn - else return mx -} - -async function getMachines({ getValue, watchDependency, discriminator }, minmax) { - watchDependency('discriminator#/topologyMachines') - const depends = minmax === 'min' ? 'max' : 'min' - const dependantPath = `/allowedMachine-${depends}` - - watchDependency(`discriminator#${dependantPath}`) - const dependantMachine = getValue(discriminator, dependantPath) - - const nodeGroups = getValue(discriminator, '/topologyMachines') || [] - - const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) - - const machines = nodeGroups?.map((item) => { - const subText = `CPU: ${item.allocatable.cpu}, Memory: ${item.allocatable.memory}` - const text = item.topologyValue - return { text, subText, value: item.topologyValue } - }) - const filteredMachine = machines?.filter((item, ind) => - minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, - ) - - return dependantIndex === -1 ? machines : filteredMachine -} - -function hasAnnotations({ model, getValue }) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComPostgresAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - - return !!instance -} - -function hasNoAnnotations({ model, getValue }) { - return !hasAnnotations({ model, getValue }) -} - -function onMachineChange({ model, getValue, discriminator, commit }, type) { - const annoPath = '/resources/autoscalingKubedbComPostgresAutoscaler/metadata/annotations' - const annotations = getValue(model, annoPath) - const instance = annotations['kubernetes.io/instance-type'] - - const minMachine = getValue(discriminator, '/allowedMachine-min') - const maxMachine = getValue(discriminator, '/allowedMachine-max') - const minMaxMachine = `${minMachine},${maxMachine}` - annotations['kubernetes.io/instance-type'] = minMaxMachine - - const machines = getValue(discriminator, `/topologyMachines`) || [] - const minMachineObj = machines.find((item) => item.topologyValue === minMachine) - const maxMachineObj = machines.find((item) => item.topologyValue === maxMachine) - const minMachineAllocatable = minMachineObj?.allocatable - const maxMachineAllocatable = maxMachineObj?.allocatable - const allowedPath = `/resources/autoscalingKubedbComPostgresAutoscaler/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 initMonitoring() { + const env = + getValue(model, '/resources/kubedbComPostgres/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 { - handleUnit, - isConsole, - getNamespaces, - getPostgresDbs, - isKubedb, - initMetadata, - onNamespaceChange, - ifScalingTypeEqualsTo, - fetchNodeTopology, - isNodeTopologySelected, - setControlledResources, - setTrigger, - setApplyToIfReady, - showOpsRequestOptions, - setInitSchedule, - fetchNames, - fetchNamespaces, - isRancherManaged, - onInputChangeSchedule, - getDefaultSchedule, - getBlueprints, - ifUsagePolicy, - initUsagePolicy, - isBlueprintOption, - initBlueprint, - getDefault, - onInputChange, - showBackupOptions, - showScheduleBackup, - isVariantAvailable, - fetchJsons, - disableLableChecker, - isEqualToModelPathValue, - getResources, - isEqualToDiscriminatorPath, - setValueFromModel, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - returnTrue, - returnStringYes, - getPostgresVersions, - showAuthPasswordField, - showAuthSecretField, - showNewSecretCreateField, - getClientAuthModes, - onVersionChange, - setDatabaseMode, - getStorageClassNames, - deleteDatabaseModePath, - isEqualToDatabaseMode, - setApiGroup, - getIssuerRefsName, - hasIssuerRefName, - hasNoIssuerRefName, - setSSLMode, - showTlsConfigureSection, - onTlsConfigureChange, - getAliasOptions, - showMonitoringSection, - onEnableMonitoringChange, - showCustomizeExporterSection, - onCustomizeExporterChange, - disableInitializationSection, - valueExists, - initPrePopulateDatabase, - onPrePopulateDatabaseChange, - initDataSource, - onDataSourceChange, - initVolumeType, - onVolumeTypeChange, - showInitializationForm, - showScriptOrStashForm, - showConfigMapOrSecretName, - initializeNamespace, - showRepositorySelectOrCreate, - onInitRepositoryChoiseChange, - initCustomizeRestoreJobRuntimeSettings, - initCustomizeRestoreJobRuntimeSettingsForBackup, - onCustomizeRestoreJobRuntimeSettingsChange, - onCustomizeRestoreJobRuntimeSettingsChangeForBackup, - showRuntimeForm, - getImagePullSecrets, - getBackupConfigsAndAnnotations, - deleteKubeDbComPostgresDbAnnotation, - addKubeDbComPostgresDbAnnotation, - initScheduleBackup, - initScheduleBackupForEdit, - onScheduleBackupChange, - showBackupForm, - initBackupInvoker, - onBackupInvokerChange, - showInvokerForm, - initalizeTargetReferenceName, - setInitialRestoreSessionRepo, - initRepositoryChoise, - initRepositoryChoiseForEdit, - onRepositoryChoiseChange, - onRepositoryNameChange, - getMongoAnnotations, - initFromAnnotationValue, - onBackupBlueprintNameChange, - onBackupBlueprintScheduleChange, - initFromAnnotationKeyValue, - onTaskParametersChange, - isValueExistInModel, - onNamespaceChange, - onLabelChange, - onNameChange, - returnFalse, - onAgentChange, - getCreateAuthSecret, - showExistingSecretSection, - showPasswordSection, - setAuthSecretPassword, - onAuthSecretPasswordChange, - encodePassword, - decodePassword, - onCreateAuthSecretChange, - getSecrets, - isEqualToServiceMonitorType, - onConfigurationSourceChange, - onConfigurationChange, - setConfigurationSource, - setSecretConfigNamespace, - setConfiguration, - setConfigurationFiles, - onSetCustomConfigChange, - getOpsRequestUrl, - getCreateNameSpaceUrl, - setStorageClass, - isBindingAlreadyOn, - addOrRemoveBinding, - - initBackupData, - isBackupDataLoadedTrue, - setBackupType, - getTypes, - onBackupTypeChange, - isBackupType, - getContext, - onContextChange, - getConfigList, - onConfigChange, - showPause, - showSchedule, - showConfigList, - setBlueprintSwitch, - onBlueprintChange, - setArchiverSwitch, - onArchiverChange, - getNamespaceArray, - getMachines, - setAllowedMachine, - hasAnnotations, - hasNoAnnotations, - fetchTopologyMachines, - onMachineChange, + return { + initScheduleBackup, + initScheduleBackupForEdit, + onScheduleBackupChange, + deleteKubeDbComPostgresDbAnnotation, + getBackupConfigsAndAnnotations, + showBackupForm, + initBackupData, + isBackupDataLoadedTrue, + setBackupType, + getTypes, + onBackupTypeChange, + isBackupType, + setBlueprintSwitch, + onBlueprintChange, + setArchiverSwitch, + onArchiverChange, + getContext, + onContextChange, + getConfigList, + onConfigChange, + showPause, + showConfigList, + showSchedule, + showScheduleBackup, + getDefaultSchedule, + initRepositoryChoiseForEdit, + addLabelAnnotation, + deleteLabelAnnotation, + onInputChangeSchedule, + objectCopy, + valueExists, + setPausedValue, + + getDbDetails, + isKubedb, + isConsole, + getNamespaces, + isRancherManaged, + onNamespaceChange, + getPostgresDbs, + initMetadata, + fetchTopologyMachines, + setTrigger, + onTriggerChange, + hasAnnotations, + setAllowedMachine, + getMachines, + onMachineChange, + hasNoAnnotations, + setControlledResources, + fetchNodeTopology, + isNodeTopologySelected, + showOpsRequestOptions, + setApplyToIfReady, + + handleUnit, + + getOpsRequestUrl, + isValueExistInModel, + setValueFromDbDetails, + onEnableMonitoringChange, + showMonitoringSection, + onAgentChange, + getResources, + isEqualToModelPathValue, + onCustomizeExporterChange, + showCustomizeExporterSection, + onLabelChange, + setValueFrom, + onValueFromChange, + resourceNames, + getConfigMapKeys, + getSecrets, + getSecretKeys, + isConfigMapTypeValueFrom, + isSecretTypeValueFrom, + getNamespacedResourceList, + returnFalse, + onEnvArrayChange, + initEnvArray, + isEqualToTemp, + initMonitoring, + + isBindingAlreadyOn, + addOrRemoveBinding, + showStorageMemoryOption, + } } diff --git a/charts/kubedbcom-proxysql-editor-options/ui/create-ui.yaml b/charts/kubedbcom-proxysql-editor-options/ui/create-ui.yaml index f1626a67c9..9e07f25045 100644 --- a/charts/kubedbcom-proxysql-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-proxysql-editor-options/ui/create-ui.yaml @@ -1,306 +1,297 @@ -steps: -- form: - discriminator: - bundleApiLoaded: - default: false - type: boolean +step: +- type: single-step-form + loader: initBundle + elements: + - type: label-element + label: '' + subtitle: Select the ProxySQL version you want to deploy on Kubernetes. The chosen version determines the ProxySQL engine features, compatibility, and runtime behavior of your database proxy. + - disableUnselect: true + loader: getAdminOptions|databases/ProxySQL/versions + if: + type: function + name: isToggleOn|databases/ProxySQL/versions + label: Database Version + schema: schema/properties/spec/properties/admin/properties/databases/properties/ProxySQL/properties/versions/properties/default + type: select + - init: + type: func + value: getDefault|databases/ProxySQL/mode + loader: getAdminOptions|databases/ProxySQL/mode + isHorizontal: true + if: + type: function + name: isToggleOn|databases/ProxySQL/mode + label: Database Mode + watcher: + func: clearArbiterHidden + paths: + - schema/properties/spec/properties/mode + schema: schema/properties/spec/properties/mode + type: radio + - if: + type: function + name: EqualToDatabaseMode|Replicaset + label: Replicas + schema: schema/properties/spec/properties/replicas + type: input + - elements: + - type: label-element + label: '' + subtitle: Select a machine profile to allocate CPU and memory resources for your database proxy. Choose 'custom' to manually specify resource requirements or select a predefined profile. + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: CPU + loader: setLimits|cpu + watcher: + func: setRequests|cpu + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: Memory + loader: setLimits|memory + watcher: + func: setRequests|memory + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + label: Machine Profile + showLabels: true + type: block-layout + - loader: getAdminOptions|storageClasses + if: + type: function + name: isToggleOn|storageClasses + label: Storage Class + schema: schema/properties/spec/properties/admin/properties/storageClasses/properties/default + type: select + - label: Backend Section + type: label-element + subtitle: Specify the backend databases for ProxySQL to route queries. + - loader: getAppBindings + label: Backend + refresh: true + schema: schema/properties/spec/properties/backend + type: select + - description: Configure Credentials, Deployment Mode etc. elements: - - computed: initBundle - if: returnFalse - type: label-element - - disableUnselect: true - fetch: getAdminOptions|databases/ProxySQL/versions - if: isToggleOn|databases/ProxySQL/versions - label: - text: labels.database.version - schema: - $ref: schema#/properties/spec/properties/admin/properties/databases/properties/ProxySQL/properties/versions/properties/default + - elements: + - type: label-element + label: '' + subtitle: Add custom labels and annotations to your database resources for organization, monitoring, and integration with other Kubernetes tools and services. + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/annotations + label: Labels & Annotations + showLabels: true + hideBlock: true + type: block-layout + - init: + type: func + value: getDefault|deletionPolicy + customClass: mt-20 + if: + type: function + name: isToggleOn|deletionPolicy + label: Deletion Policy + options: + - description: options.deletionPolicy.delete.description + text: Delete + value: Delete + - description: options.deletionPolicy.wipeOut.description + text: WipeOut + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: DoNotTerminate + value: DoNotTerminate + schema: schema/properties/spec/properties/deletionPolicy type: select - - computed: getDefault|databases/ProxySQL/mode - fetch: getAdminOptions|databases/ProxySQL/mode - hasDescription: true - if: isToggleOn|databases/ProxySQL/mode - label: - text: labels.database.mode - onChange: clearArbiterHidden - schema: - $ref: schema#/properties/spec/properties/mode - type: radio - - if: EqualToDatabaseMode|Replicaset - label: - text: labels.replicas - schema: - $ref: schema#/properties/spec/properties/replicas + - if: + type: function + name: getDefaultValue|spec/admin/authCredential/customize + label: Provide Authentication Credentials? + watcher: + func: onAuthChange + paths: + - temp/createAuthSecret + schema: temp/createAuthSecret + type: switch + - if: + type: function + name: showReferSecretSwitch + label: Refer existing Secret? + watcher: + func: onReferSecretChange + paths: + - temp/referSecret + schema: temp/referSecret + type: switch + - loader: getReferSecrets + if: + type: function + name: showSecretDropdown + label: Secret + schema: schema/properties/spec/properties/authSecret/properties/name + type: select + - if: + type: function + name: showReferSecret + label: Password + schema: schema/properties/spec/properties/authSecret/properties/password type: input - - elements: - - computed: setMachineToCustom - customClass: mt-10 - fetch: getMachineListForOptions - label: - text: labels.machine - schema: - $ref: schema#/properties/spec/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.cpu - onChange: setRequests|cpu - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.memory - onChange: setRequests|memory - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - label: - text: labels.machine_profile - show_label: true - type: single-step-form - - fetch: getAdminOptions|storageClasses - if: isToggleOn|storageClasses - label: - text: labels.storage.class - schema: - $ref: schema#/properties/spec/properties/admin/properties/storageClasses/properties/default + - if: + type: function + name: getDefaultValue|spec/admin/customConfiguration + label: Configure Database? + watcher: + func: clearConfiguration + paths: + - temp/configDatabase + schema: temp/configDatabase + type: switch + - if: + type: function + name: isConfigDatabaseOn + label: Configuration + schema: schema/properties/spec/properties/configuration + type: textarea + - label: Sync Users? + schema: schema/properties/spec/properties/syncUsers + type: switch + - if: + type: function + name: isToggleOn|deployment + label: Deployment Mode + options: + - description: Postgres sharded cluster for high performance and high availability. + text: Shared + value: Shared + - description: For production applications with sophisticated workload requirements. + text: Dedicated + value: Dedicated + schema: schema/properties/spec/properties/admin/properties/deployment/properties/default + type: radio + - if: + type: function + name: isToggleOn|clusterTier + isHorizontal: true + label: Cluster Tier + options: + - text: General Purpose + value: GeneralPurpose + - text: Memory Optimized + value: MemoryOptimized + - text: CPU Optimized + value: CPUOptimized + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/default + type: radio + - disableUnselect: true + loader: getAdminOptions|clusterTier/placement + if: + type: function + name: isToggleOn|clusterTier/placement + label: Placement Policy + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default type: select - - label: - text: labels.backend_section - type: label-element - - fetch: getAppBindings - label: - text: labels.backend + - disableUnselect: true + loader: getNodeTopology + if: + type: function + name: isToggleOn|clusterTier/nodeTopology + label: Node Topology refresh: true - schema: - $ref: schema#/properties/spec/properties/backend + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default type: select - - accordion: true - description: - text: Configure Credentials, Deployment Mode etc. - discriminator: - configDatabase: - default: false - type: boolean - createAuthSecret: - default: false - type: boolean - referSecret: - default: false - type: boolean - elements: - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties - type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties - type: input - hideForm: true - label: - text: Labels & Annotation - show_label: true - type: single-step-form - - computed: getDefault|deletionPolicy - customClass: mt-20 - if: isToggleOn|deletionPolicy - label: - text: labels.deletionPolicy - options: - - description: options.deletionPolicy.delete.description - text: options.deletionPolicy.delete.label - value: Delete - - 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/spec/properties/deletionPolicy - type: select - - if: getDefaultValue|spec/admin/authCredential/customize - label: - text: Provide Authentication Credentials? - onChange: onAuthChange - schema: - $ref: discriminator#/createAuthSecret - type: switch - - if: showReferSecretSwitch - label: - text: Refer existing Secret? - onChange: onReferSecretChange - schema: - $ref: discriminator#/referSecret - type: switch - - fetch: getReferSecrets - if: showSecretDropdown - label: - text: Secret - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/name - type: select - - if: showReferSecret - label: - text: labels.password - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/password - type: input - - computed: isConfigAvailable - if: getDefaultValue|spec/admin/customConfiguration - label: - text: Configure Database? - onChange: clearConfiguration - schema: - $ref: discriminator#/configDatabase - type: switch - - if: isConfigDatabaseOn - label: - text: Configuration - schema: - $ref: schema#/properties/spec/properties/configuration - type: editor - - label: - text: labels.sync_users_question - schema: - $ref: schema#/properties/spec/properties/syncUsers + label: Advanced Configuration + showLabels: true + hideBlock: true + type: block-layout + - description: Enable Backup, Monitoring, TLS etc. + elements: + - elements: + - init: + type: func + value: setMonitoring + label: Enable Monitoring + watcher: + func: updateAlertValue + paths: + - temp/monitoring + schema: temp/monitoring type: switch - - hasDescription: true - if: isToggleOn|deployment - label: - text: labels.deployment.name + - customClass: mt-10 + if: + type: function + name: showAlerts + label: Alert Options options: - - description: labels.deployment.shared - text: Shared - value: Shared - - description: labels.deployment.dedicated - text: Dedicated - value: Dedicated - schema: - $ref: schema#/properties/spec/properties/admin/properties/deployment/properties/default - type: radio - - if: isToggleOn|clusterTier - isHorizontal: true - label: - text: labels.clusterTier - options: - - text: General Purpose - value: GeneralPurpose - - text: Memory Optimized - value: MemoryOptimized - - text: CPU Optimized - value: CPUOptimized - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/default - type: radio - - disableUnselect: true - fetch: getAdminOptions|clusterTier/placement - if: isToggleOn|clusterTier/placement - label: - text: labels.placement - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + - text: None + value: none + - text: Critical + value: critical + - text: Warning + value: warning + - text: Info + value: info + schema: schema/properties/form/properties/alert/properties/enabled type: select - - disableUnselect: true - fetch: getNodeTopology - if: isToggleOn|clusterTier/nodeTopology - label: - text: labels.nodeTopology - refresh: true - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + if: + type: function + name: isToggleOn|monitoring + type: block-layout + - elements: + - label: Enable TLS? + schema: schema/properties/spec/properties/admin/properties/tls/properties/default + type: switch + - loader: getAdminOptions|clusterIssuers + if: + type: function + name: showIssuer + label: Cluster Issuers + validation: + type: required + schema: schema/properties/spec/properties/admin/properties/clusterIssuers/properties/default type: select - hideForm: true - label: - text: Advanced Configuration - show_label: true - type: single-step-form - - accordion: true - description: - text: Enable Backup, Monitoring, TLS etc. - elements: - - discriminator: - monitoring: - default: false - type: boolean - elements: - - computed: setMonitoring - label: - text: labels.enable_monitoring - onChange: updateAlertValue - schema: - $ref: discriminator#/monitoring - type: switch - - customClass: mt-10 - if: showAlerts - label: - text: labels.alert.options - options: - - text: None - value: none - - text: Critical - value: critical - - text: Warning - value: warning - - text: Info - value: info - schema: - $ref: schema#/properties/form/properties/alert/properties/enabled - sortable: true - type: select - if: isToggleOn|monitoring - type: single-step-form - - elements: - - label: - text: Enable TLS? - schema: - $ref: schema#/properties/spec/properties/admin/properties/tls/properties/default - type: switch - - fetch: getAdminOptions|clusterIssuers - if: showIssuer - label: - text: labels.clusterIssuers - required: true - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterIssuers/properties/default - type: select - if: isToggleOn|tls - type: single-step-form - if: showAdditionalSettings - label: - text: Additional Options - show_label: true - type: single-step-form - type: single-step-form + if: + type: function + name: isToggleOn|tls + type: block-layout + if: + type: function + name: showAdditionalSettings + label: Additional Options + showLabels: true + type: block-layout id: options - title: steps.0.label + # title: steps.0.label type: multi-step-form diff --git a/charts/kubedbcom-proxysql-editor-options/ui/functions.js b/charts/kubedbcom-proxysql-editor-options/ui/functions.js index 1f1eab5342..7c6137bcaf 100644 --- a/charts/kubedbcom-proxysql-editor-options/ui/functions.js +++ b/charts/kubedbcom-proxysql-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -315,93 +317,61 @@ const modeDetails = { }, } -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} - -function showAuthSecretField({ discriminator, getValue, watchDependency }) { - return !showAuthPasswordField({ - discriminator, - getValue, - watchDependency, - }) -} - -async function getResources({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, ) - 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 -} - -async function getProxysqlVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + setDiscriminatorValue('bundleApiLoaded', false) + setDiscriminatorValue('configDatabase', false) + setDiscriminatorValue('createAuthSecret', false) + setDiscriminatorValue('referSecret', false) + setDiscriminatorValue('monitoring', false) - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, - }, - }, + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - const resources = (resp && resp.data && resp.data.items) || [] + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) - // keep only non deprecated versions - const filteredProxysqlVersions = resources.filter((item) => item.spec && !item.spec.deprecated) + const resources = (resp && resp.data && resp.data.items) || [] - filteredProxysqlVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredProxysqlVersions -} + resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true + }) + return resources + } -async function getAppBindings({ axios, storeGet }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + async function getProxysqlVersions(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { type: null }, + const queryParams = { + filter: { + items: { + metadata: { name: null }, + spec: { version: null, deprecated: null }, + }, }, - }, - } + } - try { const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/appcatalog.appscode.com/v1alpha1/appbindings`, + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, { params: queryParams, }, @@ -409,960 +379,1011 @@ async function getAppBindings({ axios, storeGet }) { const resources = (resp && resp.data && resp.data.items) || [] - const fileredResources = resources - .filter((item) => item.spec?.type === 'kubedb.com/mysql') - .map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) - return fileredResources - } catch (e) { - console.log(e) - return [] + // keep only non deprecated versions + const filteredProxysqlVersions = resources.filter((item) => item.spec && !item.spec.deprecated) + + filteredProxysqlVersions.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + const specVersion = (item.spec && item.spec.version) || '' + item.text = `${name} (${specVersion})` + item.value = name + return true + }) + return filteredProxysqlVersions } -} -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/spec/authSecret/name') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/spec/authSecret/password') + async function getAppBindings() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + + const queryParams = { + filter: { + items: { + metadata: { name: null }, + spec: { type: null }, + }, + }, + } + + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/appcatalog.appscode.com/v1alpha1/appbindings`, + { + params: queryParams, + }, + ) + + const resources = (resp && resp.data && resp.data.items) || [] + + const fileredResources = resources + .filter((item) => item.spec?.type === 'kubedb.com/mysql') + .map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + return fileredResources + } catch (e) { + console.log(e) + return [] + } } -} -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, + 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') + + 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 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) - }) + 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 -} + filteredSecrets.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true + }) + return filteredSecrets + } -function getMachineListForOptions({ model, getValue }) { - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') let array = [] + function getMachineListForOptions() { + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') - if (available.length) { - array = available.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - else { - let subText = '', - text = '' - const machineData = machinesFromPreset.find((val) => val.id === machine) - if (machineData) { - subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` - text = machineData.name ? machineData.name : machineData.id - } - return { text, subText, value: machine } - } - }) - } else { - array = machineList - .map((machine) => { + if (available.length) { + array = available.map((machine) => { if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + else { + let subText = '', + text = '' + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + text = machineData.name ? machineData.name : machineData.id + } + return { text, subText, value: machine } + } }) - .filter((val) => !!val) + } else { + array = machineList + .map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { text, subText, value: machine } + }) + .filter((val) => !!val) + } + return array } - return array -} -function setLimits({ model, getValue, commit, watchDependency }, resource, type) { - const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' - watchDependency(`model#${path}`) - const selectedMachine = getValue(model, path) || 'custom' - const reqCommitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - const comparePath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - - const resourceValue = getValue(model, comparePath) - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - - let cpu = '', - memory = '' - if (available.length && selectedMachine !== 'custom') { - const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) - if (machineData) { - cpu = machineData.limits.cpu - memory = machineData.limits.memory + function setLimits(resource, type) { + const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' + // watchDependency(`model#${path}`) + const selectedMachine = getValue(model, path) || 'custom' + const reqCommitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + const comparePath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + + const resourceValue = getValue(model, comparePath) + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + let cpu = '', + memory = '' + if (available.length && selectedMachine !== 'custom') { + const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) + if (machineData) { + cpu = machineData.limits.cpu + memory = machineData.limits.memory + } + } else { + if (selectedMachine === 'custom') { + cpu = resourceValue + memory = resourceValue + } else { + cpu = machines[selectedMachine].resources.limits.cpu + memory = machines[selectedMachine].resources.limits.memory + } } - } else { - if (selectedMachine === 'custom') { - cpu = resourceValue - memory = resourceValue + + if (resource === 'memory') { + commit('wizard/model$update', { + path: reqCommitPath, + value: memory, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: memory, + force: true, + }) + return memory } else { - cpu = machines[selectedMachine].resources.limits.cpu - memory = machines[selectedMachine].resources.limits.memory + commit('wizard/model$update', { + path: reqCommitPath, + value: cpu, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: cpu, + force: true, + }) + return cpu } } - if (resource === 'memory') { + function setRequests(resource, type) { + const modelPath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + + const fullpath = `/spec/podResources/machine` + const modelPathValue = getValue(model, fullpath) + commit('wizard/model$update', { - path: reqCommitPath, - value: memory, + path: commitPath, + value: val, force: true, }) - commit('wizard/model$update', { - path: comparePath, - value: memory, - force: true, + + if (modelPathValue === 'custom') { + return + } + let commitCpuMemory, ModelPathValue + if (resource && type) { + const fullPath = `/spec/${type}/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/${type}/podResources/resources/requests/${resource}` + } else { + const fullPath = `/spec/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/podResources/resources/requests/${resource}` + } + let cpuMemoryValue + array.forEach((item) => { + if (item.value === ModelPathValue) { + // Parse subText like "CPU: 2, Memory: 2Gi" + const subText = item.subText || '' + if (resource === 'cpu') { + // Extract CPU value + const cpuMatch = subText.match(/CPU:\s*([^,]+)/) + cpuMemoryValue = cpuMatch ? cpuMatch[1].trim() : '' + } else if (resource === 'memory') { + // Extract Memory value + const memoryMatch = subText.match(/Memory:\s*(.+)/) + cpuMemoryValue = memoryMatch ? memoryMatch[1].trim() : '' + } + } }) - return memory - } else { commit('wizard/model$update', { - path: reqCommitPath, - value: cpu, + path: commitCpuMemory, + value: cpuMemoryValue, force: true, }) + return cpuMemoryValue + } + + function setRequests(resource) { + const modelPath = `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = `/spec/podResources/resources/limits/${resource}` commit('wizard/model$update', { - path: comparePath, - value: cpu, + path: commitPath, + value: val, force: true, }) - return cpu } -} -function setRequests({ getValue, model, commit }, resource) { - const modelPath = `/spec/podResources/resources/requests/${resource}` - const val = getValue(model, modelPath) - commitPath = `/spec/podResources/resources/limits/${resource}` - commit('wizard/model$update', { - path: commitPath, - value: val, - force: true, - }) -} + function setMachineToCustom() { + const machine = getValue(model, '/spec/admin/machineProfiles/default') + return machine || 'custom' + } -function setMachineToCustom({ getValue, model }) { - const machine = getValue(model, '/spec/admin/machineProfiles/default') - return machine || 'custom' -} + async function fetchJsons() { + let ui = {} + let language = {} + let functions = {} + const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart -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) + } - 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, + } } - return { - ui: ui.data || {}, - language: language.data || {}, - functions, + function updateAlertValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const alert = isMonitorEnabled ? 'warning' : 'none' + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: alert, + force: true, + }) + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: agent, + force: true, + }) } -} -function updateAgentValue({ commit }, val) { - commit('wizard/model$update', { - path: '/spec/monitoring/agent', - value: val ? 'prometheus.io/operator' : '', - force: true, - }) - - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: val ? 'warning' : 'none', - force: true, - }) -} -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function getCreateNameSpaceUrl() { + 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + const domain = storeGet('/domain') || '' + if (domain.includes('bb.test')) { + return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } } -} -const ifCapiProviderIsNotEmpty = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/provider') - const val = getValue(model, '/form/capi/provider') - if (val) return true -} + const ifCapiProviderIsNotEmpty = () => { + // watchDependency('model#/form/capi/provider') + const val = getValue(model, '/form/capi/provider') + if (val) return true + } -const showMultiselectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') + const showMultiselectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') - if (val === 'capz' && ifDedicated({ model, getValue })) return true -} + if (val === 'capz' && ifDedicated()) return true + } -const showSelectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') - if (val !== 'capz' && ifDedicated({ model, getValue })) return true -} + const showSelectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') + if (val !== 'capz' && ifDedicated()) return true + } -const ifDedicated = ({ model, getValue }) => { - const val = getValue(model, 'form/capi/dedicated') - if (val) return true -} + const ifDedicated = () => { + const val = getValue(model, 'form/capi/dedicated') + if (val) return true + } -const dedicatedOnChange = ({ model, getValue, commit }) => { - const val = getValue(model, 'form/capi/dedicated') - if (!val) { - commit('wizard/model$delete', 'form/capi/zones') - commit('wizard/model$delete', 'form/capi/sku') + const dedicatedOnChange = () => { + const val = getValue(model, 'form/capi/dedicated') + if (!val) { + commit('wizard/model$delete', 'form/capi/zones') + commit('wizard/model$delete', 'form/capi/sku') + } } -} -const ifZones = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/zones') - watchDependency('model#/form/capi/dedicated') - const zones = getValue(model, 'form/capi/zones') || [] - const isDedicated = getValue(model, 'form/capi/dedicated') - if (zones.length && isDedicated) return true -} + const ifZones = () => { + // watchDependency('model#/form/capi/zones') + // watchDependency('model#/form/capi/dedicated') + const zones = getValue(model, 'form/capi/zones') || [] + const isDedicated = getValue(model, 'form/capi/dedicated') + if (zones.length && isDedicated) return true + } -const zonesOnChange = ({ model, getValue, commit }) => { - const zones = getValue(model, 'form/capi/zones') || [] - if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') -} + const zonesOnChange = () => { + const zones = getValue(model, 'form/capi/zones') || [] + if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') + } -async function getZones({ storeGet, axios, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const isDedicated = getValue(model, 'form/capi/dedicated') - if (isDedicated) { - try { - const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) - const val = resp.data.map((item) => { - return { value: item, text: item } - }) - return val - } catch (e) { - console.log(e) - return [] + async function getZones() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const isDedicated = getValue(model, 'form/capi/dedicated') + if (isDedicated) { + try { + const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) + const val = resp.data.map((item) => { + return { value: item, text: item } + }) + return val + } catch (e) { + console.log(e) + return [] + } } } -} -async function getSKU({ storeGet, axios, model, getValue, watchDependency }) { - watchDependency('model#/form/capi/zones') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const zones = getValue(model, 'form/capi/zones') || [] - if (zones.length) { - try { - let url = `clustersv2/${owner}/${cluster}/vms?` - if (typeof zones === 'string') { - url += `zones=${encodeURIComponent(zones)}` - } else { - zones.forEach((item) => { - url += `zones=${encodeURIComponent(item)}&` + async function getSKU() { + // watchDependency('model#/form/capi/zones') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const zones = getValue(model, 'form/capi/zones') || [] + if (zones.length) { + try { + let url = `clustersv2/${owner}/${cluster}/vms?` + if (typeof zones === 'string') { + url += `zones=${encodeURIComponent(zones)}` + } else { + zones.forEach((item) => { + url += `zones=${encodeURIComponent(item)}&` + }) + url = url.slice(0, -1) + } + const resp = await axios.get(url) + const val = resp.data.map((item) => { + return { + value: item.name, + text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, + } }) - url = url.slice(0, -1) + return val + } catch (e) { + console.log(e) + return [] } - const resp = await axios.get(url) - const val = resp.data.map((item) => { - return { - value: item.name, - text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, - } - }) - return val - } catch (e) { - console.log(e) - return [] } } -} -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false + } -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, }, - }, - ) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] + ) + if (resp.data?.status?.projects) { + const projects = resp.data?.status?.projects + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } + } catch (e) { + console.log(e) } - } catch (e) { - console.log(e) - } - return [] -} - -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} - -function updateAlertValue({ commit, model, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const alert = isMonitorEnabled ? 'warning' : 'none' - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: alert, - force: true, - }) - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} - -function setStorageClass({ model, getValue, commit, watchDependency, discriminator }) { - const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' - let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' - const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] - const suffix = '-retain' - - const simpleClassList = storageClassList.filter((item) => { - return !item.endsWith(suffix) - }) - const retainClassList = storageClassList.filter((item) => { - return item.endsWith(suffix) - }) - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] - } else { - storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + return [] } - const isChangeable = isToggleOn( - { getValue, model, watchDependency, discriminator }, - 'storageClasses', - ) - if (isChangeable && storageClass) { - commit('wizard/model$update', { - path: '/spec/admin/storageClasses/default', - value: storageClass, - force: true, - }) + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found } -} -function showAlerts({ watchDependency, model, getValue, discriminator }) { - watchDependency('discriminator#/monitoring') - const isMonitorEnabled = getValue(discriminator, '/monitoring') - return ( - isMonitorEnabled && isToggleOn({ getValue, model, discriminator, watchDependency }, 'alert') - ) -} + function setStorageClass() { + const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' + let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' + const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] + const suffix = '-retain' -function onBackupSwitch({ discriminator, getValue, commit }) { - const isBackupOn = getValue(discriminator, '/backup') - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: isBackupOn ? 'KubeStash' : '', - force: true, - }) -} - -function clearArbiterHidden({ commit }) { - commit('wizard/model$update', { - path: `/spec/arbiter/enabled`, - value: false, - force: true, - }) - - commit('wizard/model$update', { - path: `/spec/hidden/enabled`, - value: false, - force: true, - }) -} - -function isConfigDatabaseOn({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configDatabase') - return getValue(discriminator, '/configDatabase') -} -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} -function showHidden({ watchDependency, model, getValue }) { - watchDependency('model#/spec/hidden/enabled') - const isHiddenOn = getValue(model, '/spec/hidden/enabled') || '' - const notStandalone = notEqualToDatabaseMode({ model, getValue, watchDependency }, 'Standalone') - return isHiddenOn && notStandalone -} -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} -function showArbiter({ watchDependency, model, getValue }) { - watchDependency('model#/spec/arbiter/enabled') - const isArbiterOn = getValue(model, '/spec/arbiter/enabled') || '' - const notStandalone = notEqualToDatabaseMode({ model, getValue, watchDependency }, 'Standalone') - return isArbiterOn && notStandalone -} -function clearConfiguration({ discriminator, getValue, commit }) { - const configOn = getValue(discriminator, '/configDatabase') - - if (!configOn) { - commit('wizard/model$delete', '/spec/configuration') - } -} + const simpleClassList = storageClassList.filter((item) => { + return !item.endsWith(suffix) + }) + const retainClassList = storageClassList.filter((item) => { + return item.endsWith(suffix) + }) + if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { + storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] + } else { + storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + } -let placement = [] -let versions = [] -let storageClass = [] -let clusterIssuers = [] -let nodetopologiesShared = [] -let nodetopologiesDedicated = [] -let features = [] -async function initBundle({ commit, model, getValue, axios, storeGet, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - - let db = getValue(model, '/metadata/resource/kind') - db = db.toLowerCase() - let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` - const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - - try { - const resp = await axios.get(url) - features = resp.data.features || [] - placement = resp.data.placementpolicies || [] - versions = resp.data.versions || [] - storageClass = resp.data.storageclasses || [] - clusterIssuers = resp.data.clusterissuers || [] - nodetopologiesDedicated = resp.data.dedicated || [] - nodetopologiesShared = resp.data.shared || [] - - const response = await axios.get(annotationUrl) - const annotations = response.data?.metadata?.annotations || {} - const uidRange = annotations['openshift.io/sa.scc.uid-range'] - if (uidRange) { - const val = uidRange.split('/')[0] + const isChangeable = isToggleOn('storageClasses') + if (isChangeable && storageClass) { commit('wizard/model$update', { - path: '/spec/openshift/securityContext/runAsUser', - value: val, + path: '/spec/admin/storageClasses/default', + value: storageClass, force: true, }) } - } catch (e) { - console.log(e) } - commit('wizard/model$update', { - path: '/spec/deletionPolicy', - value: getDefault({ getValue, model }, 'deletionPolicy'), - force: true, - }) - - if (!getValue(model, `/spec/admin/databases/ProxySQL/mode/toggle`)) { - let defMode = getDefault({ getValue, model }, 'databases/ProxySQL/mode') || '' - if (defMode === '') { - const arr = getValue(model, '/spec/databases/ProxySQL/mode/available') || [] - if (arr.length) defMode = arr[0] - } + function showAlerts() { + // watchDependency('discriminator#/monitoring') + const isMonitorEnabled = getValue(discriminator, '/monitoring') + return isMonitorEnabled && isToggleOn('alert') + } + + function onBackupSwitch() { + const isBackupOn = getValue(discriminator, '/backup') commit('wizard/model$update', { - path: '/spec/mode', - value: defMode, + path: '/spec/backup/tool', + value: isBackupOn ? 'KubeStash' : '', force: true, }) } - if (!features.includes('tls')) { + function clearArbiterHidden() { commit('wizard/model$update', { - path: '/spec/admin/tls/default', + path: `/spec/arbiter/enabled`, value: false, force: true, }) - } - if (!features.includes('binding')) { + commit('wizard/model$update', { - path: '/spec/admin/expose/default', + path: `/spec/hidden/enabled`, value: false, force: true, }) } - if (!features.includes('monitoring')) { - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: 'none', - force: true, - }) + + function isConfigDatabaseOn() { + // watchDependency('discriminator#/configDatabase') + return getValue(discriminator, '/configDatabase') } - if (!features.includes('backup')) { - commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, - force: true, - }) - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: '', - force: true, - }) + + function notEqualToDatabaseMode(mode) { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + return modelPathValue && modelPathValue !== mode } - setDiscriminatorValue('/bundleApiLoaded', true) -} + function showHidden() { + // watchDependency('model#/spec/hidden/enabled') + const isHiddenOn = getValue(model, '/spec/hidden/enabled') || '' + const notStandalone = notEqualToDatabaseMode('Standalone') + return isHiddenOn && notStandalone + } -function fetchOptions({ model, getValue, commit }, type) { - let kind = getValue(model, '/metadata/resource/kind') - - let returnArray = [] - if (type === 'clusterTier/placement') { - returnArray = placement - } else if (type === `databases/${kind}/versions`) { - returnArray = versions - } else if (type === 'storageClasses') { - returnArray = storageClass - } else if (type === 'clusterIssuers') { - returnArray = clusterIssuers + function showArbiter() { + // watchDependency('model#/spec/arbiter/enabled') + const isArbiterOn = getValue(model, '/spec/arbiter/enabled') || '' + const notStandalone = notEqualToDatabaseMode('Standalone') + return isArbiterOn && notStandalone } - if (returnArray.length === 1) { - const path = `/spec/admin/${type}/default` + function clearConfiguration() { + const configOn = getValue(discriminator, '/configDatabase') + + if (!configOn) { + commit('wizard/model$delete', '/spec/configuration') + } + } + + let placement = [] + let versions = [] + let storageClass = [] + let clusterIssuers = [] + let nodetopologiesShared = [] + let nodetopologiesDedicated = [] + let features = [] + + async function initBundle() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + + let db = getValue(model, '/metadata/resource/kind') + db = db.toLowerCase() + let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` + const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` + + try { + const resp = await axios.get(url) + features = resp.data.features || [] + placement = resp.data.placementpolicies || [] + versions = resp.data.versions || [] + storageClass = resp.data.storageclasses || [] + clusterIssuers = resp.data.clusterissuers || [] + nodetopologiesDedicated = resp.data.dedicated || [] + nodetopologiesShared = resp.data.shared || [] + + const response = await axios.get(annotationUrl) + const annotations = response.data?.metadata?.annotations || {} + const uidRange = annotations['openshift.io/sa.scc.uid-range'] + if (uidRange) { + const val = uidRange.split('/')[0] + commit('wizard/model$update', { + path: '/spec/openshift/securityContext/runAsUser', + value: val, + force: true, + }) + } + } catch (e) { + console.log(e) + } + commit('wizard/model$update', { - path: path, - value: returnArray[0], + path: '/spec/deletionPolicy', + value: getDefault('deletionPolicy'), force: true, }) - } - return returnArray -} - -function getAdminOptions({ getValue, model, watchDependency, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') + if (!getValue(model, `/spec/admin/databases/ProxySQL/mode/toggle`)) { + let defMode = getDefault('databases/ProxySQL/mode') || '' + if (defMode === '') { + const arr = getValue(model, '/spec/databases/ProxySQL/mode/available') || [] + if (arr.length) defMode = arr[0] + } + commit('wizard/model$update', { + path: '/spec/mode', + value: defMode, + force: true, + }) + } - const options = getValue(model, `/spec/admin/${type}/available`) || [] + if (!features.includes('tls')) { + commit('wizard/model$update', { + path: '/spec/admin/tls/default', + value: false, + force: true, + }) + } + if (!features.includes('binding')) { + commit('wizard/model$update', { + path: '/spec/admin/expose/default', + value: false, + force: true, + }) + } + if (!features.includes('monitoring')) { + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: 'none', + force: true, + }) + } + if (!features.includes('backup')) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: '', + force: true, + }) + } - if (options.length === 0) { - return fetchOptions({ model, getValue, commit }, type) - } - if (type.endsWith('/mode')) { - return ( - options?.map((item) => ({ - description: modeDetails[item]?.description || '', - text: modeDetails[item]?.text || '', - value: item, - })) || [] - ) + setDiscriminatorValue('/bundleApiLoaded', true) } - return options -} -function checkIfFeatureOn({ getValue, model }, type) { - let val = getValue(model, `/spec/admin/${type}/toggle`) - if (type === 'backup' || type === 'archiver') { - val = getValue(model, `/spec/admin/${type}/enable/toggle`) - } - const backupVal = getValue(model, '/spec/backup/tool') - - if (type === 'backup') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } else if (type === 'tls') { - return features.includes('tls') && val - } else if (type === 'expose') { - return features.includes('binding') && val - } else if (type === 'monitoring') { - return features.includes('monitoring') && val - } else if (type === 'archiver') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } -} + function fetchOptions(type) { + let kind = getValue(model, '/metadata/resource/kind') + + let returnArray = [] + if (type === 'clusterTier/placement') { + returnArray = placement + } else if (type === `databases/${kind}/versions`) { + returnArray = versions + } else if (type === 'storageClasses') { + returnArray = storageClass + } else if (type === 'clusterIssuers') { + returnArray = clusterIssuers + } -function isToggleOn({ getValue, model, discriminator, watchDependency }, type) { - watchDependency('discriminator#/bundleApiLoaded') - watchDependency('model#/spec/admin/deployment/default') - const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') - let deploymentType = getValue(model, `/spec/admin/deployment/default`) - if ( - type === 'tls' || - type === 'backup' || - type === 'expose' || - type === 'monitoring' || - type === 'archiver' - ) { - return checkIfFeatureOn({ getValue, model }, type) - } else if ( - type === 'clusterTier' || - type === 'clusterTier/placement' || - type === 'clusterTier/nodeTopology' - ) { - if (deploymentType === 'Dedicated' && bundleApiLoaded) return true - else return false - } else if (type === 'deployment') { - const deploymentType = getValue(model, '/spec/admin/deployment/default') - if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + if (returnArray.length === 1) { + const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: '/spec/admin/deployment/default', - value: 'Shared', + path: path, + value: returnArray[0], force: true, }) } - return ( - getValue(model, `/spec/admin/${type}/toggle`) && - nodetopologiesDedicated.length && - bundleApiLoaded - ) - } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded -} -async function getNodeTopology({ model, getValue, axios, storeGet, watchDependency }) { - watchDependency('model#/spec/admin/deployment/default') - watchDependency('model#/spec/admin/clusterTier/default') - const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' - const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' - let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + return returnArray + } - const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + function getAdminOptions(type) { + // watchDependency('discriminator#/bundleApiLoaded') - if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared - else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + const options = getValue(model, `/spec/admin/${type}/available`) || [] - const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) - return filteredList -} + if (options.length === 0) { + return fetchOptions(type) + } + if (type.endsWith('/mode')) { + return ( + options?.map((item) => ({ + description: modeDetails[item]?.description || '', + text: modeDetails[item]?.text || '', + value: item, + })) || [] + ) + } + return options + } -function filterNodeTopology(list, tier, provider) { - // first filter the list from value that exists from the filtered list got from API - const filteredlist = list + function checkIfFeatureOn(type) { + let val = getValue(model, `/spec/admin/${type}/toggle`) + if (type === 'backup' || type === 'archiver') { + val = getValue(model, `/spec/admin/${type}/enable/toggle`) + } + const backupVal = getValue(model, '/spec/backup/tool') + + if (type === 'backup') { + return features.includes('backup') && backupVal === 'KubeStash' && val + } else if (type === 'tls') { + return features.includes('tls') && val + } else if (type === 'expose') { + return features.includes('binding') && val + } else if (type === 'monitoring') { + return features.includes('monitoring') && val + } else if (type === 'archiver') { + return features.includes('backup') && backupVal === 'KubeStash' && val + } + } - // filter the list based on clusterTier - if (provider === 'EKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('c') - else if (tier === 'MemoryOptimized') return item.startsWith('r') - else return !item.startsWith('c') && !item.startsWith('r') - }) - } else if (provider === 'AKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - else - return ( - !(item.startsWith('f') || item.startsWith('fx')) && - !( + function isToggleOn(type) { + // watchDependency('discriminator#/bundleApiLoaded') + // watchDependency('model#/spec/admin/deployment/default') + const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') + let deploymentType = getValue(model, `/spec/admin/deployment/default`) + if ( + type === 'tls' || + type === 'backup' || + type === 'expose' || + type === 'monitoring' || + type === 'archiver' + ) { + return checkIfFeatureOn(type) + } else if ( + type === 'clusterTier' || + type === 'clusterTier/placement' || + type === 'clusterTier/nodeTopology' + ) { + if (deploymentType === 'Dedicated' && bundleApiLoaded) return true + else return false + } else if (type === 'deployment') { + const deploymentType = getValue(model, '/spec/admin/deployment/default') + if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + commit('wizard/model$update', { + path: '/spec/admin/deployment/default', + value: 'Shared', + force: true, + }) + } + return ( + getValue(model, `/spec/admin/${type}/toggle`) && + nodetopologiesDedicated.length && + bundleApiLoaded + ) + } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded + } + + async function getNodeTopology() { + // watchDependency('model#/spec/admin/deployment/default') + // watchDependency('model#/spec/admin/clusterTier/default') + const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' + const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' + let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + + const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + + if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared + else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + + const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) + return filteredList + } + + function filterNodeTopology(list, tier, provider) { + // first filter the list from value that exists from the filtered list got from API + const filteredlist = list + + // filter the list based on clusterTier + if (provider === 'EKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('c') + else if (tier === 'MemoryOptimized') return item.startsWith('r') + else return !item.startsWith('c') && !item.startsWith('r') + }) + } else if (provider === 'AKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('e') || item.startsWith('eb') || item.startsWith('ec') || item.startsWith('m') || item.startsWith('d') ) - ) - }) - } else if (provider === 'GKE') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') - return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - else - return ( - !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && - !( + else + return ( + !(item.startsWith('f') || item.startsWith('fx')) && + !( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + ) + }) + } else if (provider === 'GKE') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') + return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('x4') || item.startsWith('m1') || item.startsWith('m2') || item.startsWith('m3') ) - ) - }) - } else return filteredlist -} + else + return ( + !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && + !( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + ) + }) + } else return filteredlist + } -function returnFalse() { - return false -} + function returnFalse() { + return false + } -function showIssuer({ model, getValue, watchDependency, discriminator }) { - watchDependency('model#/spec/admin/tls/default') - const isTlsEnabled = getValue(model, '/spec/admin/tls/default') - const isIssuerToggleEnabled = isToggleOn( - { getValue, model, watchDependency, discriminator }, - 'clusterIssuers', - ) - return isTlsEnabled && isIssuerToggleEnabled -} + function showIssuer() { + // watchDependency('model#/spec/admin/tls/default') + const isTlsEnabled = getValue(model, '/spec/admin/tls/default') + const isIssuerToggleEnabled = isToggleOn('clusterIssuers') + return isTlsEnabled && isIssuerToggleEnabled + } -function onAuthChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/authSecret/password', - value: '', - force: true, - }) -} + function onAuthChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/spec/authSecret/password', + value: '', + force: true, + }) + } -function setMonitoring({ getValue, model }) { - const agent = getValue(model, '/spec/admin/monitoring/agent') || '' - return !!agent -} + function setMonitoring() { + const agent = getValue(model, '/spec/admin/monitoring/agent') || '' + return !!agent + } -function setBackup({ model, getValue }) { - const backup = getValue(model, '/spec/backup/tool') - const val = getValue(model, '/spec/admin/backup/enable/default') - return backup === 'KubeStash' && features.includes('backup') && val -} + function setBackup() { + const backup = getValue(model, '/spec/backup/tool') + const val = getValue(model, '/spec/admin/backup/enable/default') + return backup === 'KubeStash' && features.includes('backup') && val + } -function isMachineCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue === 'custom' -} + function isMachineCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue === 'custom' + } -function isMachineNotCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue !== 'custom' && !!modelPathValue -} + function isMachineNotCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue !== 'custom' && !!modelPathValue + } -function EqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue === mode -} + function EqualToDatabaseMode(mode) { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + return modelPathValue && modelPathValue === mode + } -function showAdditionalSettings({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return features.length -} + function showAdditionalSettings() { + // watchDependency('discriminator#/bundleApiLoaded') + return features.length + } -function getDefault({ getValue, model }, type) { - const val = getValue(model, `/spec/admin/${type}/default`) || '' - return val -} + function getDefault(type) { + const val = getValue(model, `/spec/admin/${type}/default`) || '' + return val + } -function isConfigAvailable({ getValue, model }) { - const val = getValue(model, '/spec/configuration') - return val !== '' -} + async function getReferSecrets() { + const referSecret = getValue(discriminator, '/referSecret') + if (!referSecret) { + return [] + } -async function getReferSecrets({ getValue, model, storeGet, axios, discriminator }) { - const referSecret = getValue(discriminator, '/referSecret') - if (!referSecret) { - return [] - } + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/metadata/release/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/metadata/release/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - - const options = [] - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) - } catch (e) { - console.log(e) + const options = [] + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + return options } - return options -} -function showAuthPasswordField({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showAuthPasswordField() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !modelPathValue && showReferSecret() + } -function showSecretDropdown({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showSecretDropdown() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !!modelPathValue && showReferSecret() + } -function showReferSecret({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/createAuthSecret') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue -} + function showReferSecret() { + const modelPathValue = getValue(discriminator, '/createAuthSecret') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue + } -function getDefaultValue({ getValue, model }, path) { - const val = getValue(model, `/${path}`) || '' - return val -} + function getDefaultValue(path) { + const val = getValue(model, `/${path}`) || '' + return val + } -function showReferSecretSwitch({ model, getValue, watchDependency, discriminator }) { - const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showReferSecretSwitch() { + const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue && showReferSecret() + } -function onReferSecretChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) -} + function onReferSecretChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + } -return { - showReferSecretSwitch, - onReferSecretChange, - getDefaultValue, - isRancherManaged, - showSecretDropdown, - showReferSecret, - getReferSecrets, - isConfigAvailable, - initBundle, - returnFalse, - EqualToDatabaseMode, - getNamespaces, - updateAlertValue, - setStorageClass, - getAdminOptions, - isToggleOn, - showAlerts, - getNodeTopology, - clearArbiterHidden, - returnFalse, - showHidden, - isConfigDatabaseOn, - notEqualToDatabaseMode, - filterNodeTopology, - onAuthChange, - setMonitoring, - isMachineNotCustom, - isMachineCustom, - showIssuer, - showArbiter, - clearConfiguration, - onBackupSwitch, - isVariantAvailable, - fetchJsons, - showAuthPasswordField, - isEqualToModelPathValue, - showAuthSecretField, - getResources, - getProxysqlVersions, - getAppBindings, - onCreateAuthSecretChange, - getSecrets, - getMachineListForOptions, - setLimits, - setRequests, - setMachineToCustom, - updateAgentValue, - getCreateNameSpaceUrl, - ifCapiProviderIsNotEmpty, - ifDedicated, - dedicatedOnChange, - ifZones, - zonesOnChange, - getZones, - getSKU, - showMultiselectZone, - showSelectZone, - setBackup, - showAdditionalSettings, - getDefault, + return { + onReferSecretChange, + showReferSecretSwitch, + getDefaultValue, + isRancherManaged, + showSecretDropdown, + showReferSecret, + getReferSecrets, + initBundle, + returnFalse, + EqualToDatabaseMode, + getNamespaces, + updateAlertValue, + setStorageClass, + getAdminOptions, + isToggleOn, + showAlerts, + getNodeTopology, + clearArbiterHidden, + showHidden, + isConfigDatabaseOn, + notEqualToDatabaseMode, + filterNodeTopology, + onAuthChange, + setMonitoring, + isMachineNotCustom, + isMachineCustom, + showIssuer, + showArbiter, + clearConfiguration, + onBackupSwitch, + isVariantAvailable, + fetchJsons, + showAuthPasswordField, + isEqualToModelPathValue, + getResources, + getProxysqlVersions, + getAppBindings, + getSecrets, + getMachineListForOptions, + setLimits, + setRequests, + setMachineToCustom, + getCreateNameSpaceUrl, + ifCapiProviderIsNotEmpty, + ifDedicated, + dedicatedOnChange, + ifZones, + zonesOnChange, + getZones, + getSKU, + showMultiselectZone, + showSelectZone, + setBackup, + showAdditionalSettings, + getDefault, + } } diff --git a/charts/kubedbcom-proxysql-editor/ui/edit-ui.yaml b/charts/kubedbcom-proxysql-editor/ui/edit-ui.yaml index 1bbaf1d975..63da2d2b31 100644 --- a/charts/kubedbcom-proxysql-editor/ui/edit-ui.yaml +++ b/charts/kubedbcom-proxysql-editor/ui/edit-ui.yaml @@ -1,985 +1,482 @@ -steps: -- form: - elements: - - disabled: true - label: - text: labels.database.name - schema: - $ref: schema#/properties/metadata/properties/release/properties/name - type: input - - disabled: true - label: - text: labels.namespace - schema: - $ref: schema#/properties/metadata/properties/release/properties/namespace - type: input - - disabled: true - label: - text: labels.database.version - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/version - type: input - - disabled: true - label: - text: labels.replicas - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/replicas - type: input - - individualItemDisabilityCheck: disableLableChecker - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - onChange: onLabelChange - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/metadata/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/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/kubedbComProxySQL/properties/metadata/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/metadata/properties/annotations/additionalProperties - type: input - - hasDescription: true - label: - text: labels.deletionPolicy - options: - - description: options.deletionPolicy.delete.description - text: options.deletionPolicy.delete.label - value: Delete - - 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/kubedbComProxySQL/properties/spec/properties/deletionPolicy - type: radio - - label: - text: labels.backend_section - type: label-element - - disabled: true - label: - text: labels.backend - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/backend/properties/name - type: input - - label: - text: labels.sync_users_question - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/syncUsers - type: switch - - label: - text: labels.database.secret - type: label-element - - disabled: true - label: - text: labels.secret - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/authSecret/properties/name - type: input - type: single-step-form - id: basic - title: steps.0.label -- form: - elements: - - alias: reusable_alert - chart: - name: uibytebuildersdev-component-alert - version: v0.29.0 - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/form/properties/alert - type: reusable-element - type: single-step-form - id: alert - title: steps.1.label -- form: - discriminator: - configureTLS: - default: true - type: boolean - elements: - - label: - text: labels.to_update_tls - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - function: getOpsRequestUrl|ReconfigureTLS - - computed: isValueExistInModel|/resources/kubedbComProxySQL/spec/tls - disabled: true - label: - text: labels.enable_tls - onChange: onTlsConfigureChange - schema: - $ref: discriminator#/configureTLS - type: switch - - disabled: true - elements: - - elements: - - computed: setApiGroup - disabled: true - label: - text: labels.api_group - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/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/kubedbComProxySQL/properties/spec/properties/tls/properties/issuerRef/properties/kind - type: select - - allowUserDefinedOption: true - fetch: getIssuerRefsName - label: - text: labels.name - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/tls/properties/issuerRef/properties/name - type: select - label: - text: labels.issuer_ref - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/tls/properties/issuerRef - type: single-step-form - - alias: reusable_certificates - chart: - name: uibytebuildersdev-component-certificates - version: v0.29.0 - functionCallbacks: - getAliasOptions: - $ref: functions#/getAliasOptions - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/tls/properties/certificates - type: reusable-element - if: showTlsConfigureSection - type: single-step-form - type: single-step-form - id: tls - title: steps.3.label -- form: - elements: - - alias: reusable_health_checker - chart: - name: uibytebuildersdev-component-health-checker - version: v0.29.0 - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/healthChecker - type: reusable-element - type: single-step-form - id: health-checker - title: steps.4.label -- form: +type: multi-step-form +step: + - type: single-step-form + id: compute-autoscaler + loader: getDbDetails elements: - - label: - text: labels.to_update_disabled_section - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - function: getOpsRequestUrl|Reconfigure - - disabled: true - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.initConfig.adminVariables - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/initConfig/properties/adminVariables - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/initConfig/properties/adminVariables - type: input - - disabled: true - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.initConfig.mysqlVariables - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/initConfig/properties/mysqlVariables - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/initConfig/properties/mysqlVariables - type: input - - addFormLabel: labels.initConfig.mysqlQueryRule - computed: setMySQLRules - disabled: true - element: - discriminator: - mysqlQueryRules: - emitAs: mysqlQueryRules - type: array - elements: - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.initConfig.rules - schema: - $ref: discriminator#/properties/mysqlQueryRules/items/properties/rules - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: discriminator#/properties/mysqlQueryRules/items/properties/rules/additionalProperties - type: input - schema: - $ref: discriminator#/properties/mysqlQueryRules/items - type: single-step-form - label: - text: labels.initConfig.mysqlQueryRules - onChange: onMySQLRulesChange - schema: - $ref: discriminator#/properties/mysqlQueryRules - tableContents: - - inTableColumn: true - label: - text: labels.initConfig.rules - path: rules - type: value - typeOfValue: key-value - type: single-step-form-array - - addFormLabel: labels.initConfig.mysqlUser - customClass: mt-20 - disabled: true - element: + - type: block-layout + if: + type: function + name: isConsole elements: - - label: - text: labels.initConfig.username - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/initConfig/properties/mysqlUsers/items/properties/username - type: input - - label: - text: labels.initConfig.active - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/initConfig/properties/mysqlUsers/items/properties/active - type: input - - label: - text: labels.initConfig.default_schema - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/initConfig/properties/mysqlUsers/items/properties/default_schema - type: input - - label: - text: labels.initConfig.use_ssl - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/initConfig/properties/mysqlUsers/items/properties/use_ssl - type: input - - label: - text: labels.initConfig.attributes - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/initConfig/properties/mysqlUsers/items/properties/attributes - type: input - - label: - text: labels.initConfig.backend - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/initConfig/properties/mysqlUsers/items/properties/backend - type: input - - label: - text: labels.initConfig.comment - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/initConfig/properties/mysqlUsers/items/properties/comment - type: input - - label: - text: labels.initConfig.default_hostgroup - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/initConfig/properties/mysqlUsers/items/properties/default_hostgroup - type: input - - label: - text: labels.initConfig.fast_forward - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/initConfig/properties/mysqlUsers/items/properties/fast_forward - type: input - - label: - text: labels.initConfig.frontend - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/initConfig/properties/mysqlUsers/items/properties/frontend - type: input - - label: - text: labels.initConfig.max_connections - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/initConfig/properties/mysqlUsers/items/properties/max_connections - type: input - - label: - text: labels.initConfig.schema_locked - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/initConfig/properties/mysqlUsers/items/properties/schema_locked - type: input - - label: - text: labels.initConfig.transaction_persistent - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/initConfig/properties/mysqlUsers/items/properties/transaction_persistent - type: input - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/initConfig/properties/mysqlUsers/items - type: single-step-form - label: - text: labels.initConfig.mysqlUsers - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/initConfig/properties/mysqlUsers - tableContents: - - inTableColumn: true - label: - text: labels.initConfig.username - path: username - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.initConfig.active - path: active - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.initConfig.default_schema - path: default_schema - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.initConfig.use_ssl - path: use_ssl - type: value - typeOfValue: string - - label: - text: labels.initConfig.attributes - path: attributes - type: value - typeOfValue: string - - label: - text: labels.initConfig.backend - path: backend - type: value - typeOfValue: string - - label: - text: labels.initConfig.comment - path: comment - type: value - typeOfValue: string - - label: - text: labels.initConfig.default_hostgroup - path: default_hostgroup - type: value - typeOfValue: string - - label: - text: labels.initConfig.fast_forward - path: fast_forward - type: value - typeOfValue: string - - label: - text: labels.initConfig.frontend - path: frontend - type: value - typeOfValue: string - - label: - text: labels.initConfig.max_connections - path: max_connections - type: value - typeOfValue: string - - label: - text: labels.initConfig.schema_locked - path: schema_locked - type: value - typeOfValue: string - - label: - text: labels.initConfig.transaction_persistent - path: transaction_persistent - type: value - typeOfValue: string - type: single-step-form-array - type: single-step-form - id: init-config - title: steps.5.label -- form: - discriminator: - enableMonitoring: - default: true - type: boolean - elements: - - label: - text: labels.to_update_exporter_resources - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - function: getOpsRequestUrl|VerticalScaling - - computed: isValueExistInModel|/resources/kubedbComProxySQL/spec/monitor - 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 + - type: input + label: Name + schema: schema/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/metadata/properties/name + - type: select + label: Select Namespace + loader: getNamespaces + if: + type: function + name: isRancherManaged + schema: schema/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/metadata/properties/namespace + - type: select + label: Select Db + loader: getDbs + validation: + type: required + refresh: true + schema: schema/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/databaseRef/properties/name + watcher: + func: initMetadata + paths: + - schema/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/databaseRef/properties/name + + - type: radio + if: + type: function + name: isConsole + label: Select Type + validation: + type: required + schema: temp/properties/autoscalingType + watcher: + func: initMetadata + paths: + - temp/properties/autoscalingType 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/kubedbComProxySQL/properties/spec/properties/monitor/properties/agent - type: radio - - elements: - - label: - text: labels.scrapping_interval - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval - type: input - if: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComProxySQL/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/kubedbComProxySQL/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/kubedbComProxySQL/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: - - if: returnFalse - label: - text: labels.resources - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/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/kubedbComProxySQL/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/kubedbComProxySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup - type: input - - label: - text: labels.port - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/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/kubedbComProxySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args/items - type: input - label: - text: labels.args - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args - type: list-input-form - - alias: reusable_env - chart: - name: uibytebuildersdev-component-env - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/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: - - label: - text: labels.to_update_disabled_section - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - function: getOpsRequestUrl - - alias: pod_template_standalone - chart: - name: uibytebuildersdev-component-pod-template - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - functionCallbacks: - isEditWizard: - $ref: functions#/returnTrue - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/podTemplate - type: reusable-element - type: single-step-form - id: pod-template - title: steps.7.label -- form: - elements: - - alias: reusable_service_templates - chart: - name: uibytebuildersdev-component-service-templates - version: v0.29.0 - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/serviceTemplates - type: reusable-element - type: single-step-form - id: networking - title: steps.8.label -- form: - elements: - - label: - text: labels.to_update_config - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - function: getOpsRequestUrl|Reconfigure - - disabled: true - discriminator: - setCustomConfig: - type: string - elements: - - computed: setCustomConfigConfigureChoice - label: - text: labels.setCustomConfig - options: - - text: options.yesOrNo.yes.text - value: "yes" - - text: options.yesOrNo.no.text - value: "no" - schema: - $ref: discriminator#/properties/setCustomConfig - type: radio - - discriminator: - configurationSource: - default: use-existing-config - type: string + - text: Compute + value: compute + description: Scale your CPU Memory based on resource usage + - text: Storage + value: storage + description: Expand your database size based on volume usage + + - type: block-layout + showLabels: false + loader: fetchTopologyMachines elements: - - label: - text: labels.custom_config - 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#/properties/configurationSource - type: radio - - label: - text: labels.name - schema: - $ref: schema#/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/configSecret/properties/name - type: input - if: isEqualToDiscriminatorPath|yes|/setCustomConfig - type: single-step-form - type: single-step-form - type: single-step-form - id: custom-config - title: steps.9.label -- form: - discriminator: - dbDetails: - default: false - type: boolean + # proxysql mode + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComProxySQLAutoscaler/spec/compute/proxysql/trigger + schema: temp/properties/compute/properties/proxysql/properties/trigger + watcher: + func: onTriggerChange|compute/proxysql + paths: + - temp/properties/compute/properties/proxysql/properties/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/proxysql/properties/podLifeTimeThreshold + customClass: width-300 + - type: block-layout + label: ProxySQL + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/proxysql + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/proxysql/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-proxysql-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|proxysql|min + loader: + name: getMachines|proxysql|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-proxysql-max + watcher: + func: onMachineChange|proxysql + paths: + - temp/properties/allowedMachine-proxysql-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/proxysql/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/proxysql/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-proxysql-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|proxysql|max + loader: + name: getMachines|proxysql|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-proxysql-min + watcher: + func: onMachineChange|proxysql + paths: + - temp/properties/allowedMachine-proxysql-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/proxysql/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/proxysql/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|compute/proxysql + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/proxysql/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/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/proxysql/properties/containerControlledValues + - type: block-layout + label: NodeTopology + if: + type: function + name: hasNoAnnotations + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/nodeTopology + elements: + - type: select + label: Select NodeTopology + loader: fetchNodeTopology + schema: schema/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name + - type: threshold-input + label: Scale Up DiffPercentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage + - type: threshold-input + label: Scale Down DiffPercentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + # schema: schema/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/opsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: monitoring + loader: initMonitoring elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: Select Db - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: Select Type - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - discriminator: - topologyMachines: - default: [] - type: array + - type: label-element + label: To update Exporter Resource section click on Create OpsRequest + - type: anchor + label: Create OpsRequest + schema: temp/properties/opsRequestUrl + init: + type: func + value: getOpsRequestUrl|scale-vertically + - type: switch + label: Enable Monitoring + fullwidth: true + schema: temp/properties/enableMonitoring + init: + type: func + value: isValueExistInModel|/resources/kubedbComProxySQL/spec/monitor + watcher: + func: onEnableMonitoringChange + paths: + - temp/properties/enableMonitoring + - type: block-layout + if: + type: function + name: showMonitoringSection elements: - - fetch: fetchTopologyMachines - if: returnFalse - schema: - $ref: discriminator#/topologyMachines - type: input - - elements: - - computed: setTrigger|autoscalingKubedbComProxySQLAutoscaler/spec/compute/proxysql/trigger - label: - text: Trigger + - type: radio + label: Select a Monitoring Method + schema: schema/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/monitor/properties/agent + isHorizontal: true options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/proxysql/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/proxysql/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/proxysql/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-max: - type: string - allowedMachine-min: - type: string + - text: Prometheus Operator + value: prometheus.io/operator + description: Inject metric exporter sidecar and creates a ServiceMonitor + - text: Custom ServiceMonitor + value: prometheus.io + description: Injects the metric exporter sidecar and let you customize ServiceMonitor + - text: Custom Scrapper + value: prometheus.io/builtin + description: Inject metric exporter sidecar and add Prometheus annotations to the stats Service + init: + type: static + value: prometheus.io/operator + watcher: + func: onAgentChange + paths: + - schema/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/monitor/properties/agent + - type: block-layout + label: ServiceMonitor Configuration + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComProxySQL/spec/monitor/agent elements: - - computed: setAllowedMachine|min - disableUnselect: true - fetch: getMachines|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|proxysql - schema: - $ref: discriminator#/properties/allowedMachine-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/proxysql/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/proxysql/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/proxysql/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|max - disableUnselect: true - fetch: getMachines|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|proxysql - schema: - $ref: discriminator#/properties/allowedMachine-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/proxysql/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/proxysql/properties/maxAllowed/properties/memory + - label: Scrapping Interval + schema: schema/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/proxysql/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|proxysql - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/proxysql/properties/controlledResources - type: multiselect - label: - text: ProxySQL - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/proxysql - show_label: true - type: single-step-form - - elements: - - fetch: fetchNodeTopology - label: - text: Select Node Topology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name - type: select - - if: isNodeTopologySelected - label: - text: ScaleUp Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage - type: input - - if: isNodeTopologySelected - label: - text: ScaleDown Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage - type: input - if: hasNoAnnotations - label: - text: NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/compute/properties/nodeTopology - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComProxySQLAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: compute-autoscaler - title: steps.6.label -type: multi-step-form + - type: block-layout + label: Service Monitor + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComProxySQL/spec/monitor/agent + elements: + - type: array-object-form + label: Endpoints + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/endpoints + elements: + - type: switch + label: Honor labels + fullwidth: true + schema: honorLabels + - type: input + label: Interval + schema: interval + validation: + type: required + - type: input + label: Path + schema: path + validation: + type: required + - type: input + label: Port + schema: port + validation: + type: required + - type: select + multiple: true + label: Match Namespaces + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/namespaceSelector/properties/matchNames + loader: getResources|core|v1|namespaces + if: + type: function + name: returnFalse + - type: block-layout + showLabels: false + # schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector + if: + type: function + name: returnFalse + elements: + - type: object-item + label: Labels + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector/properties/matchLabels + - type: object-item + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/metadata/properties/labels + label : Labels + buttonClass: is-light is-outlined + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComProxySQL/spec/monitor/agent + # individualItemDisabilityCheck: disableLableChecker + - type: label-element + label: Exporter Configuration + schema: '' + - type: switch + label: Customize Exporter Sidecar + fullwidth: true + schema: temp/properties/customizeExporter + init: + type: static + value: true + watcher: + func: onCustomizeExporterChange + paths: + - temp/properties/customizeExporter + - type: block-layout + label: Customer Exporter Section + showLabels: false + if: + type: function + name: showCustomizeExporterSection + elements: + - type: machine-compare + label: Resources + schema: schema/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/resources + if: + type: function + name: returnFalse + - type: label-element + label: Security Context + schema: '' + - type: input + schema: schema/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsUser + label: Run as User + - type: input + schema: schema/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup + label: Run as Group + - type: input + schema: schema/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/port + label: Port + - type: array-item-form + label: Args + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/kubedbComProxySQL/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args + init: + type: static + value: ['--compatible-mode'] + element: + type: input + label: Args + # isSubsection: true + - type: block-layout + label: Metadata + showLabels: false + elements: + - type: array-object-form + init: + type: func + value: initEnvArray + label: Environment Variables + buttonClass: is-light is-outlined + watcher: + func: onEnvArrayChange + paths: + - temp/properties/env + schema: temp/properties/env + elements: + - type: input + label: Name + schema: name + validation: + type: required + - type: radio + label: Value From + schema: temp/properties/valueFromType + validation: + type: required + init: + type: func + value: setValueFrom + options: + - text: Input + value: input + - text: Secret + value: secret + - text: ConfigMap + value: configMap + watcher: + func: onValueFromChange + paths: + - temp/properties/valueFromType + - type: input + label: Value + schema: value + validation: + type: required + if: + name: isEqualToTemp|input + type: function + - type: select + if: + type: function + name: isEqualToTemp|configMap + label: ConfigMap Name + schema: valueFrom/properties/configMapKeyRef/properties/name + loader: + name: resourceNames|core|v1|configmaps + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: ConfigMap Key + schema: valueFrom/properties/configMapKeyRef/properties/key + if: + type: function + name: isEqualToTemp|configMap + loader: + name: getConfigMapKeys + watchPaths: + - schema/resources/kubedbComProxySQL/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/configMapKeyRef/name + - schema/metadata/release/namespace + - type: select + label: Secret Name + schema: valueFrom/properties/secretKeyRef/properties/name + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecrets + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: Secret Key + schema: valueFrom/properties/secretKeyRef/properties/key + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecretKeys + watchPaths: + - schema/resources/kubedbComProxySQL/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/secretKeyRef/name + - schema/metadata/release/namespace + \ No newline at end of file diff --git a/charts/kubedbcom-proxysql-editor/ui/functions.js b/charts/kubedbcom-proxysql-editor/ui/functions.js index 6f3acdde68..dc6abf2cce 100644 --- a/charts/kubedbcom-proxysql-editor/ui/functions.js +++ b/charts/kubedbcom-proxysql-editor/ui/functions.js @@ -1,1264 +1,893 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + // ************************* common functions ******************************************** // eslint-disable-next-line no-empty-pattern -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 disableLableChecker({ itemCtx }) { - const { key } = itemCtx - if (key.startsWith('app.kubernetes.io') || key.includes('helm')) return true - else return false -} - -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} - -async function getResources({ axios, storeGet }, 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 } } } }, - }, - ) +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) - const resources = (resp && resp.data && resp.data.items) || [] + 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 autoscaleType = '' + let dbDetails = {} + let instance = '' + + function isConsole() { + const isKube = isKubedb() + + if (isKube) { + const dbName = storeGet('/route/params/name') || '' + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComProxySQLAutoscaler/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/autoscalingKubedbComProxySQLAutoscaler/metadata/name', + value: modifiedName, + force: true, + }) + const namespace = storeGet('/route/query/namespace') || '' + if (namespace) { + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComProxySQLAutoscaler/metadata/namespace', + value: namespace, + force: true, + }) + } + } - 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 [] + return !isKube } -} - -function isEqualToDiscriminatorPath( - { discriminator, getValue, watchDependency }, - value, - discriminatorPath, -) { - watchDependency('discriminator#' + discriminatorPath) - const discriminatorValue = getValue(discriminator, discriminatorPath) - return discriminatorValue === value -} - -function setValueFromModel({ getValue, model }, path) { - return getValue(model, path) -} - -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) + function isKubedb() { + return !!storeGet('/route/params/actions') } - return ans -} - -async function getResourceList(axios, storeGet, { 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) + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found } - return ans -} - -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - 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) - }) + function showOpsRequestOptions() { + if (isKubedb() === true) return true + // watchDependency('model#/resources/autoscalingKubedbComProxySQLAutoscaler/spec/databaseRef/name') + // watchDependency('discriminator#/autoscalingType') + return ( + !!getValue( + model, + '/resources/autoscalingKubedbComProxySQLAutoscaler/spec/databaseRef/name', + ) && !!getValue(discriminator, '/autoscalingType') + ) } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + async function getNamespaces() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) - - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, }) - } - - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} - -function returnTrue() { - return true -} - -function returnFalse() { - return false -} - -function returnStringYes() { - return 'yes' -} - -// ************************* Basic Info ********************************************** -async function getProxySQLVersions({ axios, storeGet }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, - }, - }, - } - - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/catalog.kubedb.com/v1alpha1/proxysqlversions`, - { - params: queryParams, - }, - ) const resources = (resp && resp.data && resp.data.items) || [] - // keep only non deprecated versions - const filteredDbVersions = resources.filter((item) => item.spec && !item.spec.deprecated) - - filteredDbVersions.map((item) => { + return resources.map((item) => { const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true + return { + text: name, + value: name, + } }) - return filteredDbVersions - } catch (e) { - console.log(e) - return [] } -} -async function getAppBindings({ axios, storeGet }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { type: null }, - }, - }, - } + async function getDbs() { + // watchDependency('model#/resources/autoscalingKubedbComProxySQLAutoscaler/metadata/namespace') + const namespace = getValue( + model, + '/resources/autoscalingKubedbComProxySQLAutoscaler/metadata/namespace', + ) + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - try { const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/appcatalog.appscode.com/v1alpha1/appbindings`, + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises`, { - params: queryParams, + params: { filter: { items: { metadata: { name: null } } } }, }, ) const resources = (resp && resp.data && resp.data.items) || [] - const fileredResources = resources - .filter( - (item) => - item.spec?.type === 'kubedb.com/mysql' || item.spec?.type === 'kubedb.com/mariadb', - ) - .map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) - return fileredResources - } catch (e) { - console.log(e) - return [] - } -} - -// ************************** TLS ******************************88 - -function setApiGroup() { - return 'cert-manager.io' -} - -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - watchDependency('model#/resources/kubedbComProxySQL/spec/tls/issuerRef/apiGroup') - watchDependency('model#/resources/kubedbComProxySQL/spec/tls/issuerRef/kind') - watchDependency('model#/metadata/release/namespace') - const apiGroup = getValue(model, '/resources/kubedbComProxySQL/spec/tls/issuerRef/apiGroup') - const kind = getValue(model, '/resources/kubedbComProxySQL/spec/tls/issuerRef/kind') - const namespace = getValue(model, '/metadata/release/namespace') - - let url - if (kind === 'Issuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/namespaces/${namespace}/issuers` - } else if (kind === 'ClusterIssuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/clusterissuers` - } - - if (!url) return [] - - try { - const resp = await axios.get(url) - - const resources = (resp && resp.data && resp.data.items) || [] - - resources.map((item) => { + return resources.map((item) => { const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + return { + text: name, + value: name, + } }) - return resources - } catch (e) { - console.log(e) - return [] } -} - -async function hasIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await getIssuerRefsName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !!(resp && resp.length) -} - -async function hasNoIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await hasIssuerRefName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !resp -} -function showTlsConfigureSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configureTLS') - const configureStatus = getValue(discriminator, '/configureTLS') - return configureStatus -} + async function getDbDetails() { + const owner = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + const namespace = + storeGet('/route/query/namespace') || + getValue(model, '/resources/autoscalingKubedbComProxySQLAutoscaler/metadata/namespace') || + '' + const name = + storeGet('/route/params/name') || + getValue(model, '/resources/autoscalingKubedbComProxySQLAutoscaler/spec/databaseRef/name') || + '' + + if (namespace && name) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/proxysqls/${name}`, + ) + dbDetails = resp.data || {} + setDiscriminatorValue('/dbDetails', true) + } catch (e) { + console.log(e) + } + } -function onTlsConfigureChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/configureTLS') - if (configureStatus) { commit('wizard/model$update', { - path: '/resources/kubedbComProxySQL/spec/tls', - value: { issuerRef: {}, certificates: [] }, + path: `/metadata/release/name`, + value: name, force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComProxySQL/spec/tls') - commit('wizard/model$delete', '/resources/kubedbComProxySQL/spec/sslMode') - } -} - -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} - -/****** Monitoring *********/ - -function showMonitoringSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/enableMonitoring') - const configureStatus = getValue(discriminator, '/enableMonitoring') - return configureStatus -} - -function onEnableMonitoringChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/enableMonitoring') - if (configureStatus) { commit('wizard/model$update', { - path: '/resources/kubedbComProxySQL/spec/monitor', - value: {}, + path: `/metadata/release/namespace`, + value: namespace, force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComProxySQL/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, getValue }) { - watchDependency('discriminator#/customizeExporter') - const configureStatus = getValue(discriminator, '/customizeExporter') - return configureStatus -} - -function onCustomizeExporterChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/customizeExporter') - if (configureStatus) { commit('wizard/model$update', { - path: '/resources/kubedbComProxySQL/spec/monitor/prometheus/exporter', - value: {}, + path: `/resources/autoscalingKubedbComProxySQLAutoscaler/spec/databaseRef/name`, + value: name, force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComProxySQL/spec/monitor/prometheus/exporter') - } -} - -function isValueExistInModel({ model, getValue }, path) { - const modelValue = getValue(model, path) - return !!modelValue -} - -function onNamespaceChange({ commit, model, getValue }) { - const namespace = getValue(model, '/metadata/release/namespace') - const agent = getValue(model, '/resources/kubedbComProxySQL/spec/monitor/agent') - if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', - value: [namespace], + path: `/resources/autoscalingKubedbComProxySQLAutoscaler/metadata/labels`, + value: dbDetails.metadata.labels, force: true, }) } -} - -function onLabelChange({ commit, model, getValue }) { - const labels = getValue(model, '/resources/kubedbComProxySQL/spec/metadata/labels') - const agent = getValue(model, '/resources/kubedbComProxySQL/spec/monitor/agent') + function initMetadata() { + const dbName = + getValue(model, '/resources/autoscalingKubedbComProxySQLAutoscaler/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/autoscalingKubedbComProxySQLAutoscaler/metadata/name', + value: modifiedName, + force: true, + }) - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) + // delete the other type object from model + if (type === 'compute') + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComProxySQLAutoscaler/spec/storage', + ) + if (type === 'storage') + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComProxySQLAutoscaler/spec/compute', + ) } -} - -function onNameChange({ commit, model, getValue }) { - const dbName = getValue(model, '/metadata/release/name') - const agent = getValue(model, '/resources/kubedbComProxySQL/spec/monitor/agent') + 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 [] + } - const labels = getValue(model, '/resources/kubedbComProxySQL/spec/metadata/labels') + function isNodeTopologySelected() { + // watchDependency( + // 'model#/resources/autoscalingKubedbComProxySQLAutoscaler/spec/compute/nodeTopology/name', + // ) + const nodeTopologyName = + getValue( + model, + '/resources/autoscalingKubedbComProxySQLAutoscaler/spec/compute/nodeTopology/name', + ) || '' + return !!nodeTopologyName.length + } - if (agent === 'prometheus.io') { + function setControlledResources(type) { + const list = ['cpu', 'memory'] + const path = `/resources/autoscalingKubedbComProxySQLAutoscaler/spec/compute/${type}/controlledResources` commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, + path: path, + value: list, force: true, }) + return list } - // to reset configSecret name field - const hasSecretConfig = getValue(model, '/resources/secret_config') - if (hasSecretConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComProxySQL/spec/configSecret/name', - value: `${dbName}-config`, - force: true, - }) + function setTrigger(path) { + let value = getValue(model, `/resources/${path}`) + if (value) return value + return 'On' } -} -function onAgentChange({ commit, model, getValue }) { - const agent = getValue(model, '/resources/kubedbComProxySQL/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', - value: [], - force: true, - }) + function setApplyToIfReady() { + return 'IfReady' + } + + async function fetchTopologyMachines() { + const annotations = + getValue(model, '/resources/autoscalingKubedbComProxySQLAutoscaler/metadata/annotations') || + {} + instance = annotations['kubernetes.io/instance-type'] - onNamespaceChange({ commit, model, getValue }) - onLabelChange({ commit, model, getValue }) - } else { - commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') + 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 [] + } + } } -} -/************************************* Database Secret Section ********************************************/ + function setAllowedMachine(minmax) { + const mx = instance?.includes(',') ? instance.split(',')[1] : '' + const mn = instance?.includes(',') ? instance.split(',')[0] : '' + const machineName = minmax === 'min' ? mn : mx -function getCreateAuthSecret({ model, getValue }) { - const authSecret = getValue(model, '/resources/kubedbComProxySQL/spec/authSecret') + // Find the machine details from topologyMachines + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] + const machineData = nodeGroups.find((item) => item.topologyValue === machineName) - return !authSecret -} + // 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 showExistingSecretSection({ getValue, watchDependency, discriminator }) { - watchDependency('discriminator#/createAuthSecret') - const hasAuthSecretName = getValue(discriminator, '/createAuthSecret') - return !hasAuthSecretName -} + function getMachines(minmax) { + // watchDependency('discriminator#/topologyMachines') + const depends = minmax === 'min' ? 'max' : 'min' + const dependantPath = `/allowedMachine-${depends}` -function showPasswordSection({ getValue, watchDependency, discriminator }) { - return !showExistingSecretSection({ - getValue, - watchDependency, - discriminator, - }) -} + // watchDependency(`discriminator#${dependantPath}`) + const dependantMachineObj = getValue(discriminator, dependantPath) + const dependantMachine = dependantMachineObj?.machine || '' -function setAuthSecretPassword({ model, getValue }) { - const encodedPassword = getValue(model, '/resources/secret_auth/data/password') - return encodedPassword ? decodePassword({}, encodedPassword) : '' -} + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] -function onAuthSecretPasswordChange({ getValue, discriminator, commit }) { - const stringPassword = getValue(discriminator, '/password') + const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) - if (stringPassword) { - commit('wizard/model$update', { - path: '/resources/secret_auth/data/password', - value: encodePassword({}, stringPassword), - force: true, - }) - commit('wizard/model$update', { - path: '/resources/secret_auth/data/username', - value: encodePassword({}, 'root'), - force: true, + // 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, + }, + } }) - } else { - commit('wizard/model$delete', '/resources/secret_auth') + + const filteredMachine = machines?.filter((item, ind) => + minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, + ) + + return dependantIndex === -1 ? machines : filteredMachine } -} -function disableInitializationSection({ model, getValue, watchDependency }) { - const initialized = getValue(model, '/resources/kubedbComProxySQL/spec/init/initialized') - watchDependency('model#/resources/kubedbComProxySQL/spec/init/initialized') - return !!initialized -} + function hasAnnotations() { + const annotations = + getValue(model, '/resources/autoscalingKubedbComProxySQLAutoscaler/metadata/annotations') || + {} + const instance = annotations['kubernetes.io/instance-type'] -// eslint-disable-next-line no-empty-pattern -function encodePassword({}, value) { - return btoa(value) -} + return !!instance + } -// eslint-disable-next-line no-empty-pattern -function decodePassword({}, value) { - return atob(value) -} + function hasNoAnnotations() { + return !hasAnnotations() + } -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/resources/kubedbComProxySQL/spec/authSecret') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/resources/secret_auth') + function onMachineChange(type) { + const annoPath = '/resources/autoscalingKubedbComProxySQLAutoscaler/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/autoscalingKubedbComProxySQLAutoscaler/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, + }) + } } -} -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') + /************ Monitoring ************/ + + 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') - if (owner && cluster && namespace) { try { const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, { - params: { - filter: { - items: { - data: { username: null, password: null }, - metadata: { name: null }, - type: null, - }, - }, - }, + params: { filter: { items: { metadata: { name: null } } } }, }, ) - const secrets = (resp && resp.data && resp.data.items) || [] - - const filteredSecrets = secrets.filter((item) => { - const validType = [ - 'kubernetes.io/service-account-token', - 'Opaque', - 'kubernetes.io/basic-auth', - ] - return validType.includes(item.type) - }) + const resources = (resp && resp.data && resp.data.items) || [] - filteredSecrets.map((item) => { + resources.map((item) => { const name = (item.metadata && item.metadata.name) || '' item.text = name item.value = name return true }) - return filteredSecrets + return resources } catch (e) { console.log(e) + return [] } } - return [] -} -//////////////////// custom config ///////////////// -function onConfigurationSourceChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSource') - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_config') - } else { - const value = getValue(model, '/resources/secret_config') - if (!value) { + 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 + } + + 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/secret_config', + path: '/resources/kubedbComProxySQL/spec/monitor', value: {}, force: true, }) + } else { + commit('wizard/model$delete', '/resources/kubedbComProxySQL/spec/monitor') } - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` + + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: '/resources/kubedbComProxySQL/spec/configSecret/name', - value: configSecretName, + path: '/form/alert/enabled', + value: configureStatus ? 'warning' : 'none', force: true, }) } -} - -function onConfigurationChange({ getValue, commit, discriminator, model }) { - const value = getValue(discriminator, '/configuration') - commit('wizard/model$update', { - path: '/resources/secret_config/stringData/md-config.cnf', - value: value, - force: true, - }) - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComProxySQL/spec/configSecret/name', - value: configSecretName, - force: true, - }) -} -function setConfigurationSource({ model, getValue }) { - const modelValue = getValue(model, '/resources/secret_config') - if (modelValue) { - return 'create-new-config' + function showCustomizeExporterSection() { + // watchDependency('discriminator#/customizeExporter') + const configureStatus = getValue(discriminator, '/customizeExporter') + return configureStatus } - return 'use-existing-config' -} - -function onConfigurationValueChange({ discriminator, getValue, commit }, path) { - const value = getValue(discriminator, `/${path}`) - commit('wizard/model$update', { - path: `/resources/secret_config/stringData/${path}.cnf`, - value, - force: true, - }) -} -function setCustomConfigConfigureChoice({ model, getValue }) { - const customConfig = getValue(model, '/resources/kubedbComProxySQL/spec/configSecret') - return customConfig ? 'yes' : 'no' -} - -function onSetCustomConfigChange({ discriminator, getValue, commit }) { - const value = getValue(discriminator, '/setCustomConfig') - - if (value === 'no') { - commit('wizard/model$delete', '/resources/kubedbComProxySQL/spec/configSecret') - commit('wizard/model$delete', '/resources/secret_config') + function onCustomizeExporterChange() { + const configureStatus = getValue(discriminator, '/customizeExporter') + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComProxySQL/spec/monitor/prometheus/exporter', + value: {}, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/kubedbComProxySQL/spec/monitor/prometheus/exporter') + } } -} - -function getOpsRequestUrl({ storeGet, model, getValue, mode }, 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 + `/create-opsrequest-${reqType.toLowerCase()}?namespace=${namespace}` - - if (mode === 'standalone-step') return pathConstructedForKubedb - else - return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/proxysqlopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations${ - reqType ? '&requestType=' + reqType : '' - }` -} - -function onMySQLRulesChange({ discriminator, getValue, commit }) { - const rules = getValue(discriminator, '/mysqlQueryRules') - const modifiedRules = rules?.map((item) => item.rules) - - commit('wizard/model$update', { - path: '/resources/kubedbComProxySQL/spec/initConfig/mysqlQueryRules', - value: modifiedRules, - force: true, - }) -} - -function setMySQLRules({ model, getValue, setDiscriminatorValue }) { - const rules = getValue(model, '/resources/kubedbComProxySQL/spec/initConfig/mysqlQueryRules') - const modifiedRules = rules?.map((item) => ({ rules: item })) - - setDiscriminatorValue('/mysqlQueryRules', modifiedRules) - - return modifiedRules -} -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + function isValueExistInModel(path) { + const modelValue = getValue(model, path) || null + return !!modelValue } -} -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} + // function onNamespaceChange() { + // const namespace = getValue(model, '/metadata/release/namespace') + // const agent = getValue(model, '/resources/kubedbComProxySQL/spec/monitor/agent') + // if (agent === 'prometheus.io') { + // commit('wizard/model$update', { + // path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + // value: [namespace], + // force: true, + // }) + // } + // } -///////////////////////// Autoscaler /////////////////// -let autoscaleType = '' -let dbDetails = {} + function onLabelChange() { + const labels = getValue(model, '/resources/kubedbComProxySQL/spec/metadata/labels') -function isConsole({ storeGet, commit }) { - const isKube = isKubedb({ storeGet }) + const agent = getValue(model, '/resources/kubedbComProxySQL/spec/monitor/agent') - if (isKube) { - const dbName = storeGet('/route/params/name') || '' - commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComProxySQLAutoscaler/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/autoscalingKubedbComProxySQLAutoscaler/metadata/name', - value: modifiedName, - force: true, - }) - const namespace = storeGet('/route/query/namespace') || '' - if (namespace) { + if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComProxySQLAutoscaler/metadata/namespace', - value: namespace, + path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', + value: labels, force: true, }) } } - return !isKube -} - -function isKubedb({ storeGet }) { - return !!storeGet('/route/params/actions') -} - -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} - -function showOpsRequestOptions({ model, getValue, watchDependency, storeGet, discriminator }) { - if (isKubedb({ storeGet }) === true) return true - watchDependency('model#/resources/autoscalingKubedbComProxySQLAutoscaler/spec/databaseRef/name') - watchDependency('discriminator#/autoscalingType') - return ( - !!getValue(model, '/resources/autoscalingKubedbComProxySQLAutoscaler/spec/databaseRef/name') && - !!getValue(discriminator, '/autoscalingType') - ) -} - -async function getNamespaces({ axios, storeGet }) { - 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({ axios, storeGet, model, getValue, watchDependency }) { - watchDependency('model#/resources/autoscalingKubedbComProxySQLAutoscaler/metadata/namespace') - const namespace = getValue( - model, - '/resources/autoscalingKubedbComProxySQLAutoscaler/metadata/namespace', - ) - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) - - const resources = (resp && resp.data && resp.data.items) || [] + function onAgentChange() { + const agent = getValue(model, '/resources/kubedbComProxySQL/spec/monitor/agent') + if (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', + value: [], + force: true, + }) - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, + onNamespaceChange() + onLabelChange() + } else { + commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') } - }) -} + } -async function getDbDetails({ commit, setDiscriminatorValue, axios, storeGet, getValue, model }) { - const owner = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - const namespace = - storeGet('/route/query/namespace') || - getValue(model, '/resources/autoscalingKubedbComProxySQLAutoscaler/metadata/namespace') || - '' - const name = - storeGet('/route/params/name') || - getValue(model, '/resources/autoscalingKubedbComProxySQLAutoscaler/spec/databaseRef/name') || - '' - - if (namespace && name) { - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/proxysqls/${name}`, + 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/proxysqlopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations${ + reqType ? '&requestType=' + reqType : '' + }` + } + + function onNamespaceChange() { + const namespace = getValue( + model, + '/resources/autoscalingKubedbComProxySQLAutoscaler/metadata/namespace', + ) + if (!namespace) { + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComProxySQLAutoscaler/spec/databaseRef/name', ) - dbDetails = resp.data || {} - setDiscriminatorValue('/dbDetails', true) - } catch (e) { - console.log(e) } } - commit('wizard/model$update', { - path: `/metadata/release/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/metadata/release/namespace`, - value: namespace, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComProxySQLAutoscaler/spec/databaseRef/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComProxySQLAutoscaler/metadata/labels`, - value: dbDetails.metadata.labels, - force: true, - }) -} - -async function dbTypeEqualsTo({ watchDependency, commit }, type) { - watchDependency('discriminator#/dbDetails') - - const { spec } = dbDetails || {} - const { topology } = spec || {} - let verd = '' - if (topology) verd = 'topology' - else { - verd = 'combined' + function setValueFrom() { + if (isConfigMapTypeValueFrom()) { + return 'configMap' + } else if (isSecretTypeValueFrom()) { + return 'secret' + } else { + return 'input' + } } - clearSpecModel({ commit }, verd) - return type === verd && spec -} -function clearSpecModel({ commit }, dbtype) { - if (dbtype === 'standalone') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComProxySQLAutoscaler/spec/${autoscaleType}/cluster`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComProxySQLAutoscaler/spec/${autoscaleType}/sentinel`, - ) - } else if (dbtype === 'cluster') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComProxySQLAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComProxySQLAutoscaler/spec/${autoscaleType}/sentinel`, - ) - } else if (dbtype === 'sentinel') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComProxySQLAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComProxySQLAutoscaler/spec/${autoscaleType}/cluster`, - ) + 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 initMetadata({ getValue, discriminator, model, commit, storeGet }) { - const dbName = - getValue(model, '/resources/autoscalingKubedbComProxySQLAutoscaler/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/autoscalingKubedbComProxySQLAutoscaler/metadata/name', - value: modifiedName, - force: true, - }) + // function isEqualToValueFromType(value) { + // //watchDependency('discriminator#/valueFromType') + // const valueFrom = getValue(discriminator, '/valueFromType') + // return valueFrom === value + // } - // delete the other type object from model - if (type === 'compute') - commit('wizard/model$delete', '/resources/autoscalingKubedbComProxySQLAutoscaler/spec/storage') - if (type === 'storage') - commit('wizard/model$delete', '/resources/autoscalingKubedbComProxySQLAutoscaler/spec/compute') -} + async function resourceNames(group, version, resource) { + const namespace = getValue(model, '/metadata/release/namespace') + // watchDependency('model#/metadata/release/namespace') -function onNamespaceChange({ model, getValue, commit }) { - const namespace = getValue( - model, - '/resources/autoscalingKubedbComProxySQLAutoscaler/metadata/namespace', - ) - if (!namespace) { - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComProxySQLAutoscaler/spec/databaseRef/name', - ) - } -} + let resources = await getNamespacedResourceList(axios, storeGet, { + namespace, + group, + version, + resource, + }) -function ifScalingTypeEqualsTo( - { storeGet, watchDependency, getValue, discriminator, model }, - type, -) { - watchDependency('discriminator#/autoscalingType') - watchDependency('model#/resources/autoscalingKubedbComProxySQLAutoscaler/spec/databaseRef/name') - - const operation = storeGet('/route/params/actions') || '' - if (operation.length) { - const splitOp = operation.split('-') - if (splitOp.length > 2) autoscaleType = splitOp[2] - } else autoscaleType = getValue(discriminator, '/autoscalingType') || '' - const isDatabaseSelected = !!getValue( - model, - '/resources/autoscalingKubedbComProxySQLAutoscaler/spec/databaseRef/name', - ) - return autoscaleType === type && isDatabaseSelected -} + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } -async function fetchNodeTopology({ axios, storeGet }) { - 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 resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } }) - return mappedList - } catch (e) { - console.log(e) } - return [] -} -function isNodeTopologySelected({ watchDependency, model, getValue }) { - watchDependency( - 'model#/resources/autoscalingKubedbComProxySQLAutoscaler/spec/compute/nodeTopology/name', - ) - const nodeTopologyName = - getValue( + 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/autoscalingKubedbComProxySQLAutoscaler/spec/compute/nodeTopology/name', - ) || '' - return !!nodeTopologyName.length -} + `/resources/kubedbComProxySQL/spec/monitor/prometheus/exporter/env/${index}/valueFrom/configMapKeyRef/name`, + ) -function setControlledResources({ commit }, type) { - const list = ['cpu', 'memory'] - const path = `/resources/autoscalingKubedbComProxySQLAutoscaler/spec/compute/${type}/controlledResources` - commit('wizard/model$update', { - path: path, - value: list, - force: true, - }) - return list -} + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/configMapKeyRef/name') -function setTrigger({ model, getValue }, path) { - let value = getValue(model, `/resources/${path}`) - if (value) return value - return 'On' -} + if (!configMapName) return [] -function setApplyToIfReady() { - return 'IfReady' -} + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/configmaps/${configMapName}`, + ) -function handleUnit({ commit, model, getValue }, 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, - }) + 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 fetchTopologyMachines({ axios, getValue, storeGet, model, setDiscriminatorValue }) { - const instance = hasAnnotations({ model, getValue }) + 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') - 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 resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }, + ) - const nodeGroups = resp.data?.spec?.nodeGroups || [] - setDiscriminatorValue('/topologyMachines', nodeGroups) - return nodeGroups + 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 [] } } -} -function setAllowedMachine({ model, getValue }, minmax) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComProxySQLAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - const mx = instance?.includes(',') ? instance.split(',')[1] : '' - const mn = instance?.includes(',') ? instance.split(',')[0] : '' - - if (minmax === 'min') return mn - else return mx -} - -async function getMachines({ getValue, watchDependency, discriminator }, minmax) { - watchDependency('discriminator#/topologyMachines') - watchDependency('discriminator#/topologyMachines') - const depends = minmax === 'min' ? 'max' : 'min' - const dependantPath = `/allowedMachine-${depends}` - - watchDependency(`discriminator#${dependantPath}`) - const dependantMachine = getValue(discriminator, dependantPath) + 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/kubedbComProxySQL/spec/monitor/prometheus/exporter/env/${index}/valueFrom/secretKeyRef/name`, + ) - const nodeGroups = getValue(discriminator, '/topologyMachines') || [] - console.log(nodeGroups) + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/secretKeyRef/name') - const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) + if (!secretName) return [] - const machines = nodeGroups?.map((item) => { - const subText = `CPU: ${item.allocatable.cpu}, Memory: ${item.allocatable.memory}` - const text = item.topologyValue - return { text, subText, value: item.topologyValue } - }) + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets/${secretName}`, + ) - const filteredMachine = machines?.filter((item, ind) => - minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, - ) + const secret = (resp && resp.data && resp.data.data) || {} - return dependantIndex === -1 ? machines : filteredMachine -} + const secretKeys = Object.keys(secret).map((item) => ({ + text: item, + value: item, + })) -function hasAnnotations({ model, getValue }) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComProxySQLAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] + return secretKeys + } catch (e) { + console.log(e) + return [] + } + } - return !!instance -} + function returnFalse() { + return false + } + + 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 + }) -function hasNoAnnotations({ model, getValue }) { - return !hasAnnotations({ model, getValue }) -} + if (filteredEnv.length) + commit('wizard/model$update', { + path: '/resources/kubedbComProxySQL/spec/monitor/prometheus/exporter/env', + value: filteredEnv, + force: true, + }) + } -function onMachineChange({ model, getValue, discriminator, commit }, type) { - const annoPath = '/resources/autoscalingKubedbComProxySQLAutoscaler/metadata/annotations' - const annotations = getValue(model, annoPath) - const instance = annotations['kubernetes.io/instance-type'] + function initEnvArray() { + const env = getValue(model, '/resources/kubedbComProxySQL/spec/monitor/prometheus/exporter/env') - const minMachine = getValue(discriminator, '/allowedMachine-min') - const maxMachine = getValue(discriminator, '/allowedMachine-max') - const minMaxMachine = `${minMachine},${maxMachine}` - annotations['kubernetes.io/instance-type'] = minMaxMachine + return env || [] + } - const machines = getValue(discriminator, `/topologyMachines`) || [] - const minMachineObj = machines.find((item) => item.topologyValue === minMachine) - const maxMachineObj = machines.find((item) => item.topologyValue === maxMachine) - const minMachineAllocatable = minMachineObj?.allocatable - const maxMachineAllocatable = maxMachineObj?.allocatable - const allowedPath = `/resources/autoscalingKubedbComProxySQLAutoscaler/spec/compute/${type}` + function isEqualToTemp(value, index) { + //watchDependency('discriminator#/valueFromType') + const valueFrom = getValue(discriminator, `/env/${index}/temp/valueFromType`) + return valueFrom === value + } - 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 initMonitoring() { + const env = + getValue(model, '/resources/kubedbComProxySQL/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 { - isRancherManaged, - handleUnit, - isConsole, - getNamespaces, - getDbs, - isKubedb, - getDbDetails, - dbTypeEqualsTo, - clearSpecModel, - initMetadata, - onNamespaceChange, - ifScalingTypeEqualsTo, - fetchNodeTopology, - isNodeTopologySelected, - setControlledResources, - setTrigger, - setApplyToIfReady, - showOpsRequestOptions, - isVariantAvailable, - fetchJsons, - disableLableChecker, - isEqualToModelPathValue, - getResources, - isEqualToDiscriminatorPath, - setValueFromModel, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - returnTrue, - returnStringYes, - getProxySQLVersions, - getAppBindings, - setApiGroup, - getIssuerRefsName, - hasIssuerRefName, - hasNoIssuerRefName, - showTlsConfigureSection, - onTlsConfigureChange, - getAliasOptions, - showMonitoringSection, - onEnableMonitoringChange, - showCustomizeExporterSection, - onCustomizeExporterChange, - isValueExistInModel, - onNamespaceChange, - onLabelChange, - onNameChange, - returnFalse, - onAgentChange, - getCreateAuthSecret, - showExistingSecretSection, - showPasswordSection, - setAuthSecretPassword, - onAuthSecretPasswordChange, - disableInitializationSection, - encodePassword, - decodePassword, - onCreateAuthSecretChange, - getSecrets, - onConfigurationSourceChange, - onConfigurationChange, - setConfigurationSource, - onConfigurationValueChange, - onSetCustomConfigChange, - setCustomConfigConfigureChoice, - getOpsRequestUrl, - onMySQLRulesChange, - setMySQLRules, - getCreateNameSpaceUrl, - getMachines, - setAllowedMachine, - hasAnnotations, - hasNoAnnotations, - fetchTopologyMachines, - onMachineChange, + return { + isConsole, + isKubedb, + isRancherManaged, + showOpsRequestOptions, + getNamespaces, + getDbs, + getDbDetails, + initMetadata, + onNamespaceChange, + fetchNodeTopology, + isNodeTopologySelected, + setControlledResources, + setTrigger, + setApplyToIfReady, + fetchTopologyMachines, + setAllowedMachine, + getMachines, + hasAnnotations, + hasNoAnnotations, + onMachineChange, + + getOpsRequestUrl, + isValueExistInModel, + onEnableMonitoringChange, + showMonitoringSection, + onAgentChange, + getResources, + isEqualToModelPathValue, + onCustomizeExporterChange, + showCustomizeExporterSection, + onLabelChange, + setValueFrom, + onValueFromChange, + resourceNames, + getConfigMapKeys, + getSecrets, + getSecretKeys, + isConfigMapTypeValueFrom, + isSecretTypeValueFrom, + getNamespacedResourceList, + returnFalse, + onEnvArrayChange, + initEnvArray, + isEqualToTemp, + initMonitoring, + } } diff --git a/charts/kubedbcom-rabbitmq-editor-options/ui/create-ui.yaml b/charts/kubedbcom-rabbitmq-editor-options/ui/create-ui.yaml index d577e7c96b..ea1a59616b 100644 --- a/charts/kubedbcom-rabbitmq-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-rabbitmq-editor-options/ui/create-ui.yaml @@ -1,309 +1,309 @@ -steps: -- form: - discriminator: - bundleApiLoaded: - default: false - type: boolean +step: +- type: single-step-form + loader: initBundle + elements: + - type: label-element + label: '' + subtitle: Select the RabbitMQ version you want to deploy on Kubernetes. The chosen version determines the RabbitMQ engine features, compatibility, and runtime behavior of your database cluster. + - disableUnselect: true + loader: getAdminOptions|databases/RabbitMQ/versions + if: + type: function + name: isToggleOn|databases/RabbitMQ/versions + label: Database Version + schema: schema/properties/spec/properties/admin/properties/databases/properties/RabbitMQ/properties/versions/properties/default + type: select + - init: + type: func + value: getDefault|databases/RabbitMQ/mode + loader: getAdminOptions|databases/RabbitMQ/mode + isHorizontal: true + if: + type: function + name: isToggleOn|databases/RabbitMQ/mode + label: Database Mode + watcher: + func: onModeChange + paths: + - schema/properties/spec/properties/mode + schema: schema/properties/spec/properties/mode + type: radio + - if: + type: function + name: showReplicaField + label: Replica number + schema: schema/properties/spec/properties/replicas + type: input + - elements: + - type: label-element + label: '' + subtitle: Select a machine profile to allocate CPU and memory resources for your database. Choose 'custom' to manually specify resource requirements or select a predefined profile. + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: CPU + loader: setLimits|cpu + watcher: + func: setRequests|cpu + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: Memory + loader: setLimits|memory + watcher: + func: setRequests|memory + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + label: Machine Profile + showLabels: true + type: block-layout + - elements: + - type: horizontal-layout + showLabels: true + elements: + - loader: getAdminOptions|storageClasses + if: + type: function + name: isToggleOn|storageClasses + label: Storage Class + schema: schema/properties/spec/properties/admin/properties/storageClasses/properties/default + type: select + - label: Storage Size + schema: schema/properties/spec/properties/persistence/properties/size + type: input + type: block-layout + - description: Configure Credentials, Deployment Mode etc. elements: - - computed: initBundle - if: returnFalse - type: label-element - - disableUnselect: true - fetch: getAdminOptions|databases/RabbitMQ/versions - if: isToggleOn|databases/RabbitMQ/versions - label: - text: labels.database.version - schema: - $ref: schema#/properties/spec/properties/admin/properties/databases/properties/RabbitMQ/properties/versions/properties/default - type: select - - computed: getDefault|databases/RabbitMQ/mode - fetch: getAdminOptions|databases/RabbitMQ/mode - hasDescription: true - if: isToggleOn|databases/RabbitMQ/mode - label: - text: labels.database.mode - onChange: onModeChange - schema: - $ref: schema#/properties/spec/properties/mode - type: radio - - elements: - - if: showReplicaField - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/replicas - type: input - type: single-step-form - elements: - - computed: setMachineToCustom - customClass: mt-10 - fetch: getMachineListForOptions - label: - text: labels.machine - schema: - $ref: schema#/properties/spec/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.cpu - onChange: setRequests|cpu - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.memory - onChange: setRequests|memory - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - label: - text: labels.machine_profile - show_label: true - type: single-step-form - - fetch: getAdminOptions|storageClasses - if: isToggleOn|storageClasses - label: - text: labels.storage.class - schema: - $ref: schema#/properties/spec/properties/admin/properties/storageClasses/properties/default + - type: label-element + label: '' + subtitle: Add custom labels and annotations to your database resources for organization, monitoring, and integration with other Kubernetes tools and services. + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/annotations + label: Labels & Annotations + showLabels: true + hideBlock: true + type: block-layout + - init: + type: func + value: getDefault|deletionPolicy + customClass: mt-20 + if: + type: function + name: isToggleOn|deletionPolicy + label: Deletion Policy + watcher: + func: setStorageClass + paths: + - schema/properties/spec/properties/deletionPolicy + options: + - description: options.deletionPolicy.delete.description + text: Delete ( Keep only database Secrets and backed up data ) + value: Delete + - description: options.deletionPolicy.halt.description + text: Halt ( Keep PVCs, database Secrets and backed up data ) + value: Halt + - description: options.deletionPolicy.wipeOut.description + text: WipeOut ( Delete everything including backed up data ) + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: DoNotTerminate ( Prevent deletion of the RabbitMQ CRD ) + value: DoNotTerminate + schema: schema/properties/spec/properties/deletionPolicy + type: select + - if: + type: function + name: getDefaultValue|spec/admin/authCredential/customize + label: Provide Authentication Credentials? + watcher: + func: onAuthChange + paths: + - temp/createAuthSecret + schema: temp/createAuthSecret + type: switch + - if: + type: function + name: showReferSecretSwitch + label: Refer existing Secret? + watcher: + func: onReferSecretChange + paths: + - temp/referSecret + schema: temp/referSecret + type: switch + - loader: getReferSecrets + if: + type: function + name: showSecretDropdown + label: Secret + schema: schema/properties/spec/properties/authSecret/properties/name type: select - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/persistence/properties/size + - if: + type: function + name: showReferSecret + label: Password (leave it blank to auto generate password) + schema: schema/properties/spec/properties/authSecret/properties/password type: input - - accordion: true - description: - text: Configure Credentials, Deployment Mode etc. - discriminator: - configDatabase: - default: false - type: boolean - createAuthSecret: - default: false - type: boolean - referSecret: - default: false - type: boolean - elements: - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties - type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties - type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - computed: getDefault|deletionPolicy - customClass: mt-20 - if: isToggleOn|deletionPolicy - label: - text: labels.deletionPolicy - onChange: setStorageClass + - if: + type: function + name: getDefaultValue|spec/admin/customConfiguration + label: Configure Database? + watcher: + func: clearConfiguration + paths: + - temp/configDatabase + schema: temp/configDatabase + type: switch + - if: + type: function + name: isConfigDatabaseOn + label: Configuration + schema: schema/properties/spec/properties/configuration + type: textarea + - if: + type: function + name: isToggleOn|deployment + label: Deployment Mode + options: + - description: Postgres sharded cluster for high performance and high availability. + text: Shared + value: Shared + - description: For production applications with sophisticated workload requirements. + text: Dedicated + value: Dedicated + schema: schema/properties/spec/properties/admin/properties/deployment/properties/default + type: radio + - if: + type: function + name: isToggleOn|clusterTier + isHorizontal: true + label: Cluster Tier + options: + - text: General Purpose + value: GeneralPurpose + - text: Memory Optimized + value: MemoryOptimized + - text: CPU Optimized + value: CPUOptimized + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/default + type: radio + - disableUnselect: true + loader: getAdminOptions|clusterTier/placement + if: + type: function + name: isToggleOn|clusterTier/placement + label: Placement Policy + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + type: select + - disableUnselect: true + loader: getNodeTopology + if: + type: function + name: isToggleOn|clusterTier/nodeTopology + label: Node Topology + refresh: true + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + type: select + label: Advanced Configuration + showLabels: true + hideBlock: true + type: block-layout + - description: Enable Backup, Monitoring, TLS etc. + elements: + - elements: + - init: + type: func + value: setMonitoring + label: Enable Monitoring + watcher: + func: updateAlertValue + paths: + - temp/monitoring + schema: temp/monitoring + type: switch + - customClass: mt-10 + if: + type: function + name: showAlerts + label: Alert Options 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/spec/properties/deletionPolicy + - text: None + value: none + - text: Critical + value: critical + - text: Warning + value: warning + - text: Info + value: info + schema: schema/properties/form/properties/alert/properties/enabled type: select - - if: getDefaultValue|spec/admin/authCredential/customize - label: - text: Provide Authentication Credentials? - onChange: onAuthChange - schema: - $ref: discriminator#/createAuthSecret - type: switch - - if: showReferSecretSwitch - label: - text: Refer existing Secret? - onChange: onReferSecretChange - schema: - $ref: discriminator#/referSecret + if: + type: function + name: isToggleOn|monitoring + type: block-layout + - elements: + - label: Enable TLS? + schema: schema/properties/spec/properties/admin/properties/tls/properties/default type: switch - - fetch: getReferSecrets - if: showSecretDropdown - label: - text: Secret - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/name + - loader: getAdminOptions|clusterIssuers + if: + type: function + name: showIssuer + label: Cluster Issuers + validation: + type: required + schema: schema/properties/spec/properties/admin/properties/clusterIssuers/properties/default type: select - - if: showReferSecret - label: - text: labels.password - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/password - type: input - - computed: isConfigAvailable - if: getDefaultValue|spec/admin/customConfiguration - label: - text: Configure Database? - onChange: clearConfiguration - schema: - $ref: discriminator#/configDatabase + if: + type: function + name: isToggleOn|tls + type: block-layout + - elements: + - label: Expose via Gateway? + schema: schema/properties/spec/properties/admin/properties/expose/properties/default type: switch - - if: isConfigDatabaseOn - label: - text: Configuration - schema: - $ref: schema#/properties/spec/properties/configuration - type: editor - - hasDescription: true - if: isToggleOn|deployment - label: - text: labels.deployment.name - options: - - description: labels.deployment.shared - text: Shared - value: Shared - - description: labels.deployment.dedicated - text: Dedicated - value: Dedicated - schema: - $ref: schema#/properties/spec/properties/admin/properties/deployment/properties/default - type: radio - - if: isToggleOn|clusterTier - isHorizontal: true - label: - text: labels.clusterTier - options: - - text: General Purpose - value: GeneralPurpose - - text: Memory Optimized - value: MemoryOptimized - - text: CPU Optimized - value: CPUOptimized - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/default - type: radio - - disableUnselect: true - fetch: getAdminOptions|clusterTier/placement - if: isToggleOn|clusterTier/placement - label: - text: labels.placement - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default - type: select - - disableUnselect: true - fetch: getNodeTopology - if: isToggleOn|clusterTier/nodeTopology - label: - text: labels.nodeTopology - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default - type: select - hideForm: true - label: - text: Advanced Configuration - show_label: true - type: single-step-form - - accordion: true - description: - text: Enable Backup, Monitoring, TLS etc. - elements: - - discriminator: - monitoring: - default: false - type: boolean - elements: - - computed: setMonitoring - label: - text: labels.enable_monitoring - onChange: updateAlertValue - schema: - $ref: discriminator#/monitoring - type: switch - - customClass: mt-10 - if: showAlerts - label: - text: labels.alert.options - options: - - text: None - value: none - - text: Critical - value: critical - - text: Warning - value: warning - - text: Info - value: info - schema: - $ref: schema#/properties/form/properties/alert/properties/enabled - sortable: true - type: select - if: isToggleOn|monitoring - type: single-step-form - - elements: - - label: - text: Enable TLS? - schema: - $ref: schema#/properties/spec/properties/admin/properties/tls/properties/default - type: switch - - fetch: getAdminOptions|clusterIssuers - if: showIssuer - label: - text: labels.clusterIssuers - required: true - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterIssuers/properties/default - type: select - if: isToggleOn|tls - type: single-step-form - - elements: - - label: - text: Expose via Gateway? - schema: - $ref: schema#/properties/spec/properties/admin/properties/expose/properties/default - type: switch - if: isToggleOn|expose - type: single-step-form - if: showAdditionalSettings - label: - text: Additional Options - show_label: true - type: single-step-form - type: single-step-form + if: + type: function + name: isToggleOn|expose + type: block-layout + if: + type: function + name: showAdditionalSettings + label: Additional Options + showLabels: true + type: block-layout id: options - title: steps.0.label + # title: steps.0.label type: multi-step-form diff --git a/charts/kubedbcom-rabbitmq-editor-options/ui/functions.js b/charts/kubedbcom-rabbitmq-editor-options/ui/functions.js index c6d69af1aa..bd26d4184f 100644 --- a/charts/kubedbcom-rabbitmq-editor-options/ui/functions.js +++ b/charts/kubedbcom-rabbitmq-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -315,1055 +317,1092 @@ const modeDetails = { }, } -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} - -function showAuthSecretField({ discriminator, getValue, watchDependency }) { - return !showAuthPasswordField({ - discriminator, - getValue, - watchDependency, - }) -} +let placement = [] +let versions = [] +let storageClass = [] +let clusterIssuers = [] +let nodetopologiesShared = [] +let nodetopologiesDedicated = [] +let features = [] -function showStorageSizeField({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - const validType = ['Standalone', 'Cluster'] - return validType.includes(modelPathValue) -} +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) -function showReplicaField({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - const validType = ['Replicaset'] - return validType.includes(modelPathValue) -} + setDiscriminatorValue('bundleApiLoaded', false) + setDiscriminatorValue('configDatabase', false) + setDiscriminatorValue('createAuthSecret', false) + setDiscriminatorValue('referSecret', false) + setDiscriminatorValue('monitoring', false) -function onModeChange({ model, getValue, watchDependency, commit }) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - if (modelPathValue === 'Replicaset') { - commit('wizard/model$update', { - path: '/spec/replicas', - value: 3, - force: true, - }) - } else { - commit('wizard/model$update', { - path: '/spec/replicas', - value: 1, - force: true, - }) + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value } -} -async function getResources({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function showAuthSecretField() { + return !showAuthPasswordField() + } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + function showStorageSizeField() { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + const validType = ['Standalone', 'Cluster'] + return validType.includes(modelPathValue) + } - const resources = (resp && resp.data && resp.data.items) || [] + function showReplicaField() { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + const validType = ['Replicaset'] + return validType.includes(modelPathValue) + } - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return resources -} + function onModeChange() { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + if (modelPathValue === 'Replicaset') { + commit('wizard/model$update', { + path: '/spec/replicas', + value: 3, + force: true, + }) + } else { + commit('wizard/model$update', { + path: '/spec/replicas', + value: 1, + force: true, + }) + } + } -async function getMongoDbVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, + 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 } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) + async function getMongoDbVersions(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + + const queryParams = { + filter: { + items: { + metadata: { name: null }, + spec: { version: null, deprecated: null }, + }, + }, + } - const resources = (resp && resp.data && resp.data.items) || [] + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: queryParams, + }, + ) - // keep only non deprecated versions - const filteredMongoDbVersions = resources.filter((item) => item.spec && !item.spec.deprecated) + const resources = (resp && resp.data && resp.data.items) || [] - filteredMongoDbVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredMongoDbVersions -} + // keep only non deprecated versions + const filteredMongoDbVersions = resources.filter((item) => item.spec && !item.spec.deprecated) -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/spec/authSecret/name') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/spec/authSecret/password') + filteredMongoDbVersions.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + const specVersion = (item.spec && item.spec.version) || '' + item.text = `${name} (${specVersion})` + item.value = name + return true + }) + return filteredMongoDbVersions } -} -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, + function onCreateAuthSecretChange() { + const createAuthSecret = getValue(discriminator, '/createAuthSecret') + if (createAuthSecret) { + commit('wizard/model$delete', '/spec/authSecret/name') + } else if (createAuthSecret === false) { + commit('wizard/model$delete', '/spec/authSecret/password') + } + } + + 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') + + 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 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) - }) + 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 -} + filteredSecrets.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true + }) + return filteredSecrets + } -function getMachineListForOptions({ model, getValue }) { - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') let array = [] + function getMachineListForOptions() { + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') - if (available.length) { - array = available.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - else { - let subText = '', - text = '' - const machineData = machinesFromPreset.find((val) => val.id === machine) - if (machineData) { - subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` - text = machineData.name ? machineData.name : machineData.id - } - return { text, subText, value: machine } - } - }) - } else { - array = machineList - .map((machine) => { + if (available.length) { + array = available.map((machine) => { if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + else { + let subText = '', + text = '' + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + text = machineData.name ? machineData.name : machineData.id + } + return { text, subText, value: machine } + } }) - .filter((val) => !!val) + } else { + array = machineList + .map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { text, subText, value: machine } + }) + .filter((val) => !!val) + } + return array } - return array -} -function setLimits({ model, getValue, commit, watchDependency }, resource, type) { - const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' - watchDependency(`model#${path}`) - const selectedMachine = getValue(model, path) || 'custom' - const reqCommitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - const comparePath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - - const resourceValue = getValue(model, comparePath) - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - - let cpu = '', - memory = '' - if (available.length && selectedMachine !== 'custom') { - const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) - if (machineData) { - cpu = machineData.limits.cpu - memory = machineData.limits.memory + function setLimits(resource, type) { + const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' + // watchDependency(`model#${path}`) + const selectedMachine = getValue(model, path) || 'custom' + const reqCommitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + const comparePath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + + const resourceValue = getValue(model, comparePath) + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + let cpu = '', + memory = '' + if (available.length && selectedMachine !== 'custom') { + const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) + if (machineData) { + cpu = machineData.limits.cpu + memory = machineData.limits.memory + } + } else { + if (selectedMachine === 'custom') { + cpu = resourceValue + memory = resourceValue + } else { + cpu = machines[selectedMachine].resources.limits.cpu + memory = machines[selectedMachine].resources.limits.memory + } } - } else { - if (selectedMachine === 'custom') { - cpu = resourceValue - memory = resourceValue + + if (resource === 'memory') { + commit('wizard/model$update', { + path: reqCommitPath, + value: memory, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: memory, + force: true, + }) + return memory } else { - cpu = machines[selectedMachine].resources.limits.cpu - memory = machines[selectedMachine].resources.limits.memory + commit('wizard/model$update', { + path: reqCommitPath, + value: cpu, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: cpu, + force: true, + }) + return cpu } } - if (resource === 'memory') { + function setRequests(resource, type) { + const modelPath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + + const fullpath = `/spec/podResources/machine` + const modelPathValue = getValue(model, fullpath) + commit('wizard/model$update', { - path: reqCommitPath, - value: memory, + path: commitPath, + value: val, force: true, }) - commit('wizard/model$update', { - path: comparePath, - value: memory, - force: true, + + if (modelPathValue === 'custom') { + return + } + let commitCpuMemory, ModelPathValue + if (resource && type) { + const fullPath = `/spec/${type}/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/${type}/podResources/resources/requests/${resource}` + } else { + const fullPath = `/spec/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/podResources/resources/requests/${resource}` + } + let cpuMemoryValue + array.forEach((item) => { + if (item.value === ModelPathValue) { + // Parse subText like "CPU: 2, Memory: 2Gi" + const subText = item.subText || '' + if (resource === 'cpu') { + // Extract CPU value + const cpuMatch = subText.match(/CPU:\s*([^,]+)/) + cpuMemoryValue = cpuMatch ? cpuMatch[1].trim() : '' + } else if (resource === 'memory') { + // Extract Memory value + const memoryMatch = subText.match(/Memory:\s*(.+)/) + cpuMemoryValue = memoryMatch ? memoryMatch[1].trim() : '' + } + } }) - return memory - } else { commit('wizard/model$update', { - path: reqCommitPath, - value: cpu, + path: commitCpuMemory, + value: cpuMemoryValue, force: true, }) + return cpuMemoryValue + } + + function setRequests(resource) { + const modelPath = `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + commitPath = `/spec/podResources/resources/limits/${resource}` commit('wizard/model$update', { - path: comparePath, - value: cpu, + path: commitPath, + value: val, force: true, }) - return cpu } -} -function setRequests({ getValue, model, commit }, resource) { - const modelPath = `/spec/podResources/resources/requests/${resource}` - const val = getValue(model, modelPath) - commitPath = `/spec/podResources/resources/limits/${resource}` - commit('wizard/model$update', { - path: commitPath, - value: val, - force: true, - }) -} + function setMachineToCustom() { + const machine = getValue(model, '/spec/admin/machineProfiles/default') + return machine || 'custom' + } -function setMachineToCustom({ getValue, model }) { - const machine = getValue(model, '/spec/admin/machineProfiles/default') - return machine || 'custom' -} + async function fetchJsons(itemCtx) { + let ui = {} + let language = {} + let functions = {} + const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart -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) + } - 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, + } } - return { - ui: ui.data || {}, - language: language.data || {}, - functions, - } -} + function updateAgentValue(val) { + commit('wizard/model$update', { + path: '/spec/monitoring/agent', + value: val ? 'prometheus.io/operator' : '', + force: true, + }) -function updateAgentValue({ commit }, val) { - commit('wizard/model$update', { - path: '/spec/monitoring/agent', - value: val ? 'prometheus.io/operator' : '', - force: true, - }) - - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: val ? 'warning' : 'none', - force: true, - }) -} + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: val ? 'warning' : 'none', + force: true, + }) + } -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function getCreateNameSpaceUrl() { + 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + const domain = storeGet('/domain') || '' + if (domain.includes('bb.test')) { + return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } } -} - -const ifCapiProviderIsNotEmpty = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/provider') - const val = getValue(model, '/form/capi/provider') - if (val) return true -} -const showMultiselectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') + const ifCapiProviderIsNotEmpty = () => { + // watchDependency('model#/form/capi/provider') + const val = getValue(model, '/form/capi/provider') + if (val) return true + } - if (val === 'capz' && ifDedicated({ model, getValue })) return true -} + const showMultiselectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') -const showSelectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') - if (val !== 'capz' && ifDedicated({ model, getValue })) return true -} + if (val === 'capz' && ifDedicated()) return true + } -const ifDedicated = ({ model, getValue }) => { - const val = getValue(model, 'form/capi/dedicated') - if (val) return true -} + const showSelectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') + if (val !== 'capz' && ifDedicated()) return true + } -const dedicatedOnChange = ({ model, getValue, commit }) => { - const val = getValue(model, 'form/capi/dedicated') - if (!val) { - commit('wizard/model$delete', 'form/capi/zones') - commit('wizard/model$delete', 'form/capi/sku') + const ifDedicated = () => { + const val = getValue(model, 'form/capi/dedicated') + if (val) return true } -} -const ifZones = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/zones') - watchDependency('model#/form/capi/dedicated') - const zones = getValue(model, 'form/capi/zones') || [] - const isDedicated = getValue(model, 'form/capi/dedicated') - if (zones.length && isDedicated) return true -} + const dedicatedOnChange = () => { + const val = getValue(model, 'form/capi/dedicated') + if (!val) { + commit('wizard/model$delete', 'form/capi/zones') + commit('wizard/model$delete', 'form/capi/sku') + } + } -const zonesOnChange = ({ model, getValue, commit }) => { - const zones = getValue(model, 'form/capi/zones') || [] - if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') -} + const ifZones = () => { + // watchDependency('model#/form/capi/zones') + // watchDependency('model#/form/capi/dedicated') + const zones = getValue(model, 'form/capi/zones') || [] + const isDedicated = getValue(model, 'form/capi/dedicated') + if (zones.length && isDedicated) return true + } -async function getZones({ storeGet, axios, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const isDedicated = getValue(model, 'form/capi/dedicated') - if (isDedicated) { - try { - const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) - const val = resp.data.map((item) => { - return { value: item, text: item } - }) - return val - } catch (e) { - console.log(e) - return [] - } + const zonesOnChange = () => { + const zones = getValue(model, 'form/capi/zones') || [] + if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') } -} -async function getSKU({ storeGet, axios, model, getValue, watchDependency }) { - watchDependency('model#/form/capi/zones') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const zones = getValue(model, 'form/capi/zones') || [] - if (zones.length) { - try { - let url = `clustersv2/${owner}/${cluster}/vms?` - if (typeof zones === 'string') { - url += `zones=${encodeURIComponent(zones)}` - } else { - zones.forEach((item) => { - url += `zones=${encodeURIComponent(item)}&` + async function getZones() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const isDedicated = getValue(model, 'form/capi/dedicated') + if (isDedicated) { + try { + const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) + const val = resp.data.map((item) => { + return { value: item, text: item } }) - url = url.slice(0, -1) + return val + } catch (e) { + console.log(e) + return [] } - const resp = await axios.get(url) - const val = resp.data.map((item) => { - return { - value: item.name, - text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, - } - }) - return val - } catch (e) { - console.log(e) - return [] } } -} - -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} -function setStorageClass({ model, getValue, commit, watchDependency, discriminator }) { - const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' - let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' - const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] - const suffix = '-retain' - - const simpleClassList = storageClassList.filter((item) => { - return !item.endsWith(suffix) - }) - const retainClassList = storageClassList.filter((item) => { - return item.endsWith(suffix) - }) - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] - } else { - storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + async function getSKU() { + // watchDependency('model#/form/capi/zones') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const zones = getValue(model, 'form/capi/zones') || [] + if (zones.length) { + try { + let url = `clustersv2/${owner}/${cluster}/vms?` + if (typeof zones === 'string') { + url += `zones=${encodeURIComponent(zones)}` + } else { + zones.forEach((item) => { + url += `zones=${encodeURIComponent(item)}&` + }) + url = url.slice(0, -1) + } + const resp = await axios.get(url) + const val = resp.data.map((item) => { + return { + value: item.name, + text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, + } + }) + return val + } catch (e) { + console.log(e) + return [] + } + } } - const isChangeable = isToggleOn( - { getValue, model, watchDependency, discriminator }, - 'storageClasses', - ) - if (isChangeable && storageClass) { - commit('wizard/model$update', { - path: '/spec/admin/storageClasses/default', - value: storageClass, - force: true, - }) + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false } -} - -function showAlerts({ watchDependency, model, getValue, discriminator }) { - watchDependency('discriminator#/monitoring') - const isMonitorEnabled = getValue(discriminator, '/monitoring') - return ( - isMonitorEnabled && isToggleOn({ getValue, model, watchDependency, discriminator }, 'alert') - ) -} -function onBackupSwitch({ discriminator, getValue, commit }) { - const isBackupOn = getValue(discriminator, '/backup') - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: isBackupOn ? 'KubeStash' : '', - force: true, - }) -} + function setStorageClass() { + const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' + let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' + const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] + const suffix = '-retain' -function clearArbiterHidden({ commit }) { - commit('wizard/model$update', { - path: `/spec/arbiter/enabled`, - value: false, - force: true, - }) - - commit('wizard/model$update', { - path: `/spec/hidden/enabled`, - value: false, - force: true, - }) -} + const simpleClassList = storageClassList.filter((item) => { + return !item.endsWith(suffix) + }) + const retainClassList = storageClassList.filter((item) => { + return item.endsWith(suffix) + }) + if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { + storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] + } else { + storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + } -let placement = [] -let versions = [] -let storageClass = [] -let clusterIssuers = [] -let nodetopologiesShared = [] -let nodetopologiesDedicated = [] -let features = [] -async function initBundle({ commit, model, getValue, axios, storeGet, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - - let db = getValue(model, '/metadata/resource/kind') - db = db.toLowerCase() - let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` - const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - - try { - const resp = await axios.get(url) - features = resp.data.features || [] - placement = resp.data.placementpolicies || [] - versions = resp.data.versions || [] - storageClass = resp.data.storageclasses || [] - clusterIssuers = resp.data.clusterissuers || [] - nodetopologiesDedicated = resp.data.dedicated || [] - nodetopologiesShared = resp.data.shared || [] - - const response = await axios.get(annotationUrl) - const annotations = response.data?.metadata?.annotations || {} - const uidRange = annotations['openshift.io/sa.scc.uid-range'] - if (uidRange) { - const val = uidRange.split('/')[0] + const isChangeable = isToggleOn('storageClasses') + if (isChangeable && storageClass) { commit('wizard/model$update', { - path: '/spec/openshift/securityContext/runAsUser', - value: val, + path: '/spec/admin/storageClasses/default', + value: storageClass, force: true, }) } - } catch (e) { - console.log(e) } - commit('wizard/model$update', { - path: '/spec/deletionPolicy', - value: getDefault({ getValue, model }, 'deletionPolicy'), - force: true, - }) - - if (!getValue(model, `/spec/admin/databases/RabbitMQ/mode/toggle`)) { - let defMode = getDefault({ getValue, model }, 'databases/RabbitMQ/mode') || '' - if (defMode === '') { - const arr = getValue(model, '/spec/databases/RabbitMQ/mode/available') || [] - if (arr.length) defMode = arr[0] - } - commit('wizard/model$update', { - path: '/spec/mode', - value: defMode, - force: true, - }) + function showAlerts() { + // watchDependency('discriminator#/monitoring') + const isMonitorEnabled = getValue(discriminator, '/monitoring') + return isMonitorEnabled && isToggleOn('alert') } - if (!features.includes('tls')) { + function onBackupSwitch() { + const isBackupOn = getValue(discriminator, '/backup') commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: false, + path: '/spec/backup/tool', + value: isBackupOn ? 'KubeStash' : '', force: true, }) } - if (!features.includes('binding')) { + + function clearArbiterHidden() { commit('wizard/model$update', { - path: '/spec/admin/expose/default', + path: `/spec/arbiter/enabled`, value: false, force: true, }) - } - if (!features.includes('monitoring')) { - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: 'none', - force: true, - }) - } - if (!features.includes('backup')) { + commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', + path: `/spec/hidden/enabled`, value: false, force: true, }) - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: '', - force: true, - }) } - setDiscriminatorValue('/bundleApiLoaded', true) -} + async function initBundle() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') -function fetchOptions({ model, getValue, commit }, type) { - let kind = getValue(model, '/metadata/resource/kind') - - let returnArray = [] - if (type === 'clusterTier/placement') { - returnArray = placement - } else if (type === `databases/${kind}/versions`) { - returnArray = versions - } else if (type === 'storageClasses') { - returnArray = storageClass - } else if (type === 'clusterIssuers') { - returnArray = clusterIssuers - } + let db = getValue(model, '/metadata/resource/kind') + db = db.toLowerCase() + let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` + const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` + + try { + const resp = await axios.get(url) + features = resp.data.features || [] + placement = resp.data.placementpolicies || [] + versions = resp.data.versions || [] + storageClass = resp.data.storageclasses || [] + clusterIssuers = resp.data.clusterissuers || [] + nodetopologiesDedicated = resp.data.dedicated || [] + nodetopologiesShared = resp.data.shared || [] + + const response = await axios.get(annotationUrl) + const annotations = response.data?.metadata?.annotations || {} + const uidRange = annotations['openshift.io/sa.scc.uid-range'] + if (uidRange) { + const val = uidRange.split('/')[0] + commit('wizard/model$update', { + path: '/spec/openshift/securityContext/runAsUser', + value: val, + force: true, + }) + } + } catch (e) { + console.log(e) + } - if (returnArray.length === 1) { - const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: path, - value: returnArray[0], + path: '/spec/deletionPolicy', + value: getDefault('deletionPolicy'), force: true, }) - } - - return returnArray -} -function getAdminOptions({ getValue, model, watchDependency, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') + if (!getValue(model, `/spec/admin/databases/RabbitMQ/mode/toggle`)) { + let defMode = getDefault('databases/RabbitMQ/mode') || '' + if (defMode === '') { + const arr = getValue(model, '/spec/databases/RabbitMQ/mode/available') || [] + if (arr.length) defMode = arr[0] + } + commit('wizard/model$update', { + path: '/spec/mode', + value: defMode, + force: true, + }) + } - const options = getValue(model, `/spec/admin/${type}/available`) || [] + if (!features.includes('tls')) { + commit('wizard/model$update', { + path: '/spec/admin/tls/default', + value: false, + force: true, + }) + } + if (!features.includes('binding')) { + commit('wizard/model$update', { + path: '/spec/admin/expose/default', + value: false, + force: true, + }) + } + if (!features.includes('monitoring')) { + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: 'none', + force: true, + }) + } + if (!features.includes('backup')) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: '', + force: true, + }) + } - if (options.length === 0) { - return fetchOptions({ model, getValue, commit }, type) + setDiscriminatorValue('/bundleApiLoaded', true) } - if (type.endsWith('/mode')) { - return ( - options?.map((item) => ({ - description: modeDetails[item]?.description || '', - text: modeDetails[item]?.text || '', - value: item, - })) || [] - ) - } - return options -} -function checkIfFeatureOn({ getValue, model }, type) { - let val = getValue(model, `/spec/admin/${type}/toggle`) - if (type === 'backup' || type === 'archiver') { - val = getValue(model, `/spec/admin/${type}/enable/toggle`) - } - const backupVal = getValue(model, '/spec/backup/tool') - - if (type === 'backup') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } else if (type === 'tls') { - return features.includes('tls') && val - } else if (type === 'expose') { - return features.includes('binding') && val - } else if (type === 'monitoring') { - return features.includes('monitoring') && val - } else if (type === 'archiver') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } -} + function fetchOptions(type) { + let kind = getValue(model, '/metadata/resource/kind') + + let returnArray = [] + if (type === 'clusterTier/placement') { + returnArray = placement + } else if (type === `databases/${kind}/versions`) { + returnArray = versions + } else if (type === 'storageClasses') { + returnArray = storageClass + } else if (type === 'clusterIssuers') { + returnArray = clusterIssuers + } -function isToggleOn({ getValue, model, discriminator, watchDependency }, type) { - watchDependency('discriminator#/bundleApiLoaded') - watchDependency('model#/spec/admin/deployment/default') - const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') - let deploymentType = getValue(model, `/spec/admin/deployment/default`) - if ( - type === 'tls' || - type === 'backup' || - type === 'expose' || - type === 'monitoring' || - type === 'archiver' - ) { - return checkIfFeatureOn({ getValue, model }, type) - } else if ( - type === 'clusterTier' || - type === 'clusterTier/placement' || - type === 'clusterTier/nodeTopology' - ) { - if (deploymentType === 'Dedicated' && bundleApiLoaded) return true - else return false - } else if (type === 'deployment') { - const deploymentType = getValue(model, '/spec/admin/deployment/default') - if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + if (returnArray.length === 1) { + const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: '/spec/admin/deployment/default', - value: 'Shared', + path: path, + value: returnArray[0], force: true, }) } - return ( - getValue(model, `/spec/admin/${type}/toggle`) && - nodetopologiesDedicated.length && - bundleApiLoaded - ) - } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded -} -async function getNodeTopology({ model, getValue, axios, storeGet, watchDependency }) { - watchDependency('model#/spec/admin/deployment/default') - watchDependency('model#/spec/admin/clusterTier/default') - const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' - const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' - let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + return returnArray + } - const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + function getAdminOptions(type) { + // watchDependency('discriminator#/bundleApiLoaded') - if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared - else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + const options = getValue(model, `/spec/admin/${type}/available`) || [] - const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) - return filteredList -} + if (options.length === 0) { + return fetchOptions(type) + } + if (type.endsWith('/mode')) { + return ( + options?.map((item) => ({ + description: modeDetails[item]?.description || '', + text: modeDetails[item]?.text || '', + value: item, + })) || [] + ) + } + return options + } -function filterNodeTopology(list, tier, provider) { - // first filter the list from value that exists from the filtered list got from API - const filteredlist = list + function checkIfFeatureOn(type) { + let val = getValue(model, `/spec/admin/${type}/toggle`) + if (type === 'backup' || type === 'archiver') { + val = getValue(model, `/spec/admin/${type}/enable/toggle`) + } + const backupVal = getValue(model, '/spec/backup/tool') + + if (type === 'backup') { + return features.includes('backup') && backupVal === 'KubeStash' && val + } else if (type === 'tls') { + return features.includes('tls') && val + } else if (type === 'expose') { + return features.includes('binding') && val + } else if (type === 'monitoring') { + return features.includes('monitoring') && val + } else if (type === 'archiver') { + return features.includes('backup') && backupVal === 'KubeStash' && val + } + } - // filter the list based on clusterTier - if (provider === 'EKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('c') - else if (tier === 'MemoryOptimized') return item.startsWith('r') - else return !item.startsWith('c') && !item.startsWith('r') - }) - } else if (provider === 'AKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - else - return ( - !(item.startsWith('f') || item.startsWith('fx')) && - !( + function isToggleOn(type) { + // watchDependency('discriminator#/bundleApiLoaded') + // watchDependency('model#/spec/admin/deployment/default') + const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') + let deploymentType = getValue(model, `/spec/admin/deployment/default`) + if ( + type === 'tls' || + type === 'backup' || + type === 'expose' || + type === 'monitoring' || + type === 'archiver' + ) { + return checkIfFeatureOn(type) + } else if ( + type === 'clusterTier' || + type === 'clusterTier/placement' || + type === 'clusterTier/nodeTopology' + ) { + if (deploymentType === 'Dedicated' && bundleApiLoaded) return true + else return false + } else if (type === 'deployment') { + const deploymentType = getValue(model, '/spec/admin/deployment/default') + if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + commit('wizard/model$update', { + path: '/spec/admin/deployment/default', + value: 'Shared', + force: true, + }) + } + return ( + getValue(model, `/spec/admin/${type}/toggle`) && + nodetopologiesDedicated.length && + bundleApiLoaded + ) + } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded + } + + async function getNodeTopology() { + // watchDependency('model#/spec/admin/deployment/default') + // watchDependency('model#/spec/admin/clusterTier/default') + const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' + const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' + let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + + const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + + if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared + else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + + const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) + return filteredList + } + + function filterNodeTopology(list, tier, provider) { + // first filter the list from value that exists from the filtered list got from API + const filteredlist = list + + // filter the list based on clusterTier + if (provider === 'EKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('c') + else if (tier === 'MemoryOptimized') return item.startsWith('r') + else return !item.startsWith('c') && !item.startsWith('r') + }) + } else if (provider === 'AKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('e') || item.startsWith('eb') || item.startsWith('ec') || item.startsWith('m') || item.startsWith('d') ) - ) - }) - } else if (provider === 'GKE') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') - return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - else - return ( - !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && - !( + else + return ( + !(item.startsWith('f') || item.startsWith('fx')) && + !( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + ) + }) + } else if (provider === 'GKE') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') + return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('x4') || item.startsWith('m1') || item.startsWith('m2') || item.startsWith('m3') ) - ) - }) - } else return filteredlist -} - -function returnFalse() { - return false -} - -function isConfigDatabaseOn({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configDatabase') - return getValue(discriminator, '/configDatabase') -} + else + return ( + !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && + !( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + ) + }) + } else return filteredlist + } -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} + function returnFalse() { + return false + } -function showStorageSizeField({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - const validType = [] - return !validType.includes(modelPathValue) -} + function isConfigDatabaseOn() { + // watchDependency('discriminator#/configDatabase') + return getValue(discriminator, '/configDatabase') + } -function showHidden({ watchDependency, model, getValue }) { - watchDependency('model#/spec/hidden/enabled') - const isHiddenOn = getValue(model, '/spec/hidden/enabled') || '' - const notStandalone = notEqualToDatabaseMode({ model, getValue, watchDependency }, 'Standalone') - return isHiddenOn && notStandalone -} + function notEqualToDatabaseMode(mode) { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + return modelPathValue && modelPathValue !== mode + } -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} + function showHidden() { + // watchDependency('model#/spec/hidden/enabled') + const isHiddenOn = getValue(model, '/spec/hidden/enabled') || '' + const notStandalone = notEqualToDatabaseMode('Standalone') + return isHiddenOn && notStandalone + } -function showArbiter({ watchDependency, model, getValue }) { - watchDependency('model#/spec/arbiter/enabled') - const isArbiterOn = getValue(model, '/spec/arbiter/enabled') || '' - const notStandalone = notEqualToDatabaseMode({ model, getValue, watchDependency }, 'Standalone') - return isArbiterOn && notStandalone -} + function showArbiter() { + // watchDependency('model#/spec/arbiter/enabled') + const isArbiterOn = getValue(model, '/spec/arbiter/enabled') || '' + const notStandalone = notEqualToDatabaseMode('Standalone') + return isArbiterOn && notStandalone + } -function clearConfiguration({ discriminator, getValue, commit }) { - const configOn = getValue(discriminator, '/configDatabase') + function clearConfiguration() { + const configOn = getValue(discriminator, '/configDatabase') - if (!configOn) { - commit('wizard/model$delete', '/spec/configuration') + if (!configOn) { + commit('wizard/model$delete', '/spec/configuration') + } } -} -function showIssuer({ model, getValue, watchDependency, discriminator }) { - watchDependency('model#/spec/admin/tls/default') - const isTlsEnabled = getValue(model, '/spec/admin/tls/default') - const isIssuerToggleEnabled = isToggleOn( - { getValue, model, watchDependency, discriminator }, - 'clusterIssuers', - ) - return isTlsEnabled && isIssuerToggleEnabled -} + function showIssuer() { + // watchDependency('model#/spec/admin/tls/default') + const isTlsEnabled = getValue(model, '/spec/admin/tls/default') + const isIssuerToggleEnabled = isToggleOn('clusterIssuers') + return isTlsEnabled && isIssuerToggleEnabled + } -function onAuthChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/authSecret/password', - value: '', - force: true, - }) -} + function onAuthChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/spec/authSecret/password', + value: '', + force: true, + }) + } -function setMonitoring({ getValue, model }) { - const agent = getValue(model, '/spec/admin/monitoring/agent') || '' - return !!agent -} + function setMonitoring() { + const agent = getValue(model, '/spec/admin/monitoring/agent') || '' + return !!agent + } -function setBackup({ model, getValue }) { - const backup = getValue(model, '/spec/backup/tool') - const val = getValue(model, '/spec/admin/backup/enable/default') - return backup === 'KubeStash' && features.includes('backup') && val -} + function setBackup() { + const backup = getValue(model, '/spec/backup/tool') + const val = getValue(model, '/spec/admin/backup/enable/default') + return backup === 'KubeStash' && features.includes('backup') && val + } -function isMachineCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue === 'custom' -} + function isMachineCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue === 'custom' + } -function isMachineNotCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue !== 'custom' && !!modelPathValue -} + function isMachineNotCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue !== 'custom' && !!modelPathValue + } -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, }, - }, - ) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] + ) + if (resp.data?.status?.projects) { + const projects = resp.data?.status?.projects + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } + } catch (e) { + console.log(e) } - } catch (e) { - console.log(e) + return [] } - return [] -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } -function updateAlertValue({ commit, model, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const alert = isMonitorEnabled ? 'warning' : 'none' - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: alert, - force: true, - }) - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} + function updateAlertValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const alert = isMonitorEnabled ? 'warning' : 'none' + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: alert, + force: true, + }) + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: agent, + force: true, + }) + } -function showAdditionalSettings({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return features.length -} + function showAdditionalSettings() { + // watchDependency('discriminator#/bundleApiLoaded') + return features.length + } -function getDefault({ getValue, model }, type) { - const val = getValue(model, `/spec/admin/${type}/default`) || '' - return val -} + function getDefault(type) { + const val = getValue(model, `/spec/admin/${type}/default`) || '' + return val + } -function isConfigAvailable({ getValue, model }) { - const val = getValue(model, '/spec/configuration') - return val !== '' -} + async function getReferSecrets() { + const referSecret = getValue(discriminator, '/referSecret') + if (!referSecret) { + return [] + } -async function getReferSecrets({ getValue, model, storeGet, axios, discriminator }) { - const referSecret = getValue(discriminator, '/referSecret') - if (!referSecret) { - return [] - } + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/metadata/release/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/metadata/release/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - - const options = [] - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) - } catch (e) { - console.log(e) + const options = [] + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + return options } - return options -} -function showAuthPasswordField({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showAuthPasswordField() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !modelPathValue && showReferSecret() + } -function showSecretDropdown({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showSecretDropdown() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !!modelPathValue && showReferSecret() + } -function showReferSecret({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/createAuthSecret') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue -} + function showReferSecret() { + const modelPathValue = getValue(discriminator, '/createAuthSecret') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue + } -function getDefaultValue({ getValue, model }, path) { - const val = getValue(model, `/${path}`) || '' - return val -} + function getDefaultValue(path) { + const val = getValue(model, `/${path}`) || '' + return val + } -function showReferSecretSwitch({ model, getValue, watchDependency, discriminator }) { - const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showReferSecretSwitch() { + const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue && showReferSecret() + } -function onReferSecretChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) -} + function onReferSecretChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + } -return { - showReferSecretSwitch, - onReferSecretChange, - getDefaultValue, - isRancherManaged, - showSecretDropdown, - showReferSecret, - getReferSecrets, - isConfigAvailable, - initBundle, - getNamespaces, - updateAlertValue, - getAdminOptions, - isToggleOn, - showAlerts, - getNodeTopology, - clearArbiterHidden, - returnFalse, - showHidden, - isConfigDatabaseOn, - notEqualToDatabaseMode, - filterNodeTopology, - onAuthChange, - setMonitoring, - isMachineNotCustom, - isMachineCustom, - showIssuer, - showArbiter, - clearConfiguration, - showStorageSizeField, - onBackupSwitch, - isVariantAvailable, - fetchJsons, - showAuthPasswordField, - isEqualToModelPathValue, - showAuthSecretField, - showStorageSizeField, - getResources, - getMongoDbVersions, - onCreateAuthSecretChange, - getSecrets, - getMachineListForOptions, - setLimits, - setRequests, - setMachineToCustom, - updateAgentValue, - getCreateNameSpaceUrl, - ifCapiProviderIsNotEmpty, - ifDedicated, - dedicatedOnChange, - ifZones, - zonesOnChange, - getZones, - getSKU, - showMultiselectZone, - showSelectZone, - setStorageClass, - showReplicaField, - onModeChange, - setBackup, - showAdditionalSettings, - getDefault, + return { + showReferSecretSwitch, + onReferSecretChange, + getDefaultValue, + isRancherManaged, + showSecretDropdown, + showReferSecret, + getReferSecrets, + initBundle, + getNamespaces, + updateAlertValue, + getAdminOptions, + isToggleOn, + showAlerts, + getNodeTopology, + clearArbiterHidden, + returnFalse, + showHidden, + isConfigDatabaseOn, + notEqualToDatabaseMode, + filterNodeTopology, + onAuthChange, + setMonitoring, + isMachineNotCustom, + isMachineCustom, + showIssuer, + showArbiter, + clearConfiguration, + showStorageSizeField, + onBackupSwitch, + isVariantAvailable, + fetchJsons, + showAuthPasswordField, + isEqualToModelPathValue, + showAuthSecretField, + getResources, + getMongoDbVersions, + onCreateAuthSecretChange, + getSecrets, + getMachineListForOptions, + setLimits, + setRequests, + setMachineToCustom, + updateAgentValue, + getCreateNameSpaceUrl, + ifCapiProviderIsNotEmpty, + ifDedicated, + dedicatedOnChange, + ifZones, + zonesOnChange, + getZones, + getSKU, + showMultiselectZone, + showSelectZone, + setStorageClass, + showReplicaField, + onModeChange, + setBackup, + showAdditionalSettings, + getDefault, + } } diff --git a/charts/kubedbcom-rabbitmq-editor/ui/edit-ui.yaml b/charts/kubedbcom-rabbitmq-editor/ui/edit-ui.yaml index 74cdf8eeb9..24e58243ef 100644 --- a/charts/kubedbcom-rabbitmq-editor/ui/edit-ui.yaml +++ b/charts/kubedbcom-rabbitmq-editor/ui/edit-ui.yaml @@ -1,641 +1,568 @@ -steps: -- form: - discriminator: - dbDetails: - default: false - type: boolean +type: multi-step-form +step: + - type: single-step-form + id: compute-autoscaler + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: Select Db - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: Select Type - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - discriminator: - topologyMachines: - default: [] - type: array - elements: - - fetch: fetchTopologyMachines - if: returnFalse - schema: - $ref: discriminator#/topologyMachines - type: input - - elements: - - computed: setTrigger|autoscalingKubedbComRabbitMQAutoscaler/spec/compute/rabbitmq/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/rabbitmq/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/rabbitmq/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/rabbitmq/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-max: - type: string - allowedMachine-min: - type: string - elements: - - computed: setAllowedMachine|min - disableUnselect: true - fetch: getMachines|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|rabbitmq - schema: - $ref: discriminator#/properties/allowedMachine-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/rabbitmq/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/rabbitmq/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/rabbitmq/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|max - disableUnselect: true - fetch: getMachines|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|rabbitmq - schema: - $ref: discriminator#/properties/allowedMachine-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/rabbitmq/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/rabbitmq/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/rabbitmq/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|rabbitmq - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/rabbitmq/properties/controlledResources - type: multiselect - label: - text: RabbitMQ - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/rabbitmq - show_label: true - type: single-step-form - - elements: - - fetch: fetchNodeTopology - label: - text: Select Node Topology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name - type: select - - if: isNodeTopologySelected - label: - text: ScaleUp Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage - type: input - - if: isNodeTopologySelected - label: - text: ScaleDown Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage - type: input - if: hasNoAnnotations - label: - text: NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/nodeTopology - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply + - type: block-layout + if: + type: function + name: isConsole + elements: + - type: input + label: Name + schema: schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/metadata/properties/name + - type: select + label: Select Namespace + loader: getNamespaces + if: + type: function + name: isRancherManaged + schema: schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/metadata/properties/namespace + - type: select + label: Select Db + validation: + type: required + refresh: true + schema: schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/databaseRef/properties/name + watcher: + func: initMetadata + paths: + - schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/databaseRef/properties/name + + - type: radio + if: + type: function + name: isConsole + label: Select Type + validation: + type: required + schema: temp/properties/autoscalingType + watcher: + func: initMetadata + paths: + - temp/properties/autoscalingType options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: compute-autoscaler - title: steps.6.label -- form: - discriminator: - enableMonitoring: - default: true - type: boolean + - text: Compute + value: compute + description: Scale your CPU Memory based on resource usage + - text: Storage + value: storage + description: Expand your database size based on volume usage + + - type: block-layout + showLabels: false + loader: fetchTopologyMachines + elements: + # rabbitmq mode + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComRabbitMQAutoscaler/spec/compute/rabbitmq/trigger + schema: temp/properties/compute/properties/rabbitmq/properties/trigger + watcher: + func: onTriggerChange|compute/rabbitmq + paths: + - temp/properties/compute/properties/rabbitmq/properties/trigger + - type: label-element + label: Pod lifetime threshold + subtitle: Specifies the duration a pod can exist before being considered for autoscaling. This helps prevent frequent scaling operations on short-lived pods. + - type: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + customClass: width-300 + schema: schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/rabbitmq/properties/podLifeTimeThreshold + - type: block-layout + label: RabbitMQ + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/rabbitmq + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/rabbitmq/properties/resourceDiffPercentage + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources for autoscaling. The autoscaler will keep resource allocation within these bounds. + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|min + loader: + name: getMachines|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-max + watcher: + func: onMachineChange|rabbitmq + paths: + - temp/properties/allowedMachine-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/rabbitmq/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/rabbitmq/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|max + loader: + name: getMachines|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-min + watcher: + func: onMachineChange|rabbitmq + paths: + - temp/properties/allowedMachine-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/rabbitmq/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/rabbitmq/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|rabbitmq + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/rabbitmq/properties/controlledResources + + - type: block-layout + label: Node Topology + if: + type: function + name: hasNoAnnotations + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/nodeTopology + elements: + - type: select + label: Select NodeTopology + loader: fetchNodeTopology + schema: schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name + - type: threshold-input + label: ScaleUp Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage + - type: threshold-input + label: ScaleDown Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage + + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + # schema: schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/opsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: storage-autoscaler elements: - - label: - text: labels.to_update_exporter_resources - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - function: getOpsRequestUrl|VerticalScaling - - computed: isValueExistInModel|/resources/kubedbComRabbitMQ/spec/monitor - label: - text: labels.enable_monitoring - onChange: onEnableMonitoringChange - schema: - $ref: discriminator#/enableMonitoring - type: switch - - discriminator: - customizeExporter: - default: true - type: boolean + - type: block-layout + showLabels: false 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/kubedbComRabbitMQ/properties/spec/properties/monitor/properties/agent - type: radio - - elements: - - label: - text: labels.scrapping_interval - schema: - $ref: schema#/properties/resources/properties/kubedbComRabbitMQ/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval - type: input - if: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComRabbitMQ/spec/monitor/agent - label: - text: labels.service_monitor_configuration - show_label: true - type: single-step-form - - elements: - - elements: - - addFormLabel: labels.endpoint - element: + - type: block-layout + showLabels: false + elements: + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComRabbitMQAutoscaler/spec/storage/rabbitmq/trigger + schema: temp/properties/storage/properties/rabbitmq/properties/trigger + watcher: + func: onTriggerChange|storage/rabbitmq + paths: + - temp/properties/storage/properties/rabbitmq/properties/trigger + - type: label-element + label: Expansion Mode (Online/Offline) + subtitle: For Online Mode enables scaling without downtime by dynamically resizing volumes. Offline Mode requires brief downtime but ensures data integrity during expansion. + - type: select + label: Mode + description: Select how the storage expansion should be handled. Online mode allows expansion without downtime, while Offline mode may require a restart. + options: + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/storage/properties/rabbitmq/properties/expansionMode + - type: block-layout + label: RabbitMQ Storage + showLabels: true 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/kubedbComRabbitMQ/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/kubedbComRabbitMQ/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: - - if: returnFalse - label: - text: labels.resources - schema: - $ref: schema#/properties/resources/properties/kubedbComRabbitMQ/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/kubedbComRabbitMQ/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/kubedbComRabbitMQ/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup - type: input - - label: - text: labels.port - schema: - $ref: schema#/properties/resources/properties/kubedbComRabbitMQ/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/kubedbComRabbitMQ/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args/items - type: input - label: - text: labels.args - schema: - $ref: schema#/properties/resources/properties/kubedbComRabbitMQ/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args - type: list-input-form - - alias: reusable_env - chart: - name: uibytebuildersdev-component-env - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComRabbitMQ/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: - discriminator: - dbDetails: - default: false - type: boolean + - type: threshold-input + label: UsageThreshold (%) + subtitle: Set the threshold percentage of storage usage that triggers autoscaling + schema: schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/storage/properties/rabbitmq/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + init: + type: func + value: setValueFromDbDetails|resources/kubedbComRabbitMQ/spec/storage/resources/requests/storage + schema: schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/storage/properties/rabbitmq/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComRabbitMQ/spec/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComRabbitMQAutoscaler/spec/storage/rabbitmq/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/storage/properties/rabbitmq/properties/scalingRules + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/storage/properties/rabbitmq/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComRabbitMQAutoscaler/spec/storage/rabbitmq/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/storage/properties/rabbitmq/properties/upperBound + - type: block-layout + label: OpsRequest Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: monitoring + loader: initMonitoring elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - computed: getDbDetails - if: returnFalse - type: input - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: Select Db - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: Select Type - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComRabbitMQAutoscaler/spec/storage/rabbitmq/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/storage/properties/rabbitmq/properties/trigger - type: select - - label: - text: Expansion Mode + - type: label-element + label: To update Exporter Resource section click on Create OpsRequest + - type: anchor + label: Create OpsRequest + schema: temp/properties/opsRequestUrl + init: + type: func + value: getOpsRequestUrl|scale-vertically + - type: switch + label: Enable Monitoring + fullwidth: true + schema: temp/properties/enableMonitoring + init: + type: func + value: isValueExistInModel|/resources/kubedbComRabbitMQ/spec/monitor + watcher: + func: onEnableMonitoringChange + paths: + - temp/properties/enableMonitoring + - type: block-layout + if: + type: function + name: showMonitoringSection + elements: + - type: radio + label: Select a Monitoring Method + schema: schema/properties/resources/properties/kubedbComRabbitMQ/properties/spec/properties/monitor/properties/agent + isHorizontal: true options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/storage/properties/rabbitmq/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/storage/properties/rabbitmq/properties/usageThreshold - type: input - - addFormLabel: ScalingRules - element: - elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/storage/properties/rabbitmq/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/storage/properties/rabbitmq/properties/scalingRules/items/properties/threshold + - text: Prometheus Operator + value: prometheus.io/operator + description: Inject metric exporter sidecar and creates a ServiceMonitor + - text: Custom ServiceMonitor + value: prometheus.io + description: Injects the metric exporter sidecar and let you customize ServiceMonitor + - text: Custom Scrapper + value: prometheus.io/builtin + description: Inject metric exporter sidecar and add Prometheus annotations to the stats Service + init: + type: static + value: prometheus.io/operator + watcher: + func: onAgentChange + paths: + - schema/properties/resources/properties/kubedbComRabbitMQ/properties/spec/properties/monitor/properties/agent + - type: block-layout + label: ServiceMonitor Configuration + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComRabbitMQ/spec/monitor/agent + elements: + - label: Scrapping Interval + schema: schema/properties/resources/properties/kubedbComRabbitMQ/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComRabbitMQAutoscaler/spec/storage/rabbitmq/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/storage/properties/rabbitmq/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComRabbitMQAutoscaler/spec/storage/rabbitmq/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/storage/properties/rabbitmq/properties/upperBound - type: input - label: - text: RabbitMQ - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/compute/properties/rabbitmq - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRabbitMQAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: storage-autoscaler - title: steps.10.label -- form: - discriminator: - binding: - default: false - type: boolean + - type: block-layout + label: Service Monitor + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComRabbitMQ/spec/monitor/agent + elements: + - type: array-object-form + label: Endpoints + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/endpoints + elements: + - type: switch + label: Honor labels + fullwidth: true + schema: honorLabels + - type: input + label: Interval + schema: interval + validation: + type: required + - type: input + label: Path + schema: path + validation: + type: required + - type: input + label: Port + schema: port + validation: + type: required + - type: select + multiple: true + label: Match Namespaces + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/namespaceSelector/properties/matchNames + loader: getResources|core|v1|namespaces + if: + type: function + name: returnFalse + - type: block-layout + showLabels: false + # schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector + if: + type: function + name: returnFalse + elements: + - type: object-item + label: Labels + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector/properties/matchLabels + - type: object-item + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/metadata/properties/labels + label : Labels + buttonClass: is-light is-outlined + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComRabbitMQ/spec/monitor/agent + # individualItemDisabilityCheck: disableLableChecker + - type: label-element + label: Exporter Configuration + schema: '' + - type: switch + label: Customize Exporter Sidecar + fullwidth: true + schema: temp/properties/customizeExporter + init: + type: static + value: true + watcher: + func: onCustomizeExporterChange + paths: + - temp/properties/customizeExporter + - type: block-layout + label: Customer Exporter Section + showLabels: false + if: + type: function + name: showCustomizeExporterSection + elements: + - type: machine-compare + label: Resources + schema: schema/properties/resources/properties/kubedbComRabbitMQ/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/resources + if: + type: function + name: returnFalse + - type: label-element + label: Security Context + schema: '' + - type: input + schema: schema/properties/resources/properties/kubedbComRabbitMQ/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsUser + label: Run as User + - type: input + schema: schema/properties/resources/properties/kubedbComRabbitMQ/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup + label: Run as Group + - type: input + schema: schema/properties/resources/properties/kubedbComRabbitMQ/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/port + label: Port + - type: array-item-form + label: Args + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/kubedbComRabbitMQ/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args + init: + type: static + value: [] + element: + type: input + label: Args + # isSubsection: true + - type: block-layout + label: Metadata + showLabels: false + elements: + - type: array-object-form + init: + type: func + value: initEnvArray + label: Environment Variables + buttonClass: is-light is-outlined + watcher: + func: onEnvArrayChange + paths: + - temp/properties/env + schema: temp/properties/env + elements: + - type: input + label: Name + schema: name + validation: + type: required + - type: radio + label: Value From + schema: temp/properties/valueFromType + validation: + type: required + init: + type: func + value: setValueFrom + options: + - text: Input + value: input + - text: Secret + value: secret + - text: ConfigMap + value: configMap + watcher: + func: onValueFromChange + paths: + - temp/properties/valueFromType + - type: input + label: Value + schema: value + validation: + type: required + if: + name: isEqualToTemp|input + type: function + - type: select + if: + type: function + name: isEqualToTemp|configMap + label: ConfigMap Name + schema: valueFrom/properties/configMapKeyRef/properties/name + loader: + name: resourceNames|core|v1|configmaps + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: ConfigMap Key + schema: valueFrom/properties/configMapKeyRef/properties/key + if: + type: function + name: isEqualToTemp|configMap + loader: + name: getConfigMapKeys + watchPaths: + - schema/resources/kubedbComRabbitMQ/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/configMapKeyRef/name + - schema/metadata/release/namespace + - type: select + label: Secret Name + schema: valueFrom/properties/secretKeyRef/properties/name + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecrets + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: Secret Key + schema: valueFrom/properties/secretKeyRef/properties/key + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecretKeys + watchPaths: + - schema/resources/kubedbComRabbitMQ/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/secretKeyRef/name + - schema/metadata/release/namespace + + - type: single-step-form + id: binding elements: - - computed: isBindingAlreadyOn - label: - text: Expose Database - onChange: addOrRemoveBinding - schema: - $ref: discriminator#/properties/binding - type: switch - type: single-step-form - id: binding - title: Gateway Binding -type: multi-step-form + - type: switch + label: Expose Database + schema: temp/properties/binding + fullwidth: true + init: + type: func + value: isBindingAlreadyOn + watcher: + func: addOrRemoveBinding + paths: + - temp/properties/binding diff --git a/charts/kubedbcom-rabbitmq-editor/ui/functions.js b/charts/kubedbcom-rabbitmq-editor/ui/functions.js index 66580c8e84..5cdbbebdfa 100644 --- a/charts/kubedbcom-rabbitmq-editor/ui/functions.js +++ b/charts/kubedbcom-rabbitmq-editor/ui/functions.js @@ -1,1391 +1,373 @@ -// ************************* common functions ******************************************** -// eslint-disable-next-line no-empty-pattern -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 disableLableChecker({ itemCtx }) { - const { key } = itemCtx - if (key.startsWith('app.kubernetes.io') || key.includes('helm')) return true - else return false -} - -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} - -async function getResources({ axios, storeGet }, 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 [] - } -} - -function isEqualToDiscriminatorPath( - { discriminator, getValue, watchDependency }, - value, - discriminatorPath, -) { - watchDependency('discriminator#' + discriminatorPath) - const discriminatorValue = getValue(discriminator, discriminatorPath) - return discriminatorValue === value -} - -function setValueFromModel({ getValue, model }, path) { - return getValue(model, path) -} - -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 -} - -async function getResourceList(axios, storeGet, { 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( - { axios, getValue, model, watchDependency, storeGet }, - 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 unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - 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, - } - }) -} - -function returnTrue() { - return true -} - -function returnStringYes() { - return 'yes' -} -function setAddressType({ model, getValue }) { - const value = getValue(model, '/resources/kubedbComRabbitMQ/spec/useAddressType') - - if (!value) { - return 'DNS' - } - - return value -} - -// ************************* Basic Info ********************************************** -async function getRabbitMQVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, - }, - }, - } - - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) - - const resources = (resp && resp.data && resp.data.items) || [] - - // keep only non deprecated versions - const filteredMongoDbVersions = resources.filter((item) => item.spec && !item.spec.deprecated) - - filteredMongoDbVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredMongoDbVersions - } catch (e) { - console.log(e) - return [] - } -} - -// ********************* Database Mode *********************** -function setDatabaseMode({ model, getValue }) { - const replicas = getValue(model, '/resources/kubedbComRabbitMQ/spec/replicas') - - return replicas === 1 ? 'Standalone' : 'Cluster' -} - -function isEqualToDatabaseMode({ getValue, watchDependency, discriminator }, value) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - return mode === value -} - -const onDatabaseModeChange = ({ discriminator, getValue, commit }) => { - const databaseMode = getValue(discriminator, '/activeDatabaseMode') - - commit('wizard/model$update', { - path: '/resources/kubedbComRabbitMQ/spec/replicas', - value: databaseMode === 'Standalone' ? 1 : 3, - force: true, - }) -} - -// ************************** TLS ******************************88 - -function setApiGroup() { - return 'cert-manager.io' -} - -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - watchDependency('model#/resources/kubedbComRabbitMQ/spec/tls/issuerRef/apiGroup') - watchDependency('model#/resources/kubedbComRabbitMQ/spec/tls/issuerRef/kind') - watchDependency('model#/metadata/release/namespace') - const apiGroup = getValue(model, '/resources/kubedbComRabbitMQ/spec/tls/issuerRef/apiGroup') - const kind = getValue(model, '/resources/kubedbComRabbitMQ/spec/tls/issuerRef/kind') - const namespace = getValue(model, '/metadata/release/namespace') - - let url - if (kind === 'Issuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/namespaces/${namespace}/issuers` - } else if (kind === 'ClusterIssuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/clusterissuers` - } - - if (!url) return [] - - 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 [] - } -} - -async function hasIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await getIssuerRefsName({ - axios, - storeGet, - getValue, +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( model, - watchDependency, - }) - - return !!(resp && resp.length) -} - -async function hasNoIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await hasIssuerRefName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !resp -} - -function setSSLMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComRabbitMQ/spec/sslMode') - return val || 'require' -} - -function showTlsConfigureSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configureTLS') - const configureStatus = getValue(discriminator, '/configureTLS') - return configureStatus -} - -function onTlsConfigureChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/configureTLS') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComRabbitMQ/spec/tls', - value: { issuerRef: {}, certificates: [] }, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComRabbitMQ/spec/tls') - commit('wizard/model$delete', '/resources/kubedbComRabbitMQ/spec/sslMode') - } -} - -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} - -/****** Monitoring *********/ - -function showMonitoringSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/enableMonitoring') - const configureStatus = getValue(discriminator, '/enableMonitoring') - return configureStatus -} - -function onEnableMonitoringChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/enableMonitoring') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComRabbitMQ/spec/monitor', - value: {}, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComRabbitMQ/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, getValue }) { - watchDependency('discriminator#/customizeExporter') - const configureStatus = getValue(discriminator, '/customizeExporter') - return configureStatus -} - -function onCustomizeExporterChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/customizeExporter') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComRabbitMQ/spec/monitor/prometheus/exporter', - value: {}, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComRabbitMQ/spec/monitor/prometheus/exporter') - } -} - -// ********************************* Initialization & Backup ************************************* -const stashAppscodeComRestoreSession_init = { - spec: { - repository: { - name: '', - }, - rules: [ - { - snapshots: ['latest'], - }, - ], - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} -const initScript = { - scriptPath: '', - secret: { - secretName: '', - }, -} -const stashAppscodeComRepository_init_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const stashAppscodeComRepository_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const restoreSessionInitRunTimeSettings = { - container: { - resources: { - requests: { - cpu: '', - memory: '', - }, - limits: { - cpu: '', - memory: '', - }, - }, - nice: { - adjustment: null, - }, - ionice: { - class: null, - classData: null, - }, - securityContext: { - privileged: false, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - env: [], - envFrom: [], - }, - pod: { - serviceAccountName: '', - imagePullSecrets: [], - securityContext: { - fsGroup: null, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - }, -} - -const stashAppscodeComBackupConfiguration = { - spec: { - repository: { - name: '', - }, - retentionPolicy: { - keepLast: 5, - name: 'keep-last-5', - prune: true, - }, - schedule: '*/5 * * * *', - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} - -function valueExists(value, getValue, path) { - const val = getValue(value, path) - if (val) return true - else return false -} - -function initPrePopulateDatabase({ getValue, model }) { - const waitForInitialRestore = getValue( - model, - '/resources/kubedbComRabbitMQ/spec/init/waitForInitialRestore', - ) - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', + store.state, ) - const script = getValue(model, '/resources/kubedbComRabbitMQ/spec/init/script') - return waitForInitialRestore || !!stashAppscodeComRestoreSession_init || !!script ? 'yes' : 'no' -} + /********** 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', []) + + // Compute 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', '') + + // monitoring + + 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') -function onPrePopulateDatabaseChange({ commit, getValue, discriminator, model }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - if (prePopulateDatabase === 'no') { - // delete related properties - commit('wizard/model$update', { - path: '/resources/kubedbComRabbitMQ/spec/init/waitForInitialRestore', - value: false, - }) - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - commit('wizard/model$delete', '/resources/kubedbComRabbitMQ/spec/init/script') - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else { - const dbName = getValue(model, '/metadata/release/name') - // set stashAppscodeComRestoreSession_init if it doesn't exist - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - force: true, - }) - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - } - } -} - -function initDataSource({ getValue, model }) { - const script = getValue(model, '/resources/kubedbComRabbitMQ/spec/init/script') - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - - if (script) return 'script' - else if (stashAppscodeComRestoreSession_init) return 'stashBackup' - else return undefined -} - -function onDataSourceChange({ commit, getValue, discriminator, model }) { - const dataSource = getValue(discriminator, '/dataSource') - - commit('wizard/model$update', { - path: '/resources/kubedbComRabbitMQ/spec/init/waitForInitialRestore', - value: dataSource === 'stashBackup', - force: true, - }) - - if (dataSource === 'script') { - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - - // create a new script if there is no script property - if (!valueExists(model, getValue, '/resources/kubedbComRabbitMQ/spec/init/script')) - commit('wizard/model$update', { - path: '/resources/kubedbComRabbitMQ/spec/init/script', - value: initScript, - }) - } else if (dataSource === 'stashBackup') { - commit('wizard/model$delete', '/resources/kubedbComRabbitMQ/spec/init/script') - - // create a new stashAppscodeComRestoreSession_init if there is no stashAppscodeComRestoreSession_init property - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - const dbName = getValue(model, '/metadata/release/name') + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - }) + const resources = (resp && resp.data && resp.data.items) || [] - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, + 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 [] } } -} - -// // for script -function initVolumeType({ getValue, model }) { - const configMap = getValue(model, '/resources/kubedbComRabbitMQ/spec/init/script/configMap/name') - const secret = getValue(model, '/resources/kubedbComRabbitMQ/spec/init/script/secret/secretName') - if (configMap) return 'configMap' - else if (secret) return 'secret' - else return undefined -} + async function getNamespacedResourceList( + axios, + storeGet, + { namespace, group, version, resource }, + ) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function onVolumeTypeChange({ commit, getValue, discriminator, model }) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - if (sourceVolumeType === 'configMap') { - // add configMap object and delete secret object - commit('wizard/model$delete', '/resources/kubedbComRabbitMQ/spec/init/script/secret') + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` - if (!valueExists(model, getValue, '/resources/kubedbComRabbitMQ/spec/init/script/configMap')) { - commit('wizard/model$update', { - path: '/resources/kubedbComRabbitMQ/spec/init/script/configMap', - value: { - name: '', + let ans = [] + try { + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, }, }) - } - } else if (sourceVolumeType === 'secret') { - // delete configMap object and add secret object - commit('wizard/model$delete', '/resources/kubedbComRabbitMQ/spec/init/script/configMap') - if (!valueExists(model, getValue, '/resources/kubedbComRabbitMQ/spec/init/script/secret')) { - commit('wizard/model$update', { - path: '/resources/kubedbComRabbitMQ/spec/init/script/secret', - value: { - secretName: '', - }, - }) + const items = (resp && resp.data && resp.data.items) || [] + ans = items + } catch (e) { + console.log(e) } - } -} -function showInitializationForm({ getValue, discriminator, watchDependency }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - watchDependency('discriminator#/prePopulateDatabase') - return prePopulateDatabase === 'yes' -} - -function showScriptOrStashForm({ getValue, discriminator, watchDependency }, value) { - const dataSource = getValue(discriminator, '/dataSource') - watchDependency('discriminator#/dataSource') - return dataSource === value -} - -function showConfigMapOrSecretName({ getValue, discriminator, watchDependency }, value) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - watchDependency('discriminator#/sourceVolumeType') - return sourceVolumeType === value -} - -// for stash backup -function initializeNamespace({ getValue, model }) { - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} - -function showRepositorySelectOrCreate({ getValue, discriminator, watchDependency }, value) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - return repositoryChoise === value -} - -function onInitRepositoryChoiseChange({ getValue, discriminator, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - if (repositoryChoise === 'select') { - // delete stashAppscodeComRepository_init_repo from model - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else if (repositoryChoise === 'create') { - // add stashAppscodeComRepository_init_repo to model - commit('wizard/model$update', { - path: 'resources/stashAppscodeComRepository_init_repo', - value: stashAppscodeComRepository_init_repo, - }) - - const repositoryName = `${getValue(model, '/metadata/release/name')}-init-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: repositoryName, - }) + return ans } -} -function initCustomizeRestoreJobRuntimeSettings({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} + /****** Monitoring *********/ -function initCustomizeRestoreJobRuntimeSettingsForBackup({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function onCustomizeRestoreJobRuntimeSettingsChange({ commit, getValue, discriminator, model }) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - value: restoreSessionInitRunTimeSettings, - }) - } + function showMonitoringSection() { + // watchDependency('discriminator#/enableMonitoring') + const configureStatus = getValue(discriminator, '/enableMonitoring') + return configureStatus } -} -function onCustomizeRestoreJobRuntimeSettingsChangeForBackup({ - commit, - getValue, - discriminator, - model, -}) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - ) { - // set new value + function onEnableMonitoringChange() { + const configureStatus = getValue(discriminator, '/enableMonitoring') + if (configureStatus) { commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', + path: '/resources/kubedbComRabbitMQ/spec/monitor', value: {}, force: true, }) + } else { + commit('wizard/model$delete', '/resources/kubedbComRabbitMQ/spec/monitor') } - } -} - -function showRuntimeForm({ discriminator, getValue, watchDependency }, value) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - watchDependency('discriminator#/customizeRestoreJobRuntimeSettings') - return customizeRestoreJobRuntimeSettings === value -} - -async function getImagePullSecrets({ getValue, model, watchDependency, axios, storeGet }) { - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - - let resources = await getNamespacedResourceList(axios, storeGet, { - namespace, - group: 'core', - version: 'v1', - resource: 'secrets', - }) - - resources = resources.filter((item) => { - const validType = ['kubernetes.io/dockerconfigjson'] - return validType.includes(item.type) - }) - - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: { name: name }, - } - }) -} - -// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// FOR Backup Configuration -// schedule bakcup - -function getBackupConfigsAndAnnotations(getValue, model) { - const stashAppscodeComBackupConfiguration = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration', - ) - const kubedbComRabbitMQAnnotations = - getValue(model, '/resources/kubedbComRabbitMQ/metadata/annotations') || {} - - const isBluePrint = Object.keys(kubedbComRabbitMQAnnotations).some( - (k) => - k === 'stash.appscode.com/backup-blueprint' || - k === 'stash.appscode.com/schedule' || - k.startsWith('params.stash.appscode.com/'), - ) - - return { - stashAppscodeComBackupConfiguration, - isBluePrint, + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: configureStatus ? 'warning' : 'none', + force: true, + }) } -} - -function deleteKubeDbComRabbitMQDbAnnotation(getValue, model, commit) { - const annotations = getValue(model, '/resources/kubedbComRabbitMQ/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/kubedbComRabbitMQ/metadata/annotations', - value: filteredAnnotations, - }) -} -function addKubeDbComRabbitMQDbAnnotation(getValue, model, commit, key, value, force) { - const annotations = getValue(model, '/resources/kubedbComRabbitMQ/metadata/annotations') || {} - - if (annotations[key] === undefined) { - annotations[key] = value - } else if (force) { - annotations[key] = value + function showCustomizeExporterSection() { + // watchDependency('discriminator#/customizeExporter') + const configureStatus = getValue(discriminator, '/customizeExporter') + return configureStatus } - commit('wizard/model$update', { - path: '/resources/kubedbComRabbitMQ/metadata/annotations', - value: annotations, - force: true, - }) -} - -function initScheduleBackupForEdit({ getValue, model, setDiscriminatorValue }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function initScheduleBackup({ getValue, model }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function onScheduleBackupChange({ commit, getValue, discriminator, model }) { - 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 kubedbComRabbitMQ annotation - deleteKubeDbComRabbitMQDbAnnotation(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 - ) { + function onCustomizeExporterChange() { + const configureStatus = getValue(discriminator, '/customizeExporter') + if (configureStatus) { commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration', - value: stashAppscodeComBackupConfiguration, - }) - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, + path: '/resources/kubedbComRabbitMQ/spec/monitor/prometheus/exporter', + value: {}, force: true, }) + } else { + commit('wizard/model$delete', '/resources/kubedbComRabbitMQ/spec/monitor/prometheus/exporter') } } -} - -// backup form -function showBackupForm({ getValue, discriminator, watchDependency }) { - const scheduleBackup = getValue(discriminator, '/scheduleBackup') - watchDependency('discriminator#/scheduleBackup') - if (scheduleBackup === 'yes') return true - else return false -} + function isValueExistInModel(path) { + const modelValue = getValue(model, path) || null + return !!modelValue + } -// invoker form -function initBackupInvoker({ getValue, model }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) + // function onNamespaceChange() { + // const namespace = getValue(model, '/metadata/release/namespace') + // const agent = getValue(model, '/resources/kubedbComRabbitMQ/spec/monitor/agent') + // if (agent === 'prometheus.io') { + // commit('wizard/model$update', { + // path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + // value: [namespace], + // force: true, + // }) + // } + // } - if (stashAppscodeComBackupConfiguration) return 'backupConfiguration' - else if (isBluePrint) return 'backupBlueprint' - else return undefined -} + function onLabelChange() { + const labels = getValue(model, '/resources/kubedbComRabbitMQ/spec/metadata/labels') -function onBackupInvokerChange({ getValue, discriminator, commit, model }) { - const backupInvoker = getValue(discriminator, '/backupInvoker') + const agent = getValue(model, '/resources/kubedbComRabbitMQ/spec/monitor/agent') - if (backupInvoker === 'backupConfiguration') { - // delete annotation and create backup config object - deleteKubeDbComRabbitMQDbAnnotation(getValue, model, commit) - const dbName = getValue(model, '/metadata/release/name') - - if (!valueExists(model, getValue, '/resources/stashAppscodeComBackupConfiguration')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration', - value: stashAppscodeComBackupConfiguration, - }) + if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, + path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', + value: labels, force: true, }) } - } else if (backupInvoker === 'backupBlueprint') { - // delete backup configuration object and create the annotation - commit('wizard/model$delete', '/resources/stashAppscodeComBackupConfiguration') - addKubeDbComRabbitMQDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/backup-blueprint', - '', - ) } -} -function showInvokerForm({ getValue, discriminator, watchDependency }, value) { - const backupInvoker = getValue(discriminator, '/backupInvoker') - watchDependency('discriminator#/backupInvoker') - - return backupInvoker === value -} - -// backup configuration form -function initalizeTargetReferenceName({ getValue, model, watchDependency }) { - const databaseName = getValue(model, '/metadata/release/name') - watchDependency('model#/metadata/release/name') - - return databaseName -} - -// restore session repository -function setInitialRestoreSessionRepo({ getValue, model }) { - const value = getValue(model, 'resources/stashAppscodeComRepository_init_repo') - return value ? 'create' : 'select' -} - -// backup config repository -function initRepositoryChoise({ getValue, model }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - - if (stashAppscodeComRepository_repo) return 'create' - else return 'select' -} - -function initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' - setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) - - return repoInitialSelectionStatus -} - -function onRepositoryChoiseChange({ getValue, discriminator, watchDependency, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - if (repositoryChoise === 'select') { - // delete the stashAppscodeComRepository_repo - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') - } else if (repositoryChoise === 'create') { - // create new stashAppscodeComRepository_repo - if (!valueExists(model, getValue, '/resources/stashAppscodeComRepository_repo')) { + function onAgentChange() { + const agent = getValue(model, '/resources/kubedbComRabbitMQ/spec/monitor/agent') + if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: '/resources/stashAppscodeComRepository_repo', - value: stashAppscodeComRepository_repo, - }) - const repositoryName = `${getValue(model, '/metadata/release/name')}-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, + path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', + value: [], + force: true, }) - } - } -} - -function onRepositoryNameChange({ getValue, model, commit }) { - const repositoryName = getValue(model, 'resources/stashAppscodeComRepository_repo/metadata/name') - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) -} - -// backup blueprint form -function getMongoAnnotations(getValue, model) { - const annotations = getValue(model, '/resources/kubedbComRabbitMQ/metadata/annotations') - return { ...annotations } || {} -} - -function initFromAnnotationValue({ getValue, model }, key) { - const annotations = getMongoAnnotations(getValue, model) - return annotations[key] -} - -function onBackupBlueprintNameChange({ getValue, discriminator, commit, model }) { - const backupBlueprintName = getValue(discriminator, '/backupBlueprintName') - addKubeDbComRabbitMQDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/backup-blueprint', - backupBlueprintName, - true, - ) -} - -function onBackupBlueprintScheduleChange({ getValue, discriminator, commit, model }) { - const backupBlueprintSchedule = getValue(discriminator, '/schedule') - addKubeDbComRabbitMQDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/schedule', - backupBlueprintSchedule, - true, - ) -} -function initFromAnnotationKeyValue({ getValue, model }, prefix) { - const annotations = getMongoAnnotations(getValue, model) - const newOb = {} - Object.keys(annotations).forEach((key) => { - if (key.startsWith(prefix)) { - const newKey = key.replace(prefix, '') - newOb[newKey] = annotations[key] + onNamespaceChange() + onLabelChange() + } else { + commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') } - }) - return newOb -} - -function onTaskParametersChange({ getValue, discriminator, model, commit }) { - const taskParameters = getValue(discriminator, '/taskParameters') - - const taskParamterKeys = Object.keys(taskParameters).map( - (tp) => `params.stash.appscode.com/${tp}`, - ) - const oldAnnotations = getValue(model, '/resources/kubedbComRabbitMQ/metadata/annotations') || {} - const newAnnotations = {} - - const filteredAnnotationKeys = Object.keys(oldAnnotations).filter( - (key) => !taskParamterKeys.includes(key) && !key.startsWith('params.stash.appscode.com/'), - ) - - filteredAnnotationKeys.forEach((key) => { - newAnnotations[key] = oldAnnotations[key] - }) - - Object.keys(taskParameters).forEach((tpk) => { - newAnnotations[`params.stash.appscode.com/${tpk}`] = taskParameters[tpk] - }) - - commit('wizard/model$update', { - path: '/resources/kubedbComRabbitMQ/metadata/annotations', - value: newAnnotations, - }) -} - -function isValueExistInModel({ model, getValue }, path) { - const modelValue = getValue(model, path) - return !!modelValue -} - -function onNamespaceChange({ commit, model, getValue }) { - const namespace = getValue(model, '/metadata/release/namespace') - const agent = getValue(model, '/resources/kubedbComRabbitMQ/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', - value: [namespace], - force: true, - }) } -} -function onLabelChange({ commit, model, getValue }) { - const labels = getValue(model, '/resources/kubedbComRabbitMQ/spec/metadata/labels') + 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 agent = getValue(model, '/resources/kubedbComRabbitMQ/spec/monitor/agent') + const isKube = !!storeGet('/route/params/actions') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) + if (isKube) return pathConstructedForKubedb + else + return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/rabbitmqopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` } -} - -function onNameChange({ commit, model, getValue }) { - const dbName = getValue(model, '/metadata/release/name') - const agent = getValue(model, '/resources/kubedbComRabbitMQ/spec/monitor/agent') - - const labels = getValue(model, '/resources/kubedbComRabbitMQ/spec/metadata/labels') - - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) + function onNamespaceChange() { + const namespace = getValue( + model, + '/resources/autoscalingKubedbComRabbitMQAutoscaler/metadata/namespace', + ) + if (!namespace) { + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/databaseRef/name', + ) + } } - const scheduleBackup = getValue(model, '/resources/stashAppscodeComBackupConfiguration') - - if (scheduleBackup) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_repo') - if (creatingNewRepo) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: `${dbName}-repo`, - force: true, - }) + function setValueFrom() { + if (isConfigMapTypeValueFrom()) { + return 'configMap' + } else if (isSecretTypeValueFrom()) { + return 'secret' + } else { + return 'input' } } - const prePopulateDatabase = getValue(model, '/resources/stashAppscodeComRestoreSession_init') - - if (prePopulateDatabase) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_init_repo') - if (creatingNewRepo) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: `${dbName}-init-repo`, - force: true, - }) + 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, + }) } } - // to reset configSecret name field - const hasSecretConfig = getValue(model, '/resources/secret_config') - if (hasSecretConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComRabbitMQ/spec/configSecret/name', - value: `${dbName}-config`, - force: true, - }) - } + // function isEqualToValueFromType(value) { + // //watchDependency('discriminator#/valueFromType') + // const valueFrom = getValue(discriminator, '/valueFromType') + // return valueFrom === value + // } - // to reset shard configSecret name field - const hasSecretShardConfig = getValue(model, '/resources/secret_shard_config') - if (hasSecretShardConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComRabbitMQ/spec/shardTopology/shard/configSecret/name', - value: `${dbName}-shard-config`, - force: true, - }) - } + async function resourceNames(group, version, resource) { + const namespace = getValue(model, '/metadata/release/namespace') + // watchDependency('model#/metadata/release/namespace') - // to reset shard configSecret name field - const hasSecretConfigServerConfig = getValue(model, '/resources/secret_configserver_config') - if (hasSecretConfigServerConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComRabbitMQ/spec/shardTopology/configServer/configSecret/name', - value: `${dbName}-configserver-config`, - force: true, - }) - } - - // to reset mongos configSecret name field - const hasSecretMongosConfig = getValue(model, '/resources/secret_mongos_config') - if (hasSecretMongosConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComRabbitMQ/spec/shardTopology/mongos/configSecret/name', - value: `${dbName}-mongos-config`, - force: true, + let resources = await getNamespacedResourceList(axios, storeGet, { + namespace, + group, + version, + resource, }) - } -} -function returnFalse() { - return false -} + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } -function onAgentChange({ commit, model, getValue }) { - const agent = getValue(model, '/resources/kubedbComRabbitMQ/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', - value: [], - force: true, + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } }) - - onNamespaceChange({ commit, model, getValue }) - onLabelChange({ commit, model, getValue }) - } else { - commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') } -} - -/************************************* Database Secret Section ********************************************/ - -function getCreateAuthSecret({ model, getValue }) { - const authSecret = getValue(model, '/resources/kubedbComRabbitMQ/spec/authSecret') - - return !authSecret -} - -function showExistingSecretSection({ getValue, watchDependency, discriminator }) { - watchDependency('discriminator#/createAuthSecret') - const hasAuthSecretName = getValue(discriminator, '/createAuthSecret') - return !hasAuthSecretName -} -function showPasswordSection({ getValue, watchDependency, discriminator }) { - return !showExistingSecretSection({ - getValue, - watchDependency, - discriminator, - }) -} + 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/kubedbComRabbitMQ/spec/monitor/prometheus/exporter/env/${index}/valueFrom/configMapKeyRef/name`, + ) -function setAuthSecretPassword({ model, getValue }) { - const encodedPassword = getValue(model, '/resources/secret_auth/data/password') - return encodedPassword ? decodePassword({}, encodedPassword) : '' -} + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/configMapKeyRef/name') -function onAuthSecretPasswordChange({ getValue, discriminator, commit }) { - const stringPassword = getValue(discriminator, '/password') + if (!configMapName) return [] - if (stringPassword) { - commit('wizard/model$update', { - path: '/resources/secret_auth/data/password', - value: encodePassword({}, stringPassword), - force: true, - }) - commit('wizard/model$update', { - path: '/resources/secret_auth/data/username', - value: encodePassword({}, 'root'), - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/secret_auth') - } -} - -function disableInitializationSection({ model, getValue, watchDependency }) { - const initialized = getValue(model, '/resources/kubedbComRabbitMQ/spec/init/initialized') - watchDependency('model#/resources/kubedbComRabbitMQ/spec/init/initialized') - return !!initialized -} + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/configmaps/${configMapName}`, + ) -// eslint-disable-next-line no-empty-pattern -function encodePassword({}, value) { - return btoa(value) -} + const configMaps = (resp && resp.data && resp.data.data) || {} -// eslint-disable-next-line no-empty-pattern -function decodePassword({}, value) { - return atob(value) -} + const configMapKeys = Object.keys(configMaps).map((item) => ({ + text: item, + value: item, + })) -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/resources/kubedbComRabbitMQ/spec/authSecret') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/resources/secret_auth') + return configMapKeys + } catch (e) { + console.log(e) + return [] + } } -} -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') + 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') - if (owner && cluster && namespace) { try { const resp = await axios.get( `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, { params: { - filter: { - items: { - data: { username: null, password: null }, - metadata: { name: null }, - type: null, - }, - }, + filter: { items: { metadata: { name: null }, type: null } }, }, }, ) @@ -1393,838 +375,641 @@ async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) const secrets = (resp && resp.data && resp.data.items) || [] const filteredSecrets = secrets.filter((item) => { - const validType = [ - 'kubernetes.io/service-account-token', - 'Opaque', - 'kubernetes.io/basic-auth', - ] + 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 [] -} - -//////////////////// custom config ///////////////// -function onConfigurationSourceChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSource') - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_config') - } else { - const value = getValue(model, '/resources/secret_config') - if (!value) { - commit('wizard/model$update', { - path: '/resources/secret_config', - value: {}, - force: true, + item.value = name + return true }) + return filteredSecrets + } catch (e) { + console.log(e) + return [] } - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - - commit('wizard/model$update', { - path: '/resources/kubedbComRabbitMQ/spec/configSecret/name', - value: configSecretName, - force: true, - }) } -} -function onConfigurationChange({ getValue, commit, discriminator, model }) { - const value = getValue(discriminator, '/configuration') - commit('wizard/model$update', { - path: '/resources/secret_config/stringData/user.conf', - value: value, - force: true, - }) - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComRabbitMQ/spec/configSecret/name', - value: configSecretName, - force: true, - }) -} + 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/kubedbComRabbitMQ/spec/monitor/prometheus/exporter/env/${index}/valueFrom/secretKeyRef/name`, + ) -function onConfigurationChangeEdit({ getValue, commit, discriminator, model }) { - const value = getValue(discriminator, '/configuration') - - commit('wizard/model$update', { - path: '/resources/secret_config/data/rabbitmq.ini', - value: btoa(value), - force: true, - }) - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComRabbitMQ/spec/configSecret/name', - value: configSecretName, - force: true, - }) -} + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/secretKeyRef/name') -function setConfigurationSource({ model, getValue }) { - const modelValue = getValue(model, '/resources/secret_config') - if (modelValue) { - return 'create-new-config' - } - return 'use-existing-config' -} + if (!secretName) return [] -function setSecretConfigNamespace({ getValue, model, watchDependency }) { - watchDependency('model#/metadata/release/namespace') - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets/${secretName}`, + ) -function setConfiguration({ model, getValue }) { - return getValue(model, '/resources/secret_config/stringData/user.conf') -} + const secret = (resp && resp.data && resp.data.data) || {} -function setConfigurationForEdit({ model, getValue }) { - const value = getValue(model, '/resources/secret_config/data/rabbitmq.ini') - return atob(value) -} + const secretKeys = Object.keys(secret).map((item) => ({ + text: item, + value: item, + })) -function setConfigurationFiles({ model, getValue }) { - const value = getValue(model, '/resources/secret_config/data/user.conf') - return atob(value) -} + return secretKeys + } catch (e) { + console.log(e) + return [] + } + } -function onSetCustomConfigChange({ discriminator, getValue, commit }) { - const value = getValue(discriminator, '/setCustomConfig') + // storage - if (value === 'no') { - commit('wizard/model$delete', '/resources/kubedbComRabbitMQ/spec/configSecret') - commit('wizard/model$delete', '/resources/secret_config') + 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 getOpsRequestUrl({ storeGet, model, getValue, mode }, 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 + `/create-opsrequest-${reqType.toLowerCase()}?namespace=${namespace}` - - if (mode === 'standalone-step') return pathConstructedForKubedb - else - return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/rabbitmqopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` -} + // compute -const getAppbinding = async ({ axios, storeGet, getValue, watchDependency, rootModel }) => { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + let autoscaleType = '' + let dbDetails = {} + let instance = '' - const group = 'appcatalog.appscode.com' - const version = 'v1alpha1' - const resource = 'appbindings' + function isConsole() { + const isKube = isKubedb() - watchDependency('rootModel#/databaseRef/namespace') + if (isKube) { + const dbName = storeGet('/route/params/name') || '' + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComRabbitMQAutoscaler/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/autoscalingKubedbComRabbitMQAutoscaler/metadata/name', + value: modifiedName, + force: true, + }) + const namespace = storeGet('/route/query/namespace') || '' + if (namespace) { + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComRabbitMQAutoscaler/metadata/namespace', + value: namespace, + force: true, + }) + } + } - const namespace = getValue(rootModel, '/databaseRef/namespace') + return !isKube + } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + function isKubedb() { + return !!storeGet('/route/params/actions') + } - const resources = (resp && resp.data && resp.data.items) || [] + function showOpsRequestOptions() { + if (isKubedb() === true) return true + // watchDependency('model#/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/databaseRef/name') + // watchDependency('discriminator#/autoscalingType') + return ( + !!getValue( + model, + '/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/databaseRef/name', + ) && !!getValue(discriminator, '/autoscalingType') + ) + } - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return resources -} + async function getNamespaces() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, + }) -function onRefChange({ discriminator, getValue, commit }) { - const ref = getValue(discriminator, '/pgRef') || {} - commit('wizard/model$update', { - path: '/resources/kubedbComRabbitMQ/spec/database/databaseRef/name', - value: ref.name || '', - force: true, - }) - commit('wizard/model$update', { - path: '/resources/kubedbComRabbitMQ/spec/database/databaseRef/namespace', - value: ref.namespace || '', - force: true, - }) -} + const resources = (resp && resp.data && resp.data.items) || [] -async function getAppBindings({ axios, storeGet }, type) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const queryParams = { - filter: { - items: { - metadata: { name: null, namespace: null }, - spec: { type: null }, - }, - }, + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) } - try { + + async function getDbs() { + // watchDependency('model#/resources/autoscalingKubedbComRabbitMQAutoscaler/metadata/namespace') + const namespace = getValue( + model, + '/resources/autoscalingKubedbComRabbitMQAutoscaler/metadata/namespace', + ) + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/appcatalog.appscode.com/v1alpha1/appbindings`, - queryParams, + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, ) + const resources = (resp && resp.data && resp.data.items) || [] - const fileredResources = resources - .filter((item) => item.spec?.type === `kubedb.com/${type}`) - .map((item) => { - const name = item.metadata?.name || '' - const namespace = item.metadata?.namespace || '' - return { - text: `${namespace}/${name}`, - value: { - name: name, - namespace: namespace, - }, - } - }) - return fileredResources - } catch (e) { - console.log(e) - return [] + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) } -} -///////////////////////// Autoscaler /////////////////// -let autoscaleType = '' -let dbDetails = {} - -function isConsole({ storeGet, commit }) { - const isKube = isKubedb({ storeGet }) + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } + + async function getDbDetails() { + const owner = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + const namespace = + storeGet('/route/query/namespace') || + getValue(model, '/resources/autoscalingKubedbComRabbitMQAutoscaler/metadata/namespace') || + '' + const name = + storeGet('/route/params/name') || + getValue(model, '/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/databaseRef/name') || + '' + + if (namespace && name) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/rabbitmqs/${name}`, + ) + dbDetails = resp.data || {} + setDiscriminatorValue('/dbDetails', true) + } catch (e) { + console.log(e) + } + } - if (isKube) { - const dbName = storeGet('/route/params/name') || '' commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/databaseRef/name', - value: dbName, + path: `/metadata/release/name`, + value: name, + force: true, + }) + commit('wizard/model$update', { + path: `/metadata/release/namespace`, + value: namespace, + force: true, + }) + commit('wizard/model$update', { + path: `/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/databaseRef/name`, + value: name, 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/autoscalingKubedbComRabbitMQAutoscaler/metadata/name', - value: modifiedName, + path: `/resources/autoscalingKubedbComRabbitMQAutoscaler/metadata/labels`, + value: dbDetails.metadata.labels, force: true, }) - const namespace = storeGet('/route/query/namespace') || '' - if (namespace) { + } + + function initMetadata() { + const dbName = + getValue(model, '/resources/autoscalingKubedbComRabbitMQAutoscaler/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/autoscalingKubedbComRabbitMQAutoscaler/metadata/namespace', - value: namespace, + path: '/resources/autoscalingKubedbComRabbitMQAutoscaler/metadata/name', + value: modifiedName, force: true, }) - } + + // delete the other type object from model + if (type === 'compute') + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/storage', + ) + if (type === 'storage') + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/compute', + ) } - return !isKube -} + function onNamespaceChange() { + const namespace = getValue( + model, + '/resources/autoscalingKubedbComRabbitMQAutoscaler/metadata/namespace', + ) + if (!namespace) { + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/databaseRef/name', + ) + } + } -function isKubedb({ storeGet }) { - return !!storeGet('/route/params/actions') -} + 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 showOpsRequestOptions({ model, getValue, watchDependency, storeGet, discriminator }) { - if (isKubedb({ storeGet }) === true) return true - watchDependency('model#/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/databaseRef/name') - watchDependency('discriminator#/autoscalingType') - return ( - !!getValue(model, '/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/databaseRef/name') && - !!getValue(discriminator, '/autoscalingType') - ) -} + function isNodeTopologySelected() { + // watchDependency( + // 'model#/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/compute/nodeTopology/name', + // ) + const nodeTopologyName = + getValue( + model, + '/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/compute/nodeTopology/name', + ) || '' + return !!nodeTopologyName.length + } -async function getNamespaces({ axios, storeGet }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function setControlledResources(type) { + const list = ['cpu', 'memory'] + const path = `/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/compute/${type}/controlledResources` + commit('wizard/model$update', { + path: path, + value: list, + force: true, + }) + return list + } - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + function setTrigger(path) { + let value = getValue(model, `/resources/${path}`) + return value === 'On' + } - const resources = (resp && resp.data && resp.data.items) || [] + function onTriggerChange(type) { + const trigger = getValue(discriminator, `/${type}/trigger`) + const commitPath = `/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/${type}/trigger` - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + commit('wizard/model$update', { + path: commitPath, + value: trigger ? 'On' : 'Off', + force: true, + }) + } -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - watchDependency('model#/resources/autoscalingKubedbComRabbitMQAutoscaler/metadata/namespace') - const namespace = getValue( - model, - '/resources/autoscalingKubedbComRabbitMQAutoscaler/metadata/namespace', - ) - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function setApplyToIfReady() { + return 'IfReady' + } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + async function fetchTopologyMachines() { + const annotations = + getValue(model, '/resources/autoscalingKubedbComRabbitMQAutoscaler/metadata/annotations') || + {} + instance = annotations['kubernetes.io/instance-type'] - const resources = (resp && resp.data && resp.data.items) || [] + 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) - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, + const nodeGroups = resp.data?.spec?.nodeGroups || [] + setDiscriminatorValue('/topologyMachines', nodeGroups) + return nodeGroups + } catch (e) { + console.log(e) + return [] + } } - }) -} + } -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function setAllowedMachine(minmax) { + const mx = instance?.includes(',') ? instance.split(',')[1] : '' + const mn = instance?.includes(',') ? instance.split(',')[0] : '' + const machineName = minmax === 'min' ? mn : mx -async function getDbDetails({ commit, setDiscriminatorValue, axios, storeGet, getValue, model }) { - const owner = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - const namespace = - storeGet('/route/query/namespace') || - getValue(model, '/resources/autoscalingKubedbComRabbitMQAutoscaler/metadata/namespace') || - '' - const name = - storeGet('/route/params/name') || - getValue(model, '/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/databaseRef/name') || - '' - - if (namespace && name) { - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/rabbitmqs/${name}`, - ) - dbDetails = resp.data || {} - setDiscriminatorValue('/dbDetails', true) - } catch (e) { - console.log(e) + // 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: '', } } - commit('wizard/model$update', { - path: `/metadata/release/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/metadata/release/namespace`, - value: namespace, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/databaseRef/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComRabbitMQAutoscaler/metadata/labels`, - value: dbDetails.metadata.labels, - force: true, - }) -} + function getMachines(minmax) { + // watchDependency('discriminator#/topologyMachines') + const depends = minmax === 'min' ? 'max' : 'min' + const dependantPath = `/allowedMachine-${depends}` -async function dbTypeEqualsTo({ watchDependency, commit }, type) { - watchDependency('discriminator#/dbDetails') + // watchDependency(`discriminator#${dependantPath}`) + const dependantMachineObj = getValue(discriminator, dependantPath) + const dependantMachine = dependantMachineObj?.machine || '' - const { spec } = dbDetails || {} - const { topology } = spec || {} - let verd = '' - if (topology) verd = 'topology' - else { - verd = 'combined' - } - clearSpecModel({ commit }, verd) - return type === verd && spec -} + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] -function clearSpecModel({ commit }, dbtype) { - if (dbtype === 'standalone') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/${autoscaleType}/cluster`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/${autoscaleType}/sentinel`, - ) - } else if (dbtype === 'cluster') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/${autoscaleType}/sentinel`, - ) - } else if (dbtype === 'sentinel') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/${autoscaleType}/cluster`, - ) - } -} + const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) -function initMetadata({ getValue, discriminator, model, commit, storeGet }) { - const dbName = - getValue(model, '/resources/autoscalingKubedbComRabbitMQAutoscaler/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/autoscalingKubedbComRabbitMQAutoscaler/metadata/name', - value: modifiedName, - force: true, + // 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, + }, + } }) - // delete the other type object from model - if (type === 'compute') - commit('wizard/model$delete', '/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/storage') - if (type === 'storage') - commit('wizard/model$delete', '/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/compute') -} - -function onNamespaceChange({ model, getValue, commit }) { - const namespace = getValue( - model, - '/resources/autoscalingKubedbComRabbitMQAutoscaler/metadata/namespace', - ) - if (!namespace) { - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/databaseRef/name', + const filteredMachine = machines?.filter((item, ind) => + minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, ) + + return dependantIndex === -1 ? machines : filteredMachine } -} -function ifScalingTypeEqualsTo( - { storeGet, watchDependency, getValue, discriminator, model }, - type, -) { - watchDependency('discriminator#/autoscalingType') - watchDependency('model#/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/databaseRef/name') - - const operation = storeGet('/route/params/actions') || '' - if (operation.length) { - const splitOp = operation.split('-') - if (splitOp.length > 2) autoscaleType = splitOp[2] - } else autoscaleType = getValue(discriminator, '/autoscalingType') || '' - const isDatabaseSelected = !!getValue( - model, - '/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/databaseRef/name', - ) - return autoscaleType === type && isDatabaseSelected -} + function hasAnnotations() { + const annotations = + getValue(model, '/resources/autoscalingKubedbComRabbitMQAutoscaler/metadata/annotations') || + {} + const instance = annotations['kubernetes.io/instance-type'] -async function fetchNodeTopology({ axios, storeGet }) { - 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 !!instance } - return [] -} -function isNodeTopologySelected({ watchDependency, model, getValue }) { - watchDependency( - 'model#/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/compute/nodeTopology/name', - ) - const nodeTopologyName = - getValue( - model, - '/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/compute/nodeTopology/name', - ) || '' - return !!nodeTopologyName.length -} + function hasNoAnnotations() { + return !hasAnnotations() + } -function setControlledResources({ commit }, type) { - const list = ['cpu', 'memory'] - const path = `/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/compute/${type}/controlledResources` - commit('wizard/model$update', { - path: path, - value: list, - force: true, - }) - return list -} + function onMachineChange(type) { + const annoPath = '/resources/autoscalingKubedbComRabbitMQAutoscaler/metadata/annotations' + const annotations = getValue(model, annoPath) || {} + const instance = annotations['kubernetes.io/instance-type'] -function setTrigger({ model, getValue }, path) { - let value = getValue(model, `/resources/${path}`) - if (value) return value - return 'On' -} + // 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 -function setApplyToIfReady() { - return 'IfReady' -} + // 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/autoscalingKubedbComRabbitMQAutoscaler/spec/compute/${type}` -function handleUnit({ commit, model, getValue }, 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)) { + if (minMachine && maxMachine && instance !== minMaxMachine) { commit('wizard/model$update', { - path: `/resources/${path}`, - value: updatedValue, + path: `${allowedPath}/maxAllowed`, + value: maxMachineAllocatable, force: true, }) - } - } else { - if (!isNaN(value)) { - value += 'Gi' commit('wizard/model$update', { - path: `/resources/${path}`, - value: value, + path: `${allowedPath}/minAllowed`, + value: minMachineAllocatable, + force: true, + }) + commit('wizard/model$update', { + path: annoPath, + value: { ...annotations }, force: true, }) } } -} -function isBindingAlreadyOn({ model, getValue }) { - const value = getValue(model, '/resources') - const keys = Object.keys(value) - isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComRabbitMQBinding') - return isExposeBinding -} + // binding -async function addOrRemoveBinding({ commit, model, getValue, discriminator }) { - const value = getValue(discriminator, `/binding`) - const dbName = getValue(model, '/metadata/release/name') - const dbNamespace = getValue(model, '/metadata/release/namespace') - const labels = getValue(model, '/resources/kubedbComRabbitMQ/metadata/labels') - const bindingValues = { - apiVersion: 'catalog.appscode.com/v1alpha1', - kind: 'RabbitMQBinding', - metadata: { - labels, - name: dbName, - namespace: dbNamespace, - }, - spec: { - sourceRef: { + 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/kubedbComRabbitMQ/metadata/labels') + const bindingValues = { + apiVersion: 'catalog.appscode.com/v1alpha1', + kind: 'PostgresBinding', + metadata: { + labels, name: dbName, namespace: dbNamespace, }, - }, - } - - if (value) { - await commit('wizard/model$update', { - path: '/resources/catalogAppscodeComRabbitMQBinding', - value: bindingValues, - force: true, - }) - } else { - await commit('wizard/model$delete', '/resources/catalogAppscodeComRabbitMQBinding') - } -} - -async function fetchTopologyMachines({ axios, getValue, storeGet, model, setDiscriminatorValue }) { - const instance = hasAnnotations({ model, getValue }) - - 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) + spec: { + sourceRef: { + name: dbName, + namespace: dbNamespace, + }, + }, + } - const nodeGroups = resp.data?.spec?.nodeGroups || [] - setDiscriminatorValue('/topologyMachines', nodeGroups) - return nodeGroups - } catch (e) { - console.log(e) - return [] + if (value) { + commit('wizard/model$update', { + path: '/resources/catalogAppscodeComRabbitMQBinding', + value: bindingValues, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/catalogAppscodeComRabbitMQBinding') } } -} - -function setAllowedMachine({ model, getValue }, minmax) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComRabbitMQAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - const mx = instance?.includes(',') ? instance.split(',')[1] : '' - const mn = instance?.includes(',') ? instance.split(',')[0] : '' - - if (minmax === 'min') return mn - else return mx -} - -async function getMachines({ getValue, watchDependency, discriminator }, minmax) { - watchDependency('discriminator#/topologyMachines') - const depends = minmax === 'min' ? 'max' : 'min' - const dependantPath = `/allowedMachine-${depends}` - watchDependency(`discriminator#${dependantPath}`) - const dependantMachine = getValue(discriminator, dependantPath) - - const nodeGroups = getValue(discriminator, '/topologyMachines') || [] - - const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) - - const machines = nodeGroups?.map((item) => { - const subText = `CPU: ${item.allocatable.cpu}, Memory: ${item.allocatable.memory}` - const text = item.topologyValue - return { text, subText, value: item.topologyValue } - }) - - const filteredMachine = machines?.filter((item, ind) => - minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, - ) + function isBindingAlreadyOn() { + const value = getValue(model, '/resources') + const keys = Object.keys(value) + const isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComRabbitMQBinding') + return isExposeBinding + } - return dependantIndex === -1 ? machines : filteredMachine -} + function returnFalse() { + return false + } -function hasAnnotations({ model, getValue }) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComRabbitMQAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] + function setValueFromDbDetails(path) { + const value = getValue(model, path) + return value + } - return !!instance -} + 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 + }) -function hasNoAnnotations({ model, getValue }) { - return !hasAnnotations({ model, getValue }) -} + if (filteredEnv.length) + commit('wizard/model$update', { + path: '/resources/kubedbComRabbitMQ/spec/monitor/prometheus/exporter/env', + value: filteredEnv, + force: true, + }) + } -function onMachineChange({ model, getValue, discriminator, commit }, type) { - const annoPath = '/resources/autoscalingKubedbComRabbitMQAutoscaler/metadata/annotations' - const annotations = getValue(model, annoPath) - const instance = annotations['kubernetes.io/instance-type'] + function initEnvArray() { + const env = getValue(model, '/resources/kubedbComRabbitMQ/spec/monitor/prometheus/exporter/env') - const minMachine = getValue(discriminator, '/allowedMachine-min') - const maxMachine = getValue(discriminator, '/allowedMachine-max') - const minMaxMachine = `${minMachine},${maxMachine}` - annotations['kubernetes.io/instance-type'] = minMaxMachine + return env || [] + } - const machines = getValue(discriminator, `/topologyMachines`) || [] - const minMachineObj = machines.find((item) => item.topologyValue === minMachine) - const maxMachineObj = machines.find((item) => item.topologyValue === maxMachine) - const minMachineAllocatable = minMachineObj?.allocatable - const maxMachineAllocatable = maxMachineObj?.allocatable - const allowedPath = `/resources/autoscalingKubedbComRabbitMQAutoscaler/spec/compute/${type}` + function isEqualToTemp(value, index) { + //watchDependency('discriminator#/valueFromType') + const valueFrom = getValue(discriminator, `/env/${index}/temp/valueFromType`) + return valueFrom === value + } - 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 initMonitoring() { + const env = + getValue(model, '/resources/kubedbComRabbitMQ/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 { - isRancherManaged, - handleUnit, - isConsole, - getNamespaces, - getDbs, - isKubedb, - getDbDetails, - dbTypeEqualsTo, - clearSpecModel, - initMetadata, - onNamespaceChange, - ifScalingTypeEqualsTo, - fetchNodeTopology, - isNodeTopologySelected, - setControlledResources, - setTrigger, - setApplyToIfReady, - showOpsRequestOptions, - isVariantAvailable, - fetchJsons, - getAppbinding, - onDatabaseModeChange, - setDatabaseMode, - disableLableChecker, - isEqualToModelPathValue, - getResources, - isEqualToDiscriminatorPath, - setValueFromModel, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - returnTrue, - returnStringYes, - setAddressType, - getRabbitMQVersions, - isEqualToDatabaseMode, - setApiGroup, - getIssuerRefsName, - hasIssuerRefName, - hasNoIssuerRefName, - setSSLMode, - showTlsConfigureSection, - onTlsConfigureChange, - getAliasOptions, - showMonitoringSection, - onEnableMonitoringChange, - showCustomizeExporterSection, - onCustomizeExporterChange, - valueExists, - onConfigurationChangeEdit, - setConfigurationForEdit, - initPrePopulateDatabase, - onPrePopulateDatabaseChange, - initDataSource, - onDataSourceChange, - initVolumeType, - onVolumeTypeChange, - showInitializationForm, - showScriptOrStashForm, - showConfigMapOrSecretName, - initializeNamespace, - showRepositorySelectOrCreate, - onInitRepositoryChoiseChange, - initCustomizeRestoreJobRuntimeSettings, - initCustomizeRestoreJobRuntimeSettingsForBackup, - onCustomizeRestoreJobRuntimeSettingsChange, - onCustomizeRestoreJobRuntimeSettingsChangeForBackup, - showRuntimeForm, - getImagePullSecrets, - getBackupConfigsAndAnnotations, - deleteKubeDbComRabbitMQDbAnnotation, - addKubeDbComRabbitMQDbAnnotation, - initScheduleBackup, - initScheduleBackupForEdit, - onScheduleBackupChange, - showBackupForm, - initBackupInvoker, - onBackupInvokerChange, - showInvokerForm, - initalizeTargetReferenceName, - setInitialRestoreSessionRepo, - initRepositoryChoise, - initRepositoryChoiseForEdit, - setConfigurationForEdit, - onRepositoryChoiseChange, - onRepositoryNameChange, - getMongoAnnotations, - initFromAnnotationValue, - onBackupBlueprintNameChange, - onBackupBlueprintScheduleChange, - initFromAnnotationKeyValue, - onTaskParametersChange, - isValueExistInModel, - onNamespaceChange, - onLabelChange, - onNameChange, - returnFalse, - onAgentChange, - getCreateAuthSecret, - showExistingSecretSection, - showPasswordSection, - setAuthSecretPassword, - onAuthSecretPasswordChange, - disableInitializationSection, - encodePassword, - decodePassword, - onCreateAuthSecretChange, - getSecrets, - onConfigurationSourceChange, - onConfigurationChange, - setConfigurationSource, - setSecretConfigNamespace, - setConfiguration, - setConfigurationFiles, - onSetCustomConfigChange, - getOpsRequestUrl, - onRefChange, - getAppBindings, - isBindingAlreadyOn, - addOrRemoveBinding, - getMachines, - setAllowedMachine, - hasAnnotations, - hasNoAnnotations, - fetchTopologyMachines, - onMachineChange, + return { + returnFalse, + isEqualToModelPathValue, + getResources, + showMonitoringSection, + onEnableMonitoringChange, + showCustomizeExporterSection, + onCustomizeExporterChange, + isValueExistInModel, + onNamespaceChange, + onLabelChange, + onAgentChange, + getOpsRequestUrl, + isConfigMapTypeValueFrom, + isSecretTypeValueFrom, + onValueFromChange, + resourceNames, + getConfigMapKeys, + getSecrets, + getSecretKeys, + isConsole, + isKubedb, + showOpsRequestOptions, + getNamespaces, + getDbs, + isRancherManaged, + getDbDetails, + initMetadata, + fetchNodeTopology, + isNodeTopologySelected, + setControlledResources, + setTrigger, + onTriggerChange, + setApplyToIfReady, + fetchTopologyMachines, + setAllowedMachine, + getMachines, + hasAnnotations, + hasNoAnnotations, + onMachineChange, + addOrRemoveBinding, + isBindingAlreadyOn, + handleUnit, + setValueFromDbDetails, + onEnvArrayChange, + initEnvArray, + isEqualToTemp, + initMonitoring, + } } diff --git a/charts/kubedbcom-redis-editor-options/ui/create-ui.yaml b/charts/kubedbcom-redis-editor-options/ui/create-ui.yaml index 6d18c8dcc7..3001789b35 100644 --- a/charts/kubedbcom-redis-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-redis-editor-options/ui/create-ui.yaml @@ -1,427 +1,401 @@ -steps: -- form: - discriminator: - bundleApiLoaded: - default: false - type: boolean - elements: - - computed: initBundle - if: returnFalse - type: label-element - - disableUnselect: true - fetch: getAdminOptions|databases/Redis/versions - if: isToggleOn|databases/Redis/versions - label: - text: labels.database.version - schema: - $ref: schema#/properties/spec/properties/admin/properties/databases/properties/Redis/properties/versions/properties/default - type: select - - computed: getDefault|databases/Redis/mode - fetch: getAdminOptions|databases/Redis/mode - hasDescription: true - if: isToggleOn|databases/Redis/mode - label: - text: labels.database.mode - schema: - $ref: schema#/properties/spec/properties/mode +step: +- type: single-step-form + loader: initBundle + elements: + - type: label-element + label: '' + subtitle: Select the Redis version you want to deploy on Kubernetes. The chosen version determines the Redis engine features, compatibility, and runtime behavior of your in-memory data store. + - disableUnselect: true + loader: getAdminOptions|databases/Redis/versions + if: + type: function + name: isToggleOn|databases/Redis/versions + label: Database Version + schema: schema/properties/spec/properties/admin/properties/databases/properties/Redis/properties/versions/properties/default + type: select + - init: + type: func + value: getDefault|databases/Redis/mode + loader: getAdminOptions|databases/Redis/mode + isHorizontal: true + if: + type: function + name: isToggleOn|databases/Redis/mode + label: Database Mode + schema: schema/properties/spec/properties/mode + type: radio + - elements: + - type: horizontal-layout + showLabels: true + elements: + - label: Shards + schema: schema/properties/spec/properties/cluster/properties/master + type: input + - label: Replica Number + schema: schema/properties/spec/properties/cluster/properties/replicas + customClass: mb-20 + type: input + if: + type: function + name: isEqualToModelPathValue|Cluster|/spec/mode + type: block-layout + - elements: + - init: + type: func + value: returnTrue + label: Sentinel Type + watcher: + func: onCreateSentinelChange + paths: + - temp/createSentinel + options: + - text: Use Existing Sentinel + value: "false" + - text: Create New Sentinel + value: "true" + schema: temp/createSentinel type: radio - - if: isEqualToModelPathValue|Cluster|/spec/mode - label: - text: labels.shards - schema: - $ref: schema#/properties/spec/properties/cluster/properties/master - type: input - - if: isEqualToModelPathValue|Cluster|/spec/mode - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/cluster/properties/replicas + - loader: getResources|core|v1|namespaces + if: + type: function + name: showSentinelNameAndNamespace + label: Namespace + schema: schema/properties/spec/properties/sentinelRef/properties/namespace + type: select + - loader: getRedisSentinels + if: + type: function + name: showSentinelNameAndNamespace + label: Name + schema: schema/properties/spec/properties/sentinelRef/properties/name + type: select + - label: Replica Number + schema: schema/properties/spec/properties/replicas type: input - - discriminator: - announce: - default: false - type: boolean - createSentinel: - default: true - type: boolean + customClass: mb-20 + if: + type: function + name: isEqualToModelPathValue|Sentinel|/spec/mode + type: block-layout + - elements: + - type: label-element + label: '' + subtitle: Select a machine profile to allocate CPU and memory resources for your in-memory data store. Choose 'custom' to manually specify resource requirements or select a predefined profile. + - type: horizontal-layout + showLabels: true elements: - - label: - text: labels.sentinel_section - type: label-element - - onChange: onCreateSentinelChange - options: - - text: options.sentinelType.existingSentinel.label - value: false - - text: options.sentinelType.customSentinel.label - value: true - schema: - $ref: discriminator#/properties/createSentinel - type: radio - - fetch: getResources|core|v1|namespaces - if: showSentinelNameAndNamespace - keepEmpty: true - label: - text: labels.namespace - schema: - $ref: schema#/properties/spec/properties/sentinelRef/properties/namespace - type: select - - allowUserDefinedOption: true - fetch: getRedisSentinels - if: showSentinelNameAndNamespace - keepEmpty: true - label: - text: labels.name - schema: - $ref: schema#/properties/spec/properties/sentinelRef/properties/name - type: select - - label: - text: labels.replicaset.number - minValue: 2 - schema: - $ref: schema#/properties/spec/properties/replicas + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: CPU + loader: setLimits|cpu + watcher: + func: setRequests|cpu + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: Memory + loader: setLimits|memory + watcher: + func: setRequests|memory + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + if: + type: function + name: notEqualToDatabaseMode|Sharded + label: Machine profile + showLabels: true + type: block-layout + - elements: + - type: horizontal-layout + showLabels: true + elements: + - loader: getAdminOptions|storageClasses + label: Storage Class + schema: schema/properties/spec/properties/admin/properties/storageClasses/properties/default + type: select + - if: + type: function + name: isNotEqualToModelPathValue|Sentinel|/spec/mode + label: Storage Size + schema: schema/properties/spec/properties/persistence/properties/size + type: input + type: block-layout + - init: + type: func + value: setAnnounce + label: Announce Redis Endpoints ? + watcher: + func: setAnnounce + paths: + - temp/announce + schema: temp/announce + type: switch + - elements: + - type: label-element + label: '' + subtitle: Configure how Redis cluster endpoints are announced to clients. Specify the announcement type (IP or hostname) and define shard endpoints for cluster mode connectivity. + - label: Type + options: + - text: ip + value: ip + - text: hostname + value: hostname + schema: schema/properties/spec/properties/cluster/properties/announce/properties/type + type: select + - type: array-item-form + element: + label: Shard Endpoints (comma-separated, e.g. "endpoint1,endpoint2,endpoint3") type: input - if: isEqualToModelPathValue|Sentinel|/spec/mode - type: single-step-form + label: Shards + schema: schema/properties/spec/properties/cluster/properties/announce/properties/shards + if: + type: function + name: showAnnounce + label: Announce + showLabels: true + type: block-layout + - description: Configure Credentials, Deployment Mode etc. + elements: - elements: - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.cpu - onChange: setRequests|cpu - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.memory - onChange: setRequests|memory - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - if: notEqualToDatabaseMode|Sharded - label: - text: labels.machine_profile - show_label: true - type: single-step-form - - fetch: getAdminOptions|storageClasses - label: - text: labels.storage.class - schema: - $ref: schema#/properties/spec/properties/admin/properties/storageClasses/properties/default + - type: label-element + label: '' + subtitle: Add custom labels and annotations to your database resources for organization, monitoring, and integration with other Kubernetes tools and services. + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/annotations + hideBlock: true + label: Labels & Annotations + showLabels: true + type: block-layout + - init: + type: func + value: getDefault|deletionPolicy + customClass: mt-20 + if: + type: function + name: isToggleOn|deletionPolicy + label: Deletion Policy + watcher: + func: setStorageClass + paths: + - schema/properties/spec/properties/deletionPolicy + options: + - description: options.deletionPolicy.delete.description + text: Delete ( Keep only database Secrets and backed up data ) + value: Delete + - description: options.deletionPolicy.halt.description + text: Halt ( Keep PVCs, database Secrets and backed up data ) + value: Halt + - description: options.deletionPolicy.wipeOut.description + text: WipeOut ( Delete everything including backed up data ) + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: DoNotTerminate ( Prevent deletion of the Redis CRD ) + value: DoNotTerminate + schema: schema/properties/spec/properties/deletionPolicy type: select - - if: isNotEqualToModelPathValue|Sentinel|/spec/mode - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/persistence/properties/size + - if: + type: function + name: getDefaultValue|spec/admin/authCredential/customize + label: Provide Authentication Credentials? + watcher: + func: onAuthChange + paths: + - temp/createAuthSecret + schema: temp/createAuthSecret + type: switch + - if: + type: function + name: showReferSecretSwitch + label: Refer existing Secret? + watcher: + func: onReferSecretChange + paths: + - temp/referSecret + schema: temp/referSecret + type: switch + - loader: getReferSecrets + if: + type: function + name: showSecretDropdown + label: Secret + schema: schema/properties/spec/properties/authSecret/properties/name + type: select + - if: + type: function + name: showReferSecret + label: Password (leave it blank to auto generate password) + schema: schema/properties/spec/properties/authSecret/properties/password type: input - - computed: setAnnounce - if: isEqualToModelPathValue|Cluster|/spec/mode - label: - text: Announce Redis Endpoints ? - onChange: setAnnounce - schema: - $ref: discriminator#/announce + - if: + type: function + name: getDefaultValue|spec/admin/customConfiguration + label: Configure Database? + watcher: + func: clearConfiguration + paths: + - temp/configDatabase + schema: temp/configDatabase type: switch + - if: + type: function + name: isConfigDatabaseOn + label: Configuration + schema: schema/properties/spec/properties/configuration + type: textarea + - if: + type: function + name: isToggleOn|deployment + label: Deployment Mode + options: + - description: For exploring databases when high-performance is not required. + text: Shared + value: Shared + - description: For production applications with sophisticated workload + text: Dedicated + value: Dedicated + schema: schema/properties/spec/properties/admin/properties/deployment/properties/default + type: radio + - if: + type: function + name: isToggleOn|clusterTier + isHorizontal: true + label: Cluster Tier + options: + - text: General Purpose + value: GeneralPurpose + - text: Memory Optimized + value: MemoryOptimized + - text: CPU Optimized + value: CPUOptimized + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/default + type: radio + - disableUnselect: true + loader: getAdminOptions|clusterTier/placement + if: + type: function + name: isToggleOn|clusterTier/placement + label: Placement Policy + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + type: select + - disableUnselect: true + loader: getNodeTopology + if: + type: function + name: isToggleOn|clusterTier/nodeTopology + label: Node Topology + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + type: select + hideBlock: true + label: Advanced Configuration + showLabels: true + type: block-layout + - description: Enable Backup, Monitoring, TLS etc. + elements: - elements: - - label: - text: Type - options: - - ip - - hostname - required: true - schema: - $ref: schema#/properties/spec/properties/cluster/properties/announce/properties/type - type: select - - addFormLabel: Shards - element: - elements: - - element: - label: - text: Endpoints - schema: - $ref: schema#/properties/spec/properties/cluster/properties/announce/properties/shards/items/properties/endpoints/items - type: input - label: - text: Endpoints - schema: - $ref: schema#/properties/spec/properties/cluster/properties/announce/properties/shards/items/properties/endpoints - type: list-input-form - type: single-step-form - label: - text: Shards - newItemValidator: validateEndpoints - required: true - schema: - $ref: schema#/properties/spec/properties/cluster/properties/announce/properties/shards - tableContents: - - inTableColumn: true - label: - text: Endpoints - path: endpoints - type: value - typeOfValue: string - temporaryPath: /endpoints - type: single-step-form-array - validationRuleObject: - func: isAnnounceValid - if: showAnnounce - label: - text: Announce - schema: - $ref: schema#/properties/spec/properties/cluster/properties/announce - show_label: true - type: single-step-form - - accordion: true - description: - text: Configure Credentials, Deployment Mode etc. - discriminator: - configDatabase: - default: false - type: boolean - createAuthSecret: - default: false - type: boolean - referSecret: - default: false - type: boolean - elements: - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties - type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties - type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - computed: getDefault|deletionPolicy - customClass: mt-20 - if: isToggleOn|deletionPolicy - 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/spec/properties/deletionPolicy - type: select - - if: getDefaultValue|spec/admin/authCredential/customize - label: - text: Provide Authentication Credentials? - onChange: onAuthChange - schema: - $ref: discriminator#/createAuthSecret - type: switch - - if: showReferSecretSwitch - label: - text: Refer existing Secret? - onChange: onReferSecretChange - schema: - $ref: discriminator#/referSecret + - init: + type: func + value: setMonitoring + label: Enable Monitoring + watcher: + func: updateAlertValue + paths: + - temp/monitoring + schema: temp/monitoring type: switch - - fetch: getReferSecrets - if: showSecretDropdown - label: - text: Secret - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/name - type: select - - if: showReferSecret - label: - text: labels.password - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/password - type: input - - computed: isConfigAvailable - if: getDefaultValue|spec/admin/customConfiguration - label: - text: Configure Database? - onChange: clearConfiguration - schema: - $ref: discriminator#/configDatabase - type: switch - - if: isConfigDatabaseOn - label: - text: Configuration - schema: - $ref: schema#/properties/spec/properties/configuration - type: editor - - hasDescription: true - if: isToggleOn|deployment - label: - text: labels.deployment.name + - customClass: mt-10 + if: + type: function + name: showAlerts + label: Alert Options options: - - description: labels.deployment.shared - text: Shared - value: Shared - - description: labels.deployment.dedicated - text: Dedicated - value: Dedicated - schema: - $ref: schema#/properties/spec/properties/admin/properties/deployment/properties/default - type: radio - - if: isToggleOn|clusterTier - isHorizontal: true - label: - text: labels.clusterTier - options: - - text: General Purpose - value: GeneralPurpose - - text: Memory Optimized - value: MemoryOptimized - - text: CPU Optimized - value: CPUOptimized - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/default - type: radio - - disableUnselect: true - fetch: getAdminOptions|clusterTier/placement - if: isToggleOn|clusterTier/placement - label: - text: labels.placement - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + - text: None + value: none + - text: Critical + value: critical + - text: Warning + value: warning + - text: Info + value: info + schema: schema/properties/form/properties/alert/properties/enabled type: select - - disableUnselect: true - fetch: getNodeTopology - if: isToggleOn|clusterTier/nodeTopology - label: - text: labels.nodeTopology - refresh: true - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + if: + type: function + name: isToggleOn|monitoring + type: block-layout + - init: + type: func + value: setBackup + if: + type: function + name: isToggleOn|backup + label: Enable Backup? + watcher: + func: onBackupSwitch + paths: + - temp/backup + schema: temp/backup + type: switch + - elements: + - label: Enable TLS? + schema: schema/properties/spec/properties/admin/properties/tls/properties/default + type: switch + - loader: getAdminOptions|clusterIssuers + if: + type: function + name: showIssuer + label: Cluster Issuers + validation: + type: required + schema: schema/properties/spec/properties/admin/properties/clusterIssuers/properties/default type: select - hideForm: true - label: - text: Advanced Configuration - show_label: true - type: single-step-form - - accordion: true - description: - text: Enable Backup, Monitoring, TLS etc. - discriminator: - backup: - default: false - type: boolean - elements: - - discriminator: - monitoring: - default: false - type: boolean - elements: - - computed: setMonitoring - label: - text: labels.enable_monitoring - onChange: updateAlertValue - schema: - $ref: discriminator#/monitoring - type: switch - - customClass: mt-10 - if: showAlerts - label: - text: labels.alert.options - options: - - text: None - value: none - - text: Critical - value: critical - - text: Warning - value: warning - - text: Info - value: info - schema: - $ref: schema#/properties/form/properties/alert/properties/enabled - sortable: true - type: select - if: isToggleOn|monitoring - type: single-step-form - - computed: setBackup - if: isToggleOn|backup - label: - text: Enable Backup? - onChange: onBackupSwitch - schema: - $ref: discriminator#/backup + if: + type: function + name: isToggleOn|tls + type: block-layout + - elements: + - if: + type: function + name: isToggleOn|expose + label: Expose via Gateway? + schema: schema/properties/spec/properties/admin/properties/expose/properties/default type: switch - - elements: - - label: - text: Enable TLS? - schema: - $ref: schema#/properties/spec/properties/admin/properties/tls/properties/default - type: switch - - fetch: getAdminOptions|clusterIssuers - if: showIssuer - label: - text: labels.clusterIssuers - required: true - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterIssuers/properties/default - type: select - if: isToggleOn|tls - type: single-step-form - - elements: - - if: isToggleOn|expose - label: - text: Expose via Gateway? - schema: - $ref: schema#/properties/spec/properties/admin/properties/expose/properties/default - type: switch - type: single-step-form - if: showAdditionalSettings - label: - text: Additional Options - show_label: true - type: single-step-form - type: single-step-form + type: block-layout + if: + type: function + name: showAdditionalSettings + label: Additional Options + showLabels: true + type: block-layout id: options - title: steps.0.label + # title: steps.0.label type: multi-step-form diff --git a/charts/kubedbcom-redis-editor-options/ui/functions.js b/charts/kubedbcom-redis-editor-options/ui/functions.js index 9537b050e9..b7fb39b8f1 100644 --- a/charts/kubedbcom-redis-editor-options/ui/functions.js +++ b/charts/kubedbcom-redis-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -319,1087 +321,1141 @@ const modeDetails = { }, } -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} - -function isNotEqualToModelPathValue( - { model, getValue, watchDependency, discriminator }, - value, - modelPath, -) { - const modelPathValue = getValue(model, modelPath, getValue) - watchDependency('model#' + modelPath) - return ( - modelPathValue !== value && - isToggleOn({ getValue, model, watchDependency, discriminator }, 'storageClasses') +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, ) -} - -function showAuthSecretField({ discriminator, getValue, watchDependency }) { - return !showAuthPasswordField({ - discriminator, - getValue, - watchDependency, - }) -} - -async function getResources({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + setDiscriminatorValue('bundleApiLoaded', false) + setDiscriminatorValue('createSentinel', 'true') + setDiscriminatorValue('announce', false) + setDiscriminatorValue('createAuthSecret', false) + setDiscriminatorValue('referSecret', false) + setDiscriminatorValue('configDatabase', false) + setDiscriminatorValue('monitoring', false) + setDiscriminatorValue('backup', false) + + function checkIfFeatureOn(type) { + let val = getValue(model, `/spec/admin/${type}/toggle`) + if (type === 'backup' || type === 'archiver') { + val = getValue(model, `/spec/admin/${type}/enable/toggle`) + } + const backupVal = getValue(model, '/spec/backup/tool') + + if (type === 'backup') { + return features.includes('backup') && backupVal === 'KubeStash' && val + } else if (type === 'tls') { + return features.includes('tls') && val + } else if (type === 'expose') { + return features.includes('binding') && val + } else if (type === 'monitoring') { + return features.includes('monitoring') && val + } else if (type === 'archiver') { + return features.includes('backup') && backupVal === 'KubeStash' && val + } + } - const resources = (resp && resp.data && resp.data.items) || [] + function clearConfiguration() { + const configOn = getValue(discriminator, '/configDatabase') - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return resources -} + if (!configOn) { + commit('wizard/model$delete', '/spec/configuration') + } + } -async function getRedisSentinels({ axios, storeGet, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/spec/sentinelRef/namespace') + function dedicatedOnChange() { + const val = getValue(model, 'form/capi/dedicated') + if (!val) { + commit('wizard/model$delete', 'form/capi/zones') + commit('wizard/model$delete', 'form/capi/sku') + } + } - watchDependency('model#/spec/sentinelRef/namespace') + async function fetchJsons(itemCtx) { + let ui = {} + let language = {} + let functions = {} + const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart - if (owner && cluster && namespace) { try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redissentinels`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, + 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, + } + } - const resources = (resp && resp.data && resp.data.items) || [] + function fetchOptions(type) { + let kind = getValue(model, '/metadata/resource/kind') + + let returnArray = [] + if (type === 'clusterTier/placement') { + returnArray = placement + } else if (type === `databases/${kind}/versions`) { + returnArray = versions + } else if (type === 'storageClasses') { + returnArray = storageClass + } else if (type === 'clusterIssuers') { + returnArray = clusterIssuers + } - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + if (returnArray.length === 1) { + const path = `/spec/admin/${type}/default` + commit('wizard/model$update', { + path: path, + value: returnArray[0], + force: true, }) - - return resources - } catch (err) { - console.log(err) - return [] } - } else { - return [] + + return returnArray } -} -async function getRedisVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function filterNodeTopology(list, tier, provider) { + // first filter the list from value that exists from the filtered list got from API + const filteredlist = list - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, - }, - }, + // filter the list based on clusterTier + if (provider === 'EKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('c') + else if (tier === 'MemoryOptimized') return item.startsWith('r') + else return !item.startsWith('c') && !item.startsWith('r') + }) + } else if (provider === 'AKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') + else if (tier === 'MemoryOptimized') + return ( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + else + return ( + !(item.startsWith('f') || item.startsWith('fx')) && + !( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + ) + }) + } else if (provider === 'GKE') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') + return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') + else if (tier === 'MemoryOptimized') + return ( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + else + return ( + !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && + !( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + ) + }) + } else return filteredlist } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) + function getAdminOptions(type) { + // watchDependency('discriminator#/bundleApiLoaded') - const resources = (resp && resp.data && resp.data.items) || [] + const options = getValue(model, `/spec/admin/${type}/available`) || [] - // keep only non deprecated versions - const filteredRedisVersions = resources.filter((item) => item.spec && !item.spec.deprecated) + if (options.length === 0) { + return fetchOptions(type) + } + if (type.endsWith('/mode')) { + return ( + options?.map((item) => ({ + description: modeDetails[item]?.description || '', + text: modeDetails[item]?.text || '', + value: item, + })) || [] + ) + } + return options + } - filteredRedisVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredRedisVersions -} + function getCreateNameSpaceUrl() { + const user = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + const domain = storeGet('/domain') || '' + if (domain.includes('bb.test')) { + return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } + } - const secrets = (resp && resp.data && resp.data.items) || [] + function getDefault(type) { + const val = getValue(model, `/spec/admin/${type}/default`) || '' + return val + } - const filteredSecrets = secrets.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) + function getDefaultValue(path) { + const val = getValue(model, `/${path}`) || '' + return val + } - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return filteredSecrets -} + let array = [] + function getMachineListForOptions() { + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') -function setMachineToCustom({ getValue, model }) { - const machine = getValue(model, '/spec/admin/machineProfiles/default') - return machine || 'custom' -} + if (available.length) { + array = available.map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + else { + let subText = '', + text = '' + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + text = machineData.name ? machineData.name : machineData.id + } + return { text, subText, value: machine } + } + }) + } else { + array = machineList + .map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { text, subText, value: machine } + }) + .filter((val) => !!val) + } + return array + } -function showSentinelNameAndNamespace({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/createSentinel') - const verd = getValue(discriminator, '/createSentinel') + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, + }, + ) + if (resp.data?.status?.projects) { + const projects = resp.data?.status?.projects + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } + } catch (e) { + console.log(e) + } + return [] + } - return !verd -} + async function getNodeTopology() { + // watchDependency('model#/spec/admin/deployment/default') + // watchDependency('model#/spec/admin/clusterTier/default') + const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' + const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' + let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] -function onCreateSentinelChange({ discriminator, getValue, commit }) { - const verd = getValue(discriminator, '/createSentinel') + const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' - if (verd) { - commit('wizard/model$update', { - path: '/spec/sentinelRef/name', - value: '', - force: true, - }) + if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared + else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated - commit('wizard/model$update', { - path: '/spec/sentinelRef/namespace', - value: '', - force: true, - }) + const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) + return filteredList } -} -async function fetchJsons({ axios, itemCtx }) { - let ui = {} - let language = {} - let functions = {} - const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart + async function getRedisSentinels() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/spec/sentinelRef/namespace') - 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) - } + // watchDependency('model#/spec/sentinelRef/namespace') - return { - ui: ui.data || {}, - language: language.data || {}, - functions, - } -} + if (owner && cluster && namespace) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redissentinels`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) -function updateAgentValue({ commit }, val) { - commit('wizard/model$update', { - path: '/spec/monitoring/agent', - value: val ? 'prometheus.io/operator' : '', - force: true, - }) - - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: val ? 'warning' : 'none', - force: true, - }) -} + const resources = (resp && resp.data && resp.data.items) || [] -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true + }) - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + return resources + } catch (err) { + console.log(err) + return [] + } + } else { + return [] + } } -} -const ifCapiProviderIsNotEmpty = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/provider') - const val = getValue(model, '/form/capi/provider') - if (val) return true -} + async function getRedisVersions(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -const showMultiselectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') + const queryParams = { + filter: { + items: { + metadata: { name: null }, + spec: { version: null, deprecated: null }, + }, + }, + } - if (val === 'capz' && ifDedicated({ model, getValue })) return true -} + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: queryParams, + }, + ) -const showSelectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') - if (val !== 'capz' && ifDedicated({ model, getValue })) return true -} + const resources = (resp && resp.data && resp.data.items) || [] -const ifDedicated = ({ model, getValue }) => { - const val = getValue(model, 'form/capi/dedicated') - if (val) return true -} + // keep only non deprecated versions + const filteredRedisVersions = resources.filter((item) => item.spec && !item.spec.deprecated) -const dedicatedOnChange = ({ model, getValue, commit }) => { - const val = getValue(model, 'form/capi/dedicated') - if (!val) { - commit('wizard/model$delete', 'form/capi/zones') - commit('wizard/model$delete', 'form/capi/sku') + filteredRedisVersions.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + const specVersion = (item.spec && item.spec.version) || '' + item.text = `${name} (${specVersion})` + item.value = name + return true + }) + return filteredRedisVersions } -} -const ifZones = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/zones') - watchDependency('model#/form/capi/dedicated') - const zones = getValue(model, 'form/capi/zones') || [] - const isDedicated = getValue(model, 'form/capi/dedicated') - if (zones.length && isDedicated) return true -} + async function getReferSecrets() { + const referSecret = getValue(discriminator, '/referSecret') + if (!referSecret) { + return [] + } -const zonesOnChange = ({ model, getValue, commit }) => { - const zones = getValue(model, 'form/capi/zones') || [] - if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') -} + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/metadata/release/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` -async function getZones({ storeGet, axios, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const isDedicated = getValue(model, 'form/capi/dedicated') - if (isDedicated) { + const options = [] try { - const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) - const val = resp.data.map((item) => { - return { value: item, text: item } + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) }) - return val } catch (e) { console.log(e) - return [] } + return options } -} -async function getSKU({ storeGet, axios, model, getValue, watchDependency }) { - watchDependency('model#/form/capi/zones') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const zones = getValue(model, 'form/capi/zones') || [] - if (zones.length) { - try { - let url = `clustersv2/${owner}/${cluster}/vms?` - if (typeof zones === 'string') { - url += `zones=${encodeURIComponent(zones)}` - } else { - zones.forEach((item) => { - url += `zones=${encodeURIComponent(item)}&` + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + + 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 + } + + 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') + + 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 + } + + async function getSKU() { + // watchDependency('model#/form/capi/zones') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const zones = getValue(model, 'form/capi/zones') || [] + if (zones.length) { + try { + let url = `clustersv2/${owner}/${cluster}/vms?` + if (typeof zones === 'string') { + url += `zones=${encodeURIComponent(zones)}` + } else { + zones.forEach((item) => { + url += `zones=${encodeURIComponent(item)}&` + }) + url = url.slice(0, -1) + } + const resp = await axios.get(url) + const val = resp.data.map((item) => { + return { + value: item.name, + text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, + } }) - url = url.slice(0, -1) + return val + } catch (e) { + console.log(e) + return [] } - const resp = await axios.get(url) - const val = resp.data.map((item) => { - return { - value: item.name, - text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, - } - }) - return val - } catch (e) { - console.log(e) - return [] } } -} -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} - -function setStorageClass({ model, getValue, commit, watchDependency, discriminator }) { - const deletionPolicy = getValue(model, 'spec/deletionPolicy') || '' - let storageClass = getValue(model, 'spec/storageClass/name') || '' - const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] - const suffix = '-retain' + async function getZones() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const isDedicated = getValue(model, 'form/capi/dedicated') + if (isDedicated) { + try { + const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) + const val = resp.data.map((item) => { + return { value: item, text: item } + }) + return val + } catch (e) { + console.log(e) + return [] + } + } + } - const simpleClassList = storageClassList.filter((item) => { - return !item.endsWith(suffix) - }) + const ifCapiProviderIsNotEmpty = () => { + // watchDependency('model#/form/capi/provider') + const val = getValue(model, '/form/capi/provider') + if (val) return true + } - const retainClassList = storageClassList.filter((item) => { - return item.endsWith(suffix) - }) + const ifDedicated = () => { + const val = getValue(model, 'form/capi/dedicated') + if (val) return true + } - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] - } else { - storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + const ifZones = () => { + // watchDependency('model#/form/capi/zones') + // watchDependency('model#/form/capi/dedicated') + const zones = getValue(model, 'form/capi/zones') || [] + const isDedicated = getValue(model, 'form/capi/dedicated') + if (zones.length && isDedicated) return true } - const isChangeable = isToggleOn( - { getValue, model, watchDependency, discriminator }, - 'storageClasses', - ) - if (isChangeable && storageClass) { + + let placement = [] + let versions = [] + let storageClass = [] + let clusterIssuers = [] + let nodetopologiesShared = [] + let nodetopologiesDedicated = [] + let features = [] + async function initBundle() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + + let db = getValue(model, '/metadata/resource/kind') + db = db.toLowerCase() + let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` + const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` + + try { + const resp = await axios.get(url) + features = resp.data.features || [] + placement = resp.data.placementpolicies || [] + versions = resp.data.versions || [] + storageClass = resp.data.storageclasses || [] + clusterIssuers = resp.data.clusterissuers || [] + nodetopologiesDedicated = resp.data.dedicated || [] + nodetopologiesShared = resp.data.shared || [] + + const response = await axios.get(annotationUrl) + const annotations = response.data?.metadata?.annotations || {} + const uidRange = annotations['openshift.io/sa.scc.uid-range'] + if (uidRange) { + const val = uidRange.split('/')[0] + commit('wizard/model$update', { + path: '/spec/openshift/securityContext/runAsUser', + value: val, + force: true, + }) + } + } catch (e) { + console.log(e) + } + commit('wizard/model$update', { - path: '/spec/admin/storageClasses/default', - value: storageClass, + path: '/spec/deletionPolicy', + value: getDefault('deletionPolicy'), force: true, }) - } -} -let placement = [] -let versions = [] -let storageClass = [] -let clusterIssuers = [] -let nodetopologiesShared = [] -let nodetopologiesDedicated = [] -let features = [] -async function initBundle({ commit, model, getValue, axios, storeGet, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - - let db = getValue(model, '/metadata/resource/kind') - db = db.toLowerCase() - let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` - const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - - try { - const resp = await axios.get(url) - features = resp.data.features || [] - placement = resp.data.placementpolicies || [] - versions = resp.data.versions || [] - storageClass = resp.data.storageclasses || [] - clusterIssuers = resp.data.clusterissuers || [] - nodetopologiesDedicated = resp.data.dedicated || [] - nodetopologiesShared = resp.data.shared || [] - - const response = await axios.get(annotationUrl) - const annotations = response.data?.metadata?.annotations || {} - const uidRange = annotations['openshift.io/sa.scc.uid-range'] - if (uidRange) { - const val = uidRange.split('/')[0] + if (!getValue(model, `/spec/admin/databases/Redis/mode/toggle`)) { + let defMode = getDefault('databases/Redis/mode') || '' + if (defMode === '') { + const arr = getValue(model, '/spec/databases/Redis/mode/available') || [] + if (arr.length) defMode = arr[0] + } + commit('wizard/model$update', { + path: '/spec/mode', + value: defMode, + force: true, + }) + } + + if (!features.includes('tls')) { + commit('wizard/model$update', { + path: '/spec/admin/tls/default', + value: false, + force: true, + }) + } + if (!features.includes('binding')) { + commit('wizard/model$update', { + path: '/spec/admin/expose/default', + value: false, + force: true, + }) + } + if (!features.includes('monitoring')) { commit('wizard/model$update', { - path: '/spec/openshift/securityContext/runAsUser', - value: val, + path: '/spec/admin/monitoring/agent', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: 'none', force: true, }) } - } catch (e) { - console.log(e) + if (!features.includes('backup')) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: '', + force: true, + }) + } + + setDiscriminatorValue('/bundleApiLoaded', true) } - commit('wizard/model$update', { - path: '/spec/deletionPolicy', - value: getDefault({ getValue, model }, 'deletionPolicy'), - force: true, - }) + function isAnnounceValid() { + // watchDependency('model#/spec/cluster/master') - if (!getValue(model, `/spec/admin/databases/Redis/mode/toggle`)) { - let defMode = getDefault({ getValue, model }, 'databases/Redis/mode') || '' - if (defMode === '') { - const arr = getValue(model, '/spec/databases/Redis/mode/available') || [] - if (arr.length) defMode = arr[0] - } - commit('wizard/model$update', { - path: '/spec/mode', - value: defMode, - force: true, - }) + const master = getValue(model, '/spec/cluster/master') || 0 + + const shards = getValue(model, '/spec/cluster/announce/shards') || [] + const shardsLength = shards?.length || 0 + + if (shardsLength !== master) return `Shards Length should be equal to master(${master})` + return true } - if (!features.includes('tls')) { - commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: false, - force: true, - }) + function isConfigDatabaseOn() { + // watchDependency('discriminator#/configDatabase') + return getValue(discriminator, '/configDatabase') } - if (!features.includes('binding')) { - commit('wizard/model$update', { - path: '/spec/admin/expose/default', - value: false, - force: true, - }) + + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } + + function isMachineCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue === 'custom' + } + + function isMachineNotCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue !== 'custom' && !!modelPathValue + } + + function isNotEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue !== value && isToggleOn('storageClasses') + } + + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } + + function isToggleOn(type) { + // watchDependency('discriminator#/bundleApiLoaded') + // watchDependency('model#/spec/admin/deployment/default') + const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') + let deploymentType = getValue(model, `/spec/admin/deployment/default`) + if ( + type === 'tls' || + type === 'backup' || + type === 'expose' || + type === 'monitoring' || + type === 'archiver' + ) { + return checkIfFeatureOn(type) + } else if ( + type === 'clusterTier' || + type === 'clusterTier/placement' || + type === 'clusterTier/nodeTopology' + ) { + if (deploymentType === 'Dedicated' && bundleApiLoaded) return true + else return false + } else if (type === 'deployment') { + const deploymentType = getValue(model, '/spec/admin/deployment/default') + if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + commit('wizard/model$update', { + path: '/spec/admin/deployment/default', + value: 'Shared', + force: true, + }) + } + return ( + getValue(model, `/spec/admin/${type}/toggle`) && + nodetopologiesDedicated.length && + bundleApiLoaded + ) + } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded } - if (!features.includes('monitoring')) { + + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false + } + + function notEqualToDatabaseMode(mode) { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + return modelPathValue && modelPathValue !== mode + } + + function onAuthChange() { commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', + path: '/spec/authSecret/name', value: '', force: true, }) commit('wizard/model$update', { - path: '/form/alert/enabled', - value: 'none', + path: '/spec/authSecret/password', + value: '', force: true, }) } - if (!features.includes('backup')) { - commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, - force: true, - }) + + function onBackupSwitch() { + const isBackupOn = getValue(discriminator, '/backup') commit('wizard/model$update', { path: '/spec/backup/tool', - value: '', + value: isBackupOn ? 'KubeStash' : '', force: true, }) } - setDiscriminatorValue('/bundleApiLoaded', true) -} + function onCreateSentinelChange() { + const verd = getValue(discriminator, '/createSentinel') -function fetchOptions({ model, getValue, commit }, type) { - let kind = getValue(model, '/metadata/resource/kind') + if (verd) { + commit('wizard/model$update', { + path: '/spec/sentinelRef/name', + value: '', + force: true, + }) - let returnArray = [] - if (type === 'clusterTier/placement') { - returnArray = placement - } else if (type === `databases/${kind}/versions`) { - returnArray = versions - } else if (type === 'storageClasses') { - returnArray = storageClass - } else if (type === 'clusterIssuers') { - returnArray = clusterIssuers + commit('wizard/model$update', { + path: '/spec/sentinelRef/namespace', + value: '', + force: true, + }) + } } - if (returnArray.length === 1) { - const path = `/spec/admin/${type}/default` + function onReferSecretChange() { commit('wizard/model$update', { - path: path, - value: returnArray[0], + path: '/spec/authSecret/name', + value: '', force: true, }) } - return returnArray -} - -function getAdminOptions({ getValue, model, watchDependency, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') - - const options = getValue(model, `/spec/admin/${type}/available`) || [] - - if (options.length === 0) { - return fetchOptions({ model, getValue, commit }, type) + function returnFalse() { + return false } - if (type.endsWith('/mode')) { - return ( - options?.map((item) => ({ - description: modeDetails[item]?.description || '', - text: modeDetails[item]?.text || '', - value: item, - })) || [] - ) - } - return options -} -function checkIfFeatureOn({ getValue, model }, type) { - let val = getValue(model, `/spec/admin/${type}/toggle`) - if (type === 'backup' || type === 'archiver') { - val = getValue(model, `/spec/admin/${type}/enable/toggle`) + function setAnnounce() { + commit('wizard/model$update', { + path: '/spec/cluster/announce', + value: null, + force: true, + }) } - const backupVal = getValue(model, '/spec/backup/tool') - if (type === 'backup') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } else if (type === 'tls') { - return features.includes('tls') && val - } else if (type === 'expose') { - return features.includes('binding') && val - } else if (type === 'monitoring') { - return features.includes('monitoring') && val - } else if (type === 'archiver') { - return features.includes('backup') && backupVal === 'KubeStash' && val + function setBackup() { + const backup = getValue(model, '/spec/backup/tool') + const val = getValue(model, '/spec/admin/backup/enable/default') + return backup === 'KubeStash' && features.includes('backup') && val } -} -function isToggleOn({ getValue, model, discriminator, watchDependency }, type) { - watchDependency('discriminator#/bundleApiLoaded') - watchDependency('model#/spec/admin/deployment/default') - const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') - let deploymentType = getValue(model, `/spec/admin/deployment/default`) - if ( - type === 'tls' || - type === 'backup' || - type === 'expose' || - type === 'monitoring' || - type === 'archiver' - ) { - return checkIfFeatureOn({ getValue, model }, type) - } else if ( - type === 'clusterTier' || - type === 'clusterTier/placement' || - type === 'clusterTier/nodeTopology' - ) { - if (deploymentType === 'Dedicated' && bundleApiLoaded) return true - else return false - } else if (type === 'deployment') { - const deploymentType = getValue(model, '/spec/admin/deployment/default') - if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + function setLimits(resource, type) { + const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' + // watchDependency(`model#${path}`) + const selectedMachine = getValue(model, path) || 'custom' + const reqCommitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + const comparePath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + + const resourceValue = getValue(model, comparePath) + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + let cpu = '', + memory = '' + if (available.length && selectedMachine !== 'custom') { + const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) + if (machineData) { + cpu = machineData.limits.cpu + memory = machineData.limits.memory + } + } else { + if (selectedMachine === 'custom') { + cpu = resourceValue + memory = resourceValue + } else { + cpu = machines[selectedMachine].resources.limits.cpu + memory = machines[selectedMachine].resources.limits.memory + } + } + + if (resource === 'memory') { commit('wizard/model$update', { - path: '/spec/admin/deployment/default', - value: 'Shared', + path: reqCommitPath, + value: memory, force: true, }) + commit('wizard/model$update', { + path: comparePath, + value: memory, + force: true, + }) + return memory + } else { + commit('wizard/model$update', { + path: reqCommitPath, + value: cpu, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: cpu, + force: true, + }) + return cpu } - return ( - getValue(model, `/spec/admin/${type}/toggle`) && - nodetopologiesDedicated.length && - bundleApiLoaded - ) - } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded -} -async function getNodeTopology({ model, getValue, axios, storeGet, watchDependency }) { - watchDependency('model#/spec/admin/deployment/default') - watchDependency('model#/spec/admin/clusterTier/default') - const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' - const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' - let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] - - const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + } - if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared - else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + function setRequests(resource, type) { + const modelPath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` - const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) - return filteredList -} + const fullpath = `/spec/podResources/machine` + const modelPathValue = getValue(model, fullpath) -function filterNodeTopology(list, tier, provider) { - // first filter the list from value that exists from the filtered list got from API - const filteredlist = list + commit('wizard/model$update', { + path: commitPath, + value: val, + force: true, + }) - // filter the list based on clusterTier - if (provider === 'EKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('c') - else if (tier === 'MemoryOptimized') return item.startsWith('r') - else return !item.startsWith('c') && !item.startsWith('r') + if (modelPathValue === 'custom') { + return + } + let commitCpuMemory, ModelPathValue + if (resource && type) { + const fullPath = `/spec/${type}/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/${type}/podResources/resources/requests/${resource}` + } else { + const fullPath = `/spec/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/podResources/resources/requests/${resource}` + } + let cpuMemoryValue + array.forEach((item) => { + if (item.value === ModelPathValue) { + // Parse subText like "CPU: 2, Memory: 2Gi" + const subText = item.subText || '' + if (resource === 'cpu') { + // Extract CPU value + const cpuMatch = subText.match(/CPU:\s*([^,]+)/) + cpuMemoryValue = cpuMatch ? cpuMatch[1].trim() : '' + } else if (resource === 'memory') { + // Extract Memory value + const memoryMatch = subText.match(/Memory:\s*(.+)/) + cpuMemoryValue = memoryMatch ? memoryMatch[1].trim() : '' + } + } }) - } else if (provider === 'AKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - else - return ( - !(item.startsWith('f') || item.startsWith('fx')) && - !( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - ) + commit('wizard/model$update', { + path: commitCpuMemory, + value: cpuMemoryValue, + force: true, }) - } else if (provider === 'GKE') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') - return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - else - return ( - !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && - !( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - ) + return cpuMemoryValue + } + + function setMachineToCustom() { + const machine = getValue(model, '/spec/admin/machineProfiles/default') + return machine || 'custom' + } + + function setMonitoring() { + const agent = getValue(model, '/spec/admin/monitoring/agent') || '' + return !!agent + } + + function setRequests(resource) { + const modelPath = `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = `/spec/podResources/resources/limits/${resource}` + commit('wizard/model$update', { + path: commitPath, + value: val, + force: true, }) - } else return filteredlist -} + } -function returnFalse() { - return false -} + function setStorageClass() { + const deletionPolicy = getValue(model, 'spec/deletionPolicy') || '' + let storageClass = getValue(model, 'spec/storageClass/name') || '' + const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] + const suffix = '-retain' -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], - }, - }, - ) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace + const simpleClassList = storageClassList.filter((item) => { + return !item.endsWith(suffix) + }) + + const retainClassList = storageClassList.filter((item) => { + return item.endsWith(suffix) + }) + + if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { + storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] } else { - return resp.data?.status?.namespaces || [] + storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + } + const isChangeable = isToggleOn('storageClasses') + if (isChangeable && storageClass) { + commit('wizard/model$update', { + path: '/spec/admin/storageClasses/default', + value: storageClass, + force: true, + }) } - } catch (e) { - console.log(e) } - return [] -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function showAdditionalSettings() { + // watchDependency('discriminator#/bundleApiLoaded') + return features.length + } -function updateAlertValue({ commit, model, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const alert = isMonitorEnabled ? 'warning' : 'none' - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: alert, - force: true, - }) - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} + function showAlerts() { + // watchDependency('discriminator#/monitoring') + const isMonitorEnabled = getValue(discriminator, '/monitoring') + return isMonitorEnabled && isToggleOn('alert') + } -function showAlerts({ watchDependency, model, getValue, discriminator }) { - watchDependency('discriminator#/monitoring') - const isMonitorEnabled = getValue(discriminator, '/monitoring') - return ( - isMonitorEnabled && isToggleOn({ getValue, model, watchDependency, discriminator }, 'alert') - ) -} + function showAnnounce() { + // watchDependency('discriminator#/announce') + const isAnnounceEnable = getValue(discriminator, '/announce') + return isAnnounceEnable + } -function onBackupSwitch({ discriminator, getValue, commit }) { - const isBackupOn = getValue(discriminator, '/backup') - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: isBackupOn ? 'KubeStash' : '', - force: true, - }) -} + function showAuthPasswordField() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !modelPathValue && showReferSecret() + } -function showIssuer({ model, getValue, watchDependency, discriminator }) { - watchDependency('model#/spec/admin/tls/default') - const isTlsEnabled = getValue(model, '/spec/admin/tls/default') - const isIssuerToggleEnabled = isToggleOn( - { getValue, model, watchDependency, discriminator }, - 'clusterIssuers', - ) - return isTlsEnabled && isIssuerToggleEnabled -} + function showAuthSecretField() { + return !showAuthPasswordField() + } -function setMonitoring({ getValue, model }) { - const agent = getValue(model, '/spec/admin/monitoring/agent') || '' - return !!agent -} + function showIssuer() { + // watchDependency('model#/spec/admin/tls/default') + const isTlsEnabled = getValue(model, '/spec/admin/tls/default') + const isIssuerToggleEnabled = isToggleOn('clusterIssuers') + return isTlsEnabled && isIssuerToggleEnabled + } -function setBackup({ model, getValue }) { - const backup = getValue(model, '/spec/backup/tool') - const val = getValue(model, '/spec/admin/backup/enable/default') - return backup === 'KubeStash' && features.includes('backup') && val -} + const showMultiselectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') -function clearConfiguration({ discriminator, getValue, commit }) { - const configOn = getValue(discriminator, '/configDatabase') + if (val === 'capz' && ifDedicated()) return true + } - if (!configOn) { - commit('wizard/model$delete', '/spec/configuration') + function showReferSecret() { + const modelPathValue = getValue(discriminator, '/createAuthSecret') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue } -} -function isConfigDatabaseOn({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configDatabase') - return getValue(discriminator, '/configDatabase') -} + function showReferSecretSwitch() { + const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue && showReferSecret() + } -function getMachineListForOptions({ model, getValue }) { - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - let array = [] + function showSecretDropdown() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !!modelPathValue && showReferSecret() + } - if (available.length) { - array = available.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - else { - let subText = '', - text = '' - const machineData = machinesFromPreset.find((val) => val.id === machine) - if (machineData) { - subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` - text = machineData.name ? machineData.name : machineData.id - } - return { text, subText, value: machine } - } - }) - } else { - array = machineList - .map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } - }) - .filter((val) => !!val) + const showSelectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') + if (val !== 'capz' && ifDedicated()) return true } - return array -} -function setLimits({ model, getValue, commit, watchDependency }, resource, type) { - const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' - watchDependency(`model#${path}`) - const selectedMachine = getValue(model, path) || 'custom' - const reqCommitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - const comparePath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - - const resourceValue = getValue(model, comparePath) - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - - let cpu = '', - memory = '' - if (available.length && selectedMachine !== 'custom') { - const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) - if (machineData) { - cpu = machineData.limits.cpu - memory = machineData.limits.memory - } - } else { - if (selectedMachine === 'custom') { - cpu = resourceValue - memory = resourceValue - } else { - cpu = machines[selectedMachine].resources.limits.cpu - memory = machines[selectedMachine].resources.limits.memory - } + function showSentinelNameAndNamespace() { + // watchDependency('discriminator#/createSentinel') + const verd = getValue(discriminator, '/createSentinel') + + return verd === 'false' || verd === false } - if (resource === 'memory') { + function updateAgentValue(val) { commit('wizard/model$update', { - path: reqCommitPath, - value: memory, + path: '/spec/monitoring/agent', + value: val ? 'prometheus.io/operator' : '', force: true, }) + + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: comparePath, - value: memory, + path: '/form/alert/enabled', + value: val ? 'warning' : 'none', force: true, }) - return memory - } else { + } + + function updateAlertValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const alert = isMonitorEnabled ? 'warning' : 'none' + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: reqCommitPath, - value: cpu, + path: '/form/alert/enabled', + value: alert, force: true, }) + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' commit('wizard/model$update', { - path: comparePath, - value: cpu, + path: '/spec/admin/monitoring/agent', + value: agent, force: true, }) - return cpu } -} - -function setRequests({ getValue, model, commit }, resource) { - const modelPath = `/spec/podResources/resources/requests/${resource}` - const val = getValue(model, modelPath) - commitPath = `/spec/podResources/resources/limits/${resource}` - commit('wizard/model$update', { - path: commitPath, - value: val, - force: true, - }) -} -function isMachineCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue === 'custom' -} + function validateEndpoints() { + // watchDependency('model#/spec/cluster/replicas') -function isMachineNotCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue !== 'custom' && !!modelPathValue -} - -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} + const replicas = getValue(model, '/spec/cluster/replicas') || 0 -function onAuthChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/authSecret/password', - value: '', - force: true, - }) -} - -function showAdditionalSettings({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return features.length -} - -function getDefault({ getValue, model }, type) { - const val = getValue(model, `/spec/admin/${type}/default`) || '' - return val -} - -function isConfigAvailable({ getValue, model }) { - const val = getValue(model, '/spec/configuration') - return val !== '' -} - -async function getReferSecrets({ getValue, model, storeGet, axios, discriminator }) { - const referSecret = getValue(discriminator, '/referSecret') - if (!referSecret) { - return [] + const endpoints = storeGet('/wizard/temporaryModel/endpoints') + const endpointsObject = Object.values(endpoints) + const length = Object.keys(endpointsObject?.[0])?.length + if (length !== replicas) + return { isInvalid: true, message: `Endpoints length should be equal to replicas(${replicas})` } + else { + return {} + } } - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/metadata/release/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - - const options = [] - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) - } catch (e) { - console.log(e) + function zonesOnChange() { + const zones = getValue(model, 'form/capi/zones') || [] + if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') } - return options -} -function showAuthPasswordField({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} - -function showSecretDropdown({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} - -function showReferSecret({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/createAuthSecret') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue -} - -function getDefaultValue({ getValue, model }, path) { - const val = getValue(model, `/${path}`) || '' - return val -} - -function showReferSecretSwitch({ model, getValue, watchDependency, discriminator }) { - const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} - -function onReferSecretChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) -} - -function setAnnounce({ commit }) { - commit('wizard/model$update', { - path: '/spec/cluster/announce', - value: null, - force: true, - }) -} - -function showAnnounce({ getValue, discriminator, watchDependency }) { - watchDependency('discriminator#/announce') - const isAnnounceEnable = getValue(discriminator, '/announce') - return isAnnounceEnable -} - -function isAnnounceValid({ getValue, model, watchDependency }) { - watchDependency('model#/spec/cluster/master') - - const master = getValue(model, '/spec/cluster/master') || 0 - - const shards = getValue(model, '/spec/cluster/announce/shards') || [] - const shardsLength = shards?.length || 0 - - if (shardsLength !== master) return `Shards Length should be equal to master(${master})` - return true -} - -function validateEndpoints({ getValue, model, watchDependency, storeGet }) { - watchDependency('model#/spec/cluster/replicas') - - const replicas = getValue(model, '/spec/cluster/replicas') || 0 - - const endpoints = storeGet('/wizard/temporaryModel/endpoints') - const endpointsObject = Object.values(endpoints) - const length = Object.keys(endpointsObject?.[0])?.length - if (length !== replicas) - return { isInvalid: true, message: `Endpoints length should be equal to replicas(${replicas})` } - else { - return {} + function returnTrue() { + return 'true' } -} -return { - validateEndpoints, - isAnnounceValid, - showAnnounce, - setAnnounce, - showReferSecretSwitch, - onReferSecretChange, - getDefaultValue, - isRancherManaged, - showSecretDropdown, - showReferSecret, - getReferSecrets, - isConfigAvailable, - initBundle, - returnFalse, - isVariantAvailable, - fetchJsons, - showAuthPasswordField, - isEqualToModelPathValue, - isNotEqualToModelPathValue, - showAuthSecretField, - getResources, - getRedisSentinels, - getRedisVersions, - getSecrets, - setMachineToCustom, - showSentinelNameAndNamespace, - onCreateSentinelChange, - updateAgentValue, - getCreateNameSpaceUrl, - ifCapiProviderIsNotEmpty, - ifDedicated, - dedicatedOnChange, - ifZones, - zonesOnChange, - getZones, - getSKU, - showMultiselectZone, - showSelectZone, - setStorageClass, - getAdminOptions, - isToggleOn, - getNamespaces, - getNodeTopology, - filterNodeTopology, - updateAlertValue, - showAlerts, - onBackupSwitch, - showIssuer, - setMonitoring, - clearConfiguration, - isConfigDatabaseOn, - getMachineListForOptions, - setLimits, - setRequests, - isMachineNotCustom, - isMachineCustom, - notEqualToDatabaseMode, - onAuthChange, - setBackup, - showAdditionalSettings, - getDefault, + return { + checkIfFeatureOn, + clearConfiguration, + dedicatedOnChange, + fetchJsons, + fetchOptions, + filterNodeTopology, + getAdminOptions, + getCreateNameSpaceUrl, + getDefault, + getDefaultValue, + getMachineListForOptions, + getNamespaces, + getNodeTopology, + getRedisSentinels, + getRedisVersions, + getReferSecrets, + getResources, + getSecrets, + getSKU, + getZones, + ifCapiProviderIsNotEmpty, + ifDedicated, + ifZones, + initBundle, + isAnnounceValid, + isConfigDatabaseOn, + isEqualToModelPathValue, + isMachineCustom, + isMachineNotCustom, + isNotEqualToModelPathValue, + isRancherManaged, + isToggleOn, + isVariantAvailable, + notEqualToDatabaseMode, + onAuthChange, + onBackupSwitch, + onCreateSentinelChange, + onReferSecretChange, + returnFalse, + returnTrue, + setAnnounce, + setBackup, + setLimits, + setMachineToCustom, + setMonitoring, + setRequests, + setStorageClass, + showAdditionalSettings, + showAlerts, + showAnnounce, + showAuthPasswordField, + showAuthSecretField, + showIssuer, + showMultiselectZone, + showReferSecret, + showReferSecretSwitch, + showSecretDropdown, + showSelectZone, + showSentinelNameAndNamespace, + updateAgentValue, + updateAlertValue, + validateEndpoints, + zonesOnChange, + } } diff --git a/charts/kubedbcom-redis-editor/ui/edit-ui.yaml b/charts/kubedbcom-redis-editor/ui/edit-ui.yaml index 241029541f..61c4ab9e23 100644 --- a/charts/kubedbcom-redis-editor/ui/edit-ui.yaml +++ b/charts/kubedbcom-redis-editor/ui/edit-ui.yaml @@ -1,1758 +1,946 @@ -steps: -- form: - elements: - - disabled: true - label: - text: labels.database.name - onChange: onNameChange - schema: - $ref: schema#/properties/metadata/properties/release/properties/name - type: input - - disabled: true - fetch: getResources|core|v1|namespaces - label: - text: labels.namespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/metadata/properties/release/properties/namespace - type: select - - disableUnselect: true - disabled: true - fetch: getRedisVersions|catalog.kubedb.com|v1alpha1|redisversions - label: - text: labels.database.version - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/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/kubedbComRedis/properties/metadata/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/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/kubedbComRedis/properties/metadata/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/properties/metadata/properties/annotations/additionalProperties - type: input - - hasDescription: true - label: - text: labels.deletionPolicy - 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/kubedbComRedis/properties/spec/properties/deletionPolicy - type: radio - - disabled: true - label: - text: labels.secret - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/properties/spec/properties/authSecret/properties/name - type: input - type: single-step-form - id: basic - title: steps.0.label -- form: - elements: - - alias: reusable_alert - chart: - name: uibytebuildersdev-component-alert - version: v0.29.0 - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/form/properties/alert - type: reusable-element - type: single-step-form - id: alert - title: labels.alert -- form: +type: multi-step-form +step: + - type: single-step-form + id: backupconfiguration + # label: Backup + schema: schema/ elements: - - if: isNotEqualToModelPathValue|Standalone|/resources/kubedbComRedis/spec/mode - label: - text: labels.to_update_disabled_section - type: label-element - - customClass: mb-20 - if: isNotEqualToModelPathValue|Standalone|/resources/kubedbComRedis/spec/mode - label: - text: labels.create_opsrequest - type: anchor - url: - params: - cluster: - $ref: store#/route/params/cluster - dbname: - $ref: model#/metadata/release/name - domain: - $ref: store#/domain - group: - $ref: model#/metadata/resource/group - kind: - $ref: model#/metadata/resource/kind - namespace: - $ref: model#/metadata/release/namespace - owner: - $ref: store#/route/params/user - resource: - $ref: model#/metadata/resource/name - version: - $ref: model#/metadata/resource/version - path: ${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/redisopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations - - computed: setDatabaseMode - disabled: true - hasDescription: true - label: - text: labels.database.mode - onChange: deleteDatabaseModePath + - type: radio + label: Schedule a Backup? + schema: temp/properties/scheduleBackup + isHorizontal: true options: - - description: options.database.mode.Standalone.description - text: options.database.mode.Standalone.label - value: Standalone - - description: options.database.mode.Cluster.description - text: options.database.mode.Cluster.label - value: Cluster - - description: options.database.mode.Sentinel.description - text: options.database.mode.Sentinel.label - value: Sentinel - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/properties/spec/properties/mode - type: radio - - disabled: true - elements: - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/properties/spec/properties/cluster/properties/replicas - type: input - - label: - text: labels.master - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/properties/spec/properties/cluster/properties/shards - type: input - if: isEqualToModelPathValue|Cluster|/resources/kubedbComRedis/spec/mode - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/properties/spec/properties/cluster - type: single-step-form - - disabled: true - if: isEqualToModelPathValue|Sentinel|/resources/kubedbComRedis/spec/mode - label: - text: labels.replicaset.number - minValue: 2 - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/properties/spec/properties/replicas - type: input - - disabled: true - discriminator: - createSentinel: - type: boolean + - text: 'Yes' + value: 'yes' + - text: 'No' + value: 'no' + if: + type: function + name: showScheduleBackup + init: + type: func + value: initScheduleBackupForEdit + watcher: + func: onScheduleBackupChange + paths: + - temp/properties/scheduleBackup + - type: block-layout + label: Backup Form + showLabels: false + loader: initBackupData + if: + type: function + name: showBackupForm elements: - - label: - text: labels.sentinel_section - type: label-element - - computed: setCreateSentinel - onChange: onCreateSentinelChange - options: - - text: options.sentinelType.existingSentinel.label - value: false - - text: options.sentinelType.customSentinel.label - value: true - schema: - $ref: discriminator#/properties/createSentinel - type: radio - - fetch: getResources|core|v1|namespaces - if: showSentinelNameAndNamespace - label: - text: labels.namespace - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/properties/spec/properties/sentinelRef/properties/namespace - type: select - - allowUserDefinedOption: true - fetch: getRedisSentinels - if: showSentinelNameAndNamespace - label: - text: labels.name - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/properties/spec/properties/sentinelRef/properties/name - type: select - if: isEqualToModelPathValue|Sentinel|/resources/kubedbComRedis/spec/mode - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/properties/spec/properties/sentinelRef - type: single-step-form - - disabled: true - elements: - - fetch: getStorageClassNames - label: - text: labels.storage.class - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/properties/spec/properties/storage/properties/storageClassName - type: select - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/properties/spec/properties/storage/properties/resources/properties/requests/properties/storage - type: input - if: isNotEqualToModelPathValue|Sentinel|/resources/kubedbComRedis/spec/mode - type: single-step-form - type: single-step-form - id: topology - title: steps.1.label -- form: - discriminator: - configureTLS: - default: true - type: boolean - elements: - - label: - text: labels.to_update_tls - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - params: - cluster: - $ref: store#/route/params/cluster - dbname: - $ref: model#/metadata/release/name - domain: - $ref: store#/domain - group: - $ref: model#/metadata/resource/group - kind: - $ref: model#/metadata/resource/kind - namespace: - $ref: model#/metadata/release/namespace - owner: - $ref: store#/route/params/user - resource: - $ref: model#/metadata/resource/name - version: - $ref: model#/metadata/resource/version - path: ${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/redisopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=ReconfigureTLS - - computed: isValueExistInModel|/resources/kubedbComRedis/spec/tls - disabled: true - label: - text: labels.enable_tls - onChange: onTlsConfigureChange - schema: - $ref: discriminator#/configureTLS - type: switch - - disabled: true - elements: - - elements: - - computed: setApiGroup - disabled: true - label: - text: labels.api_group - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup - type: input - - label: - text: labels.kind + - type: radio + label: Select Backup Type + schema: temp/properties/backupType + isHorizontal: true options: - - text: Issuer - value: Issuer - - text: ClusterIssuer - value: ClusterIssuer - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/properties/spec/properties/tls/properties/issuerRef/properties/kind - type: select - - allowUserDefinedOption: true - fetch: getIssuerRefsName - label: - text: labels.name - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/properties/spec/properties/tls/properties/issuerRef/properties/name - type: select - label: - text: labels.issuer_ref - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/properties/spec/properties/tls/properties/issuerRef - type: single-step-form - - alias: reusable_certificates - chart: - name: uibytebuildersdev-component-certificates - version: v0.29.0 - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/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: + - text: BackupConfig + value: BackupConfig + description: 'Create, Delete or Modify BackupConfig' + - text: BackupBlueprint + value: BackupBlueprint + description: Enable/Disable BackupBlueprint + if: + type: function + name: isBackupDataLoadedTrue + init: + type: func + value: setBackupType + loader: getTypes + watcher: + func: onBackupTypeChange + paths: + - temp/properties/backupType + - type: block-layout + label: Config + if: + type: function + name: isBackupType|BackupConfig + elements: + - type: select + label: Select Context + schema: temp/properties/backupConfigContext + validation: + type: required + loader: getContext + watcher: + func: onContextChange + paths: + - temp/properties/backupConfigContext + - type: select + label: Select BackupConfig + schema: temp/properties/config + validation: + type: required + if: + type: function + name: showConfigList + loader: getConfigList + watcher: + func: onConfigChange + paths: + - temp/properties/config + - type: input + label: Schedule + schema: temp/properties/schedule + validation: + type: required + if: + type: function + name: showSchedule + loader: + name: getDefaultSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions + watchPaths: + - temp/properties/config + watcher: + func: onInputChangeSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions|schedule + paths: + - temp/properties/schedule + - type: switch + label: Paused + fullwidth: true + schema: schema/properties/resources/properties/coreKubestashComBackupConfiguration/properties/spec/properties/paused + if: + type: function + name: showPause + watcher: + func: setPausedValue + paths: + - temp/properties/config + init: + type: func + value: setPausedValue + - type: block-layout + label: Blueprint + if: + type: function + name: isBackupType|BackupBlueprint + elements: + - type: switch + label: Enable Backup Blueprint + fullwidth: true + schema: temp/properties/blueprintEnabled + init: + type: func + value: setBlueprintSwitch + watcher: + func: onBlueprintChange + paths: + - temp/properties/blueprintEnabled + - type: block-layout + label: Archiver + if: + type: function + name: isBackupType|Archiver + elements: + - type: switch + label: Enable Archiver + fullwidth: true + schema: temp/properties/archiverEnabled + init: + type: func + value: setArchiverSwitch + watcher: + func: onArchiverChange + paths: + - temp/properties/archiverEnabled + + - type: single-step-form + id: compute-autoscaler + loader: getDbDetails elements: - - disabled: disableInitializationSection - discriminator: - prePopulateDatabase: - type: string - elements: - - computed: initPrePopulateDatabase - label: - text: labels.prePopulateDatabase - onChange: onPrePopulateDatabaseChange + - type: block-layout + if: + type: function + name: isConsole + elements: + - type: input + label: Name + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/metadata/properties/name + - type: select + label: Select Namespace + loader: getNamespaces + if: + type: function + name: isRancherManaged + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/metadata/properties/namespace + - type: select + label: Select Db + validation: + type: required + refresh: true + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/databaseRef/properties/name + watcher: + func: initMetadata + paths: + - schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/databaseRef/properties/name + + - type: radio + if: + type: function + name: isConsole + label: Select Type + validation: + type: required + schema: temp/properties/autoscalingType + watcher: + func: initMetadata + paths: + - temp/properties/autoscalingType 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 + - text: Compute + value: compute + description: Scale your CPU Memory based on resource usage + - text: Storage + value: storage + description: Expand your database size based on volume usage + + - type: block-layout + showLabels: false + loader: fetchTopologyMachines 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/kubedbComRedis/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/kubedbComRedis/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/kubedbComRedis/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 + # standalone mode + - type: switch + label: Trigger + fullwidth: true + if: + type: function + name: dbTypeEqualsTo|standalone + init: + type: func + value: setTrigger|autoscalingKubedbComRedisAutoscaler/spec/compute/standalone/trigger + schema: temp/properties/compute/properties/standalone/properties/trigger + watcher: + func: onTriggerChange|compute/standalone + paths: + - temp/properties/compute/properties/standalone/properties/trigger + - type: label-element + label: Pod lifetime threshold + subtitle: Specifies the duration a pod can exist before being considered for autoscaling. This helps prevent frequent scaling operations on short-lived pods. + if: + type: function + name: dbTypeEqualsTo|standalone + - type: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + customClass: width-300 + if: + type: function + name: dbTypeEqualsTo|standalone + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/standalone/properties/podLifeTimeThreshold + - type: block-layout + label: Standalone + showLabels: true + if: + type: function + name: dbTypeEqualsTo|standalone + # schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/standalone 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.29.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 + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/standalone/properties/resourceDiffPercentage + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources for autoscaling. The autoscaler will keep resource allocation within these bounds. + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|standalone|min + loader: + name: getMachines|standalone|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-max + watcher: + func: onMachineChange|standalone + paths: + - temp/properties/allowedMachine-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/standalone/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/standalone/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|standalone|max + loader: + name: getMachines|standalone|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-min + watcher: + func: onMachineChange|standalone + paths: + - temp/properties/allowedMachine-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/standalone/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/standalone/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|standalone + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/standalone/properties/controlledResources + + # cluster mode + - type: switch + label: Trigger + fullwidth: true + if: + type: function + name: dbTypeEqualsTo|cluster + init: + type: func + value: setTrigger|autoscalingKubedbComRedisAutoscaler/spec/compute/cluster/trigger + schema: temp/properties/compute/properties/cluster/properties/trigger + watcher: + func: onTriggerChange|compute/cluster + paths: + - temp/properties/compute/properties/cluster/properties/trigger + - type: label-element + label: Pod lifetime threshold + subtitle: Specifies the duration a pod can exist before being considered for autoscaling. This helps prevent frequent scaling operations on short-lived pods. + if: + type: function + name: dbTypeEqualsTo|cluster + - type: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + customClass: width-300 + if: + type: function + name: dbTypeEqualsTo|cluster + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/cluster/properties/podLifeTimeThreshold + - type: block-layout + label: Cluster + showLabels: true + if: + type: function + name: dbTypeEqualsTo|cluster + # schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/cluster 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.29.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/kubedbComRedis/properties/spec/properties/init/properties/waitForInitialRestore - type: switch - if: showInitializationForm - type: single-step-form - type: single-step-form - type: single-step-form - id: initialization - title: steps.3.label -- form: - discriminator: - repoInitialSelectionStatus: - type: string - scheduleBackup: - default: "yes" - type: string - elements: - - computed: initScheduleBackupForEdit - if: showScheduleBackup - 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: - backupType: - type: string - isBackupDataLoaded: - default: false - type: boolean - elements: - - computed: initBackupData - if: returnFalse - type: input - - computed: setBackupType - fetch: getTypes - hasDescription: true - if: isBackupDataLoadedTrue - label: - text: Select Backup Type - onChange: onBackupTypeChange - schema: - $ref: discriminator#/backupType - type: radio - - discriminator: - backupConfigContext: - type: string - config: - type: string - paused: - default: false - type: boolean - schedule: - type: string - elements: - - fetch: getContext - label: - text: Select Context - onChange: onContextChange - required: true - schema: - $ref: discriminator#/backupConfigContext - type: select - - fetch: getConfigList - if: showConfigList - label: - text: Select BackupConfig - onChange: onConfigChange - required: true - schema: - $ref: discriminator#/config - type: select - - computed: getDefaultSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions - if: showSchedule - label: - text: Schedule - onChange: onInputChangeSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions|schedule - required: true - schema: - $ref: discriminator#/schedule - type: input - - if: showPause - label: - text: Paused - schema: - $ref: schema#/properties/resources/properties/coreKubestashComBackupConfiguration/properties/spec/properties/paused - type: switch - if: isBackupType|BackupConfig - type: single-step-form - - discriminator: - blueprintEnabled: - default: false - type: boolean - elements: - - computed: setBlueprintSwitch - label: - text: Enable Backup Blueprint - onChange: onBlueprintChange - schema: - $ref: discriminator#/blueprintEnabled - type: switch - if: isBackupType|BackupBlueprint - type: single-step-form - - discriminator: - archiverEnabled: - default: false - type: boolean - elements: - - computed: setArchiverSwitch - label: - text: Enable Archiver - onChange: onArchiverChange - schema: - $ref: discriminator#/archiverEnabled - type: switch - if: isBackupType|Archiver - 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 + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/cluster/properties/resourceDiffPercentage + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources for autoscaling. The autoscaler will keep resource allocation within these bounds. + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|cluster|min + loader: + name: getMachines|cluster|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-max + watcher: + func: onMachineChange|cluster + paths: + - temp/properties/allowedMachine-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/cluster/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/cluster/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|cluster|max + loader: + name: getMachines|cluster|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-min + watcher: + func: onMachineChange|cluster + paths: + - temp/properties/allowedMachine-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/cluster/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/cluster/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|cluster + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/cluster/properties/controlledResources + + # sentinel mode + - type: block-layout + label: Sentinel + showLabels: true + if: + type: function + name: dbTypeEqualsTo|sentinel + # schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/sentinel + elements: + - type: select + label: Trigger + init: + type: func + value: setTrigger|autoscalingKubedbComRedisAutoscaler/spec/compute/sentinel/trigger + options: + - text: 'On' + value: 'On' + - text: 'Off' + value: 'Off' + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/sentinel/properties/trigger + - type: input + label: Pod LifeTime Threshold + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/sentinel/properties/podLifeTimeThreshold + - type: threshold-input + label: Resource Diff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/sentinel/properties/resourceDiffPercentage + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|min + loader: + name: getMachines|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-max + watcher: + func: onMachineChange|sentinel + paths: + - temp/properties/allowedMachine-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/sentinel/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/sentinel/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|max + loader: + name: getMachines|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-min + watcher: + func: onMachineChange|sentinel + paths: + - temp/properties/allowedMachine-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/sentinel/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/sentinel/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|sentinel + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/sentinel/properties/controlledResources + + - type: block-layout + label: Node Topology + if: + type: function + name: hasNoAnnotations + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/nodeTopology + elements: + - type: select + label: Select NodeTopology + loader: fetchNodeTopology + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name + - type: threshold-input + label: ScaleUp Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage + - type: threshold-input + label: ScaleDown Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage + + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + # schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/opsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: storage-autoscaler elements: - - label: - text: labels.to_update_exporter_resources - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - function: getOpsRequestUrl|VerticalScaling - - computed: isValueExistInModel|/resources/kubedbComRedis/spec/monitor - label: - text: labels.enable_monitoring - onChange: onEnableMonitoringChange - schema: - $ref: discriminator#/enableMonitoring - type: switch - - discriminator: - customizeExporter: - default: true - type: boolean + - type: block-layout + showLabels: false 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/kubedbComRedis/properties/spec/properties/monitor/properties/agent - type: radio - - elements: - - label: - text: labels.scrapping_interval - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval - type: input - if: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComRedis/spec/monitor/agent - label: - text: labels.service_monitor_configuration - show_label: true - type: single-step-form - - elements: - - elements: - - addFormLabel: labels.endpoint - element: + - type: block-layout + showLabels: false + elements: + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComRedisAutoscaler/spec/storage/redis/trigger + schema: temp/properties/storage/properties/redis/properties/trigger + watcher: + func: onTriggerChange|storage/redis + paths: + - temp/properties/storage/properties/redis/properties/trigger + - type: label-element + label: Expansion Mode (Online/Offline) + subtitle: For Online Mode enables scaling without downtime by dynamically resizing volumes. Offline Mode requires brief downtime but ensures data integrity during expansion. + - type: select + label: Mode + description: Select how the storage expansion should be handled. Online mode allows expansion without downtime, while Offline mode may require a restart. + options: + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/redis/properties/expansionMode + - type: block-layout + label: Cluster + showLabels: true 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/kubedbComRedis/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/kubedbComRedis/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: - - if: returnFalse - label: - text: labels.resources - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/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/kubedbComRedis/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/kubedbComRedis/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup - type: input - - label: - text: labels.port - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/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/kubedbComRedis/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args/items - type: input - label: - text: labels.args - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args - type: list-input-form - - alias: reusable_env - chart: - name: uibytebuildersdev-component-env - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/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: - - elements: - - alias: pod_template_standalone - chart: - name: uibytebuildersdev-component-pod-template - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - functionCallbacks: - isEditWizard: - $ref: functions#/returnTrue - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/properties/spec/properties/podTemplate - type: reusable-element - type: single-step-form - 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.29.0 - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/properties/spec/properties/serviceTemplates - type: reusable-element - type: single-step-form - id: networking - title: steps.7.label -- form: - elements: - - elements: - - discriminator: - configuration: - type: string - configurationSource: - default: use-existing-config - type: string - elements: - - label: - text: labels.to_update_config - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - params: - cluster: - $ref: store#/route/params/cluster - dbname: - $ref: model#/metadata/release/name - domain: - $ref: store#/domain - group: - $ref: model#/metadata/resource/group - kind: - $ref: model#/metadata/resource/kind - namespace: - $ref: model#/metadata/release/namespace - owner: - $ref: store#/route/params/user - resource: - $ref: model#/metadata/resource/name - version: - $ref: model#/metadata/resource/version - path: ${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/redisopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=Reconfigure - - disabled: true - 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 - disabled: true - fetch: getSecrets - if: isEqualToDiscriminatorPath|use-existing-config|/configurationSource - label: - text: labels.name - schema: - $ref: schema#/properties/resources/properties/kubedbComRedis/properties/spec/properties/configSecret/properties/name - type: select - type: single-step-form - type: single-step-form - type: single-step-form - id: custom-config - title: steps.8.label -- form: - discriminator: - dbDetails: - default: false - type: boolean + - type: threshold-input + label: UsageThreshold (%) + subtitle: Set the threshold percentage of storage usage that triggers autoscaling + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/redis/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + init: + type: func + value: setValueFromDbDetails|resources/kubedbComRedis/spec/storage/resources/requests/storage + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/redis/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComRedis/spec/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComRedisAutoscaler/spec/storage/redis/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/redis/properties/scalingRules + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/redis/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComRedisAutoscaler/spec/storage/redis/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/redis/properties/upperBound + - type: block-layout + label: OpsRequest Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: monitoring + loader: initMonitoring elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: Select Db - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: Select Type - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - discriminator: - topologyMachines: - default: [] - type: array + - type: label-element + label: To update Exporter Resource section click on Create OpsRequest + - type: anchor + label: Create OpsRequest + schema: temp/properties/opsRequestUrl + init: + type: func + value: getOpsRequestUrl|scale-vertically + - type: switch + label: Enable Monitoring + fullwidth: true + schema: temp/properties/enableMonitoring + init: + type: func + value: isValueExistInModel|/resources/kubedbComRedis/spec/monitor + watcher: + func: onEnableMonitoringChange + paths: + - temp/properties/enableMonitoring + - type: block-layout + if: + type: function + name: showMonitoringSection elements: - - fetch: fetchTopologyMachines - if: returnFalse - schema: - $ref: discriminator#/topologyMachines - type: input - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComRedisAutoscaler/spec/compute/standalone/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/standalone/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/standalone/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/standalone/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-max: - type: string - allowedMachine-min: - type: string - elements: - - computed: setAllowedMachine|min - disableUnselect: true - fetch: getMachines|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|standalone - schema: - $ref: discriminator#/properties/allowedMachine-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/standalone/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/standalone/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/standalone/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|max - disableUnselect: true - fetch: getMachines|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|standalone - schema: - $ref: discriminator#/properties/allowedMachine-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/standalone/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/standalone/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/standalone/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|standalone - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/standalone/properties/controlledResources - type: multiselect - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/standalone - type: single-step-form - if: dbTypeEqualsTo|standalone - label: - text: Standalone - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/standalone - show_label: true - type: single-step-form - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComRedisAutoscaler/spec/compute/cluster/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/cluster/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/cluster/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/cluster/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-max: - type: string - allowedMachine-min: - type: string - elements: - - computed: setAllowedMachine|min - disableUnselect: true - fetch: getMachines|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|cluster - schema: - $ref: discriminator#/properties/allowedMachine-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/cluster/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/cluster/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/cluster/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|max - disableUnselect: true - fetch: getMachines|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|cluster - schema: - $ref: discriminator#/properties/allowedMachine-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/cluster/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/cluster/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/cluster/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|cluster - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/cluster/properties/controlledResources - type: multiselect - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/cluster - type: single-step-form - if: dbTypeEqualsTo|cluster - label: - text: Cluster - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/cluster - show_label: true - type: single-step-form - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComRedisAutoscaler/spec/compute/sentinel/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/sentinel/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/sentinel/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/sentinel/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-max: - type: string - allowedMachine-min: - type: string - elements: - - computed: setAllowedMachine|min - disableUnselect: true - fetch: getMachines|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|sentinel - schema: - $ref: discriminator#/properties/allowedMachine-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/sentinel/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/sentinel/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/sentinel/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|max - disableUnselect: true - fetch: getMachines|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|sentinel - schema: - $ref: discriminator#/properties/allowedMachine-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/sentinel/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/sentinel/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/sentinel/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|sentinel - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/sentinel/properties/controlledResources - type: multiselect - label: - text: Sentinel - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/sentinel - show_label: true - type: single-step-form - if: dbTypeEqualsTo|sentinel - type: single-step-form - - elements: - - fetch: fetchNodeTopology - label: - text: SelectNodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name - type: select - - if: isNodeTopologySelected - label: - text: ScaleUp Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage - type: input - - if: isNodeTopologySelected - label: - text: ScaleDown Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage - type: input - if: hasNoAnnotations - label: - text: NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/nodeTopology - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: compute-autoscaler - title: steps.9.label -- form: - discriminator: - dbDetails: - default: false - type: boolean - elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - computed: getDbDetails - if: returnFalse - type: input - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: Select Db - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: Select Type - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComRedisAutoscaler/spec/storage/standalone/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/standalone/properties/trigger - type: select - - label: - text: Expansion Mode + - type: radio + label: Select a Monitoring Method + schema: schema/properties/resources/properties/kubedbComRedis/properties/spec/properties/monitor/properties/agent + isHorizontal: true options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/standalone/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/standalone/properties/usageThreshold - type: input - - addFormLabel: ScalingRules - element: + - text: Prometheus Operator + value: prometheus.io/operator + description: Inject metric exporter sidecar and creates a ServiceMonitor + - text: Custom ServiceMonitor + value: prometheus.io + description: Injects the metric exporter sidecar and let you customize ServiceMonitor + - text: Custom Scrapper + value: prometheus.io/builtin + description: Inject metric exporter sidecar and add Prometheus annotations to the stats Service + init: + type: static + value: prometheus.io/operator + watcher: + func: onAgentChange + paths: + - schema/properties/resources/properties/kubedbComRedis/properties/spec/properties/monitor/properties/agent + - type: block-layout + label: ServiceMonitor Configuration + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComRedis/spec/monitor/agent + elements: + - label: Scrapping Interval + schema: schema/properties/resources/properties/kubedbComRedis/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval + type: input + - type: block-layout + label: Service Monitor + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComRedis/spec/monitor/agent + elements: + - type: array-object-form + label: Endpoints + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/endpoints elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/standalone/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/standalone/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComRedisAutoscaler/spec/storage/standalone/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/standalone/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComRedisAutoscaler/spec/storage/standalone/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/standalone/properties/upperBound - type: input - if: dbTypeEqualsTo|standalone - label: - text: Standalone - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/standalone - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComRedisAutoscaler/spec/storage/cluster/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/cluster/properties/trigger - type: select - - label: - text: Expansion Mode - options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/cluster/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/cluster/properties/usageThreshold - type: input - - addFormLabel: Scaling Rules - element: + - type: switch + label: Honor labels + fullwidth: true + schema: honorLabels + - type: input + label: Interval + schema: interval + validation: + type: required + - type: input + label: Path + schema: path + validation: + type: required + - type: input + label: Port + schema: port + validation: + type: required + - type: select + multiple: true + label: Match Namespaces + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/namespaceSelector/properties/matchNames + loader: getResources|core|v1|namespaces + if: + type: function + name: returnFalse + - type: block-layout + showLabels: false + # schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector + if: + type: function + name: returnFalse elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/cluster/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/cluster/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: Scaling Rules - onChange: handleUnit|autoscalingKubedbComRedisAutoscaler/spec/storage/cluster/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/cluster/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComRedisAutoscaler/spec/storage/cluster/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/cluster/properties/upperBound - type: input - if: dbTypeEqualsTo|cluster - label: - text: Cluster - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/compute/properties/cluster - show_label: true - type: single-step-form - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComRedisAutoscaler/spec/storage/sentinel/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/sentinel/properties/trigger - type: select - - label: - text: Expansion Mode - options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/sentinel/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/sentinel/properties/usageThreshold - type: input - - addFormLabel: Scaling Rules - element: - elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/sentinel/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/sentinel/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComRedisAutoscaler/spec/storage/sentinel/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/sentinel/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComRedisAutoscaler/spec/storage/sentinel/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/sentinel/properties/upperBound - type: input - label: - text: Sentinel - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/sentinel - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComRedisAutoscaler/spec/storage/sentinel/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/sentinel/properties/trigger - type: select - - label: - text: Expansion Mode - options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/sentinel/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/sentinel/properties/usageThreshold - type: input - - addFormLabel: ScalingRules - element: - elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/sentinel/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/sentinel/properties/scalingRules/items/properties/threshold + - type: object-item + label: Labels + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector/properties/matchLabels + - type: object-item + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/metadata/properties/labels + label : Labels + buttonClass: is-light is-outlined + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComRedis/spec/monitor/agent + # individualItemDisabilityCheck: disableLableChecker + - type: label-element + label: Exporter Configuration + schema: '' + - type: switch + label: Customize Exporter Sidecar + fullwidth: true + schema: temp/properties/customizeExporter + init: + type: static + value: true + watcher: + func: onCustomizeExporterChange + paths: + - temp/properties/customizeExporter + - type: block-layout + label: Customer Exporter Section + showLabels: false + if: + type: function + name: showCustomizeExporterSection + elements: + - type: machine-compare + label: Resources + schema: schema/properties/resources/properties/kubedbComRedis/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/resources + if: + type: function + name: returnFalse + - type: label-element + label: Security Context + schema: '' + - type: input + schema: schema/properties/resources/properties/kubedbComRedis/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsUser + label: Run as User + - type: input + schema: schema/properties/resources/properties/kubedbComRedis/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup + label: Run as Group + - type: input + schema: schema/properties/resources/properties/kubedbComRedis/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/port + label: Port + - type: array-item-form + label: Args + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/kubedbComRedis/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args + init: + type: static + value: ['--compatible-mode'] + element: type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComRedisAutoscaler/spec/storage/sentinel/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/sentinel/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComRedisAutoscaler/spec/storage/sentinel/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/sentinel/properties/upperBound - type: input - label: - text: ConfigServer - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/storage/properties/sentinel - show_label: true - type: single-step-form - if: dbTypeEqualsTo|sentinel - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComRedisAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: storage-autoscaler - title: steps.10.label -- form: - discriminator: - binding: - default: false - type: boolean + label: Args + # isSubsection: true + - type: block-layout + label: Metadata + showLabels: false + elements: + - type: array-object-form + init: + type: func + value: initEnvArray + label: Environment Variables + buttonClass: is-light is-outlined + watcher: + func: onEnvArrayChange + paths: + - temp/properties/env + schema: temp/properties/env + elements: + - type: input + label: Name + schema: name + validation: + type: required + - type: radio + label: Value From + schema: temp/properties/valueFromType + validation: + type: required + init: + type: func + value: setValueFrom + options: + - text: Input + value: input + - text: Secret + value: secret + - text: ConfigMap + value: configMap + watcher: + func: onValueFromChange + paths: + - temp/properties/valueFromType + - type: input + label: Value + schema: value + validation: + type: required + if: + name: isEqualToTemp|input + type: function + - type: select + if: + type: function + name: isEqualToTemp|configMap + label: ConfigMap Name + schema: valueFrom/properties/configMapKeyRef/properties/name + loader: + name: resourceNames|core|v1|configmaps + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: ConfigMap Key + schema: valueFrom/properties/configMapKeyRef/properties/key + if: + type: function + name: isEqualToTemp|configMap + loader: + name: getConfigMapKeys + watchPaths: + - schema/resources/kubedbComRedis/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/configMapKeyRef/name + - schema/metadata/release/namespace + - type: select + label: Secret Name + schema: valueFrom/properties/secretKeyRef/properties/name + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecrets + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: Secret Key + schema: valueFrom/properties/secretKeyRef/properties/key + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecretKeys + watchPaths: + - schema/resources/kubedbComRedis/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/secretKeyRef/name + - schema/metadata/release/namespace + + - type: single-step-form + id: binding elements: - - computed: isBindingAlreadyOn - label: - text: Expose Database - onChange: addOrRemoveBinding - schema: - $ref: discriminator#/properties/binding - type: switch - type: single-step-form - id: binding - title: Gateway Binding -type: multi-step-form + - type: switch + label: Expose Database + schema: temp/properties/binding + fullwidth: true + init: + type: func + value: isBindingAlreadyOn + watcher: + func: addOrRemoveBinding + paths: + - temp/properties/binding \ No newline at end of file diff --git a/charts/kubedbcom-redis-editor/ui/functions.js b/charts/kubedbcom-redis-editor/ui/functions.js index 25e7490fe0..13d3a2cc50 100644 --- a/charts/kubedbcom-redis-editor/ui/functions.js +++ b/charts/kubedbcom-redis-editor/ui/functions.js @@ -1,2886 +1,1593 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + // ************************* common functions ******************************************** // eslint-disable-next-line no-empty-pattern -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}`, +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', '') + + function initScheduleBackupForEdit() { + const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( + getValue, + model, ) - // 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, + initRepositoryChoiseForEdit() + + if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' + else return 'no' } -} -function disableLableChecker({ itemCtx }) { - const { key } = itemCtx - if (key.startsWith('app.kubernetes.io') || key.includes('helm')) return true - else return false -} + function initScheduleBackup() { + const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( + getValue, + model, + ) -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} + if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' + else return 'no' + } -function isNotEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue !== value -} + function onScheduleBackupChange() { + const scheduleBackup = getValue(discriminator, '/scheduleBackup') -async function getResources({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + if (scheduleBackup === 'no') { + // delete stashAppscodeComBackupConfiguration + commit('wizard/model$delete', '/resources/stashAppscodeComBackupConfiguration') + commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') + // delete annotation from kubedbComRedis annotation + deletekubedbComRedisAnnotation(getValue, model, commit) + } else { + const { isBluePrint } = getBackupConfigsAndAnnotations(getValue, model) - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + // create stashAppscodeComBackupConfiguration and initialize it if not exists - const resources = (resp && resp.data && resp.data.items) || [] + const dbName = getValue(model, '/metadata/release/name') - 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 [] + 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 isEqualToDiscriminatorPath( - { discriminator, getValue, watchDependency }, - value, - discriminatorPath, -) { - watchDependency('discriminator#' + discriminatorPath) - const discriminatorValue = getValue(discriminator, discriminatorPath) - return discriminatorValue === value -} -function setValueFromModel({ getValue, model }, path) { - return getValue(model, path) -} + function valueExists(value, getValue, path) { + const val = getValue(value, path) + if (val) return true + else return false + } -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function deletekubedbComRedisAnnotation(getValue, model, commit) { + const annotations = getValue(model, '/resources/kubedbComRedis/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/kubedbComRedis/metadata/annotations', + value: filteredAnnotations, + }) + } - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + function getBackupConfigsAndAnnotations(getValue, model) { + const stashAppscodeComBackupConfiguration = getValue( + model, + '/resources/stashAppscodeComBackupConfiguration', + ) + const kubedbComRedisAnnotations = + getValue(model, '/resources/kubedbComRedis/metadata/annotations') || {} - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }) + const isBluePrint = Object.keys(kubedbComRedisAnnotations).some( + (k) => + k === 'stash.appscode.com/backup-blueprint' || + k === 'stash.appscode.com/schedule' || + k.startsWith('params.stash.appscode.com/'), + ) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + return { + stashAppscodeComBackupConfiguration, + isBluePrint, + } } - return ans -} - -async function getRedisSentinels({ axios, storeGet, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/resources/kubedbComRedis/spec/sentinelRef/namespace') + // backup form + function showBackupForm() { + const scheduleBackup = getValue(discriminator, '/scheduleBackup') + // watchDependency('discriminator#/scheduleBackup') + if (scheduleBackup === 'yes') return true + else return false + } - watchDependency('model#/resources/kubedbComRedis/spec/sentinelRef/namespace') + 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/kubedbComRedis') + initialDbMetadata = objectCopy(dbResource.metadata) + initialArchiver = dbResource.spec?.archiver ? objectCopy(dbResource.spec?.archiver) : undefined - if (owner && cluster && namespace) { + // get values.yaml to populate data when backup-config is being created try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redissentinels`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + 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 - const resources = (resp && resp.data && resp.data.items) || [] + let url = `/clusters/${user}/${cluster}/helm/packageview/values?name=${chartName}&sourceApiGroup=${sourceApiGroup}&sourceKind=${sourceKind}&sourceNamespace=${sourceNamespace}&sourceName=${sourceName}&version=${chartVersion}&format=json` - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) + if (spoke) + url = `/clusters/${user}/${spoke}/helm/packageview/values?name=${chartName}&sourceApiGroup=${sourceApiGroup}&sourceKind=${sourceKind}&sourceNamespace=${sourceNamespace}&sourceName=${sourceName}&version=${chartVersion}&format=json` - return resources - } catch (err) { - console.log(err) - return [] + const resp = await axios.get(url) + + valuesFromWizard = objectCopy(resp.data?.resources?.coreKubestashComBackupConfiguration) || {} + } catch (e) { + console.log(e) } - } else { - return [] - } -} -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` + // 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) + } + } - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }) + // 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, + ) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) - } + // 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, + ) - return ans -} + // set backup switch here + isBackupOn = !!config -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - 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) - }) - } + // set initial data from stash-presets + const stashPreset = storeGet('/backup/stashPresets') + if (stashPreset) { + const { retentionPolicy, encryptionSecret, schedule, storageRef } = stashPreset - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + const tempBackends = valuesFromWizard.spec?.backends + tempBackends[0]['storageRef'] = storageRef + tempBackends[0]['retentionPolicy'] = retentionPolicy + valuesFromWizard.spec['backends'] = tempBackends -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) - - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) - } + 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}` - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + tempSessions[0]['repositories'] = tempRepositories + tempSessions[0]['scheduler']['schedule'] = schedule + valuesFromWizard.spec['sessions'] = tempSessions } - }) -} - -function returnTrue() { - return true -} -function returnStringYes() { - return 'yes' -} - -function hasSentinelObject({ model, getValue }) { - const sentinelObj = getValue(model, '/resources/kubedbComRedisSentinel_sentinel') + 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, + } - return !!sentinelObj -} + setDiscriminatorValue('isBackupDataLoaded', true) + } -// ************************* Basic Info ********************************************** -async function getRedisVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function isBackupDataLoadedTrue() { + // watchDependency('discriminator#/isBackupDataLoaded') + return !!getValue(discriminator, '/isBackupDataLoaded') + } - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, - }, - }, + function setBackupType() { + return 'BackupConfig' } - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + function getTypes() { + const arr = [ { - params: queryParams, + description: 'Create, Delete or Modify BackupConfig', + text: 'BackupConfig', + value: 'BackupConfig', }, - ) - - const resources = (resp && resp.data && resp.data.items) || [] - - // keep only non deprecated versions - const filteredRedisVersions = resources.filter((item) => item.spec && !item.spec.deprecated) + { + description: 'Enable/Disable BackupBlueprint', + text: 'BackupBlueprint', + value: 'BackupBlueprint', + }, + ] - filteredRedisVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredRedisVersions - } catch (e) { - console.log(e) - return [] + if ((dbResource?.spec?.replicaSet || dbResource?.spec?.shardTopology) && isArchiverAvailable) { + arr.push({ + description: 'Enable/Disable Archiver', + text: 'Archiver', + value: 'Archiver', + }) + } + return arr } -} -function onVersionChange({ model, getValue, commit }) { - const version = getValue(model, '/resources/kubedbComRedis/spec/version') - - if (hasSentinelObject({ model, getValue })) { + function onBackupTypeChange() { + const type = getValue(discriminator, '/backupType') commit('wizard/model$update', { - path: '/resources/kubedbComRedisSentinel_sentinel/spec/version', - value: version, + path: '/backupType', + value: type, force: true, }) - } -} - -let storageClassList = [] -function ondeletionPolicyChange({ model, getValue, commit }) { - const deletionPolicy = getValue(model, '/resources/kubedbComRedis/spec/deletionPolicy') - - if (hasSentinelObject({ model, getValue })) { + 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/kubedbComRedisSentinel_sentinel/spec/deletionPolicy', - value: deletionPolicy, + path: '/resources/kubedbComRedis', + value: objectCopy(dbResource), force: true, }) } - setStorageClass({ model, getValue, commit }) -} + function isBackupType(type) { + // watchDependency('discriminator#/backupType') + const selectedType = getValue(discriminator, '/backupType') -// ************************* Auth Secret Field ****************************************** -function showAuthPasswordField({ model, getValue, watchDependency }) { - watchDependency('model#/resources') - const modelPathValue = getValue(model, '/resources') - return !!( - modelPathValue && - modelPathValue.secret && - modelPathValue.secret.metadata && - modelPathValue.secret.metadata.name && - !showAuthSecretField({ model, getValue, watchDependency }) - ) -} + return selectedType === type + } -function showAuthSecretField({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComRedis/spec') - const modelPathValue = getValue(model, '/resources/kubedbComRedis/spec') - return !!(modelPathValue && modelPathValue.authSecret && modelPathValue.authSecret.name) -} + function setBlueprintSwitch() { + const annotations = initialDbMetadata?.annotations -function showNewSecretCreateField({ model, getValue, watchDependency, commit }) { - const resp = - !showAuthSecretField({ model, getValue, watchDependency }) && - !showAuthPasswordField({ model, getValue, watchDependency }) - const secret = getValue(model, '/resources/secret_auth') - if (resp && !secret) { - commit('wizard/model$update', { - path: '/resources/secret_auth', - value: { - data: { - password: '', - }, - }, - force: true, - }) + return !!( + annotations['blueprint.kubestash.com/name'] && + annotations['blueprint.kubestash.com/namespace'] + ) } - return resp -} -// ********************* Database Mode *********************** -function setDatabaseMode({ model, getValue }) { - const mode = getValue(model, '/resources/kubedbComRedis/spec/mode') + function onBlueprintChange() { + const blueprintSwitch = getValue(discriminator, '/blueprintEnabled') + if (blueprintSwitch) addLabelAnnotation('annotations') + else deleteLabelAnnotation('annotations') + } - return mode || 'Standalone' -} + function setArchiverSwitch() { + const archiver = dbResource?.spec?.archiver + return !!archiver + } -async function getStorageClassNames({ axios, storeGet, commit, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function onArchiverChange() { + const archiverSwitch = getValue(discriminator, '/archiverEnabled') + const path = 'resources/kubedbComRedis/spec/archiver' + if (archiverSwitch) { + commit('wizard/model$update', { + path: path, + value: initialArchiver ? initialArchiver : archiverObjectToCommit, + }) + } else { + commit('wizard/model$delete', path) + } + } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/storage.k8s.io/v1/storageclasses`, - { - params: { - filter: { items: { metadata: { name: null, annotations: null } } }, - }, - }, - ) + function addLabelAnnotation(type) { + const obj = objectCopy(initialDbMetadata[type]) - const resources = (resp && resp.data && resp.data.items) || [] + 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' + } - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) + commit('wizard/model$update', { + path: `/resources/kubedbComRedis/metadata/${type}`, + value: obj, + force: true, + }) + } - storageClassList = resources - const initialStorageClass = getValue( - model, - '/resources/kubedbComRedis/spec/storage/storageClassName', - ) - if (!initialStorageClass) setStorageClass({ model, getValue, commit }) - return resources -} + function deleteLabelAnnotation(type) { + const obj = initialDbMetadata[type] -function setStorageClass({ model, getValue, commit }) { - const deletionPolicy = getValue(model, '/resources/kubedbComRedis/spec/deletionPolicy') || '' - let storageClass = - getValue(model, '/resources/kubedbComRedis/spec/storage/storageClassName') || '' - const suffix = '-retain' + if (type === 'annotations') { + delete obj['blueprint.kubestash.com/name'] + delete obj['blueprint.kubestash.com/namespace'] + } else delete obj['kubedb.com/archiver'] - const simpleClassList = storageClassList.filter((item) => { - return !item.metadata?.name?.endsWith(suffix) - }) + commit('wizard/model$update', { + path: `/resources/kubedbComRedis/metadata/${type}`, + value: obj, + force: true, + }) + } - const retainClassList = storageClassList.filter((item) => { - return item.metadata?.name?.endsWith(suffix) - }) + function getContext() { + if (isBackupOn) return ['Create', 'Delete', 'Modify'] + return ['Create'] + } - const defaultSimpleList = simpleClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] - ) - }) + 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) + } - const defaultRetainList = retainClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] + 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, ) - }) - - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - if (simpleClassList.length > 1) { - const found = defaultSimpleList.length ? defaultSimpleList[0] : simpleClassList[0] - storageClass = found.value - } else if (simpleClassList.length === 1) { - storageClass = simpleClassList[0]?.value - } else { - const found = defaultRetainList.length - ? defaultRetainList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found - } - } else { - if (retainClassList.length > 1) { - const found = defaultRetainList.length ? defaultRetainList[0] : retainClassList[0] - storageClass = found.value - } else if (retainClassList.length === 1) { - storageClass = retainClassList[0]?.value - } else { - const found = defaultSimpleList.length - ? defaultSimpleList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found - } + const list = filteredList?.map((ele) => ele.metadata.name) + return list } - if (storageClass) { + 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/kubedbComRedis/spec/storage/storageClassName', - value: storageClass, + path: '/resources/coreKubestashComBackupConfiguration', + value: configDetails, force: true, }) } -} -function deleteDatabaseModePath({ getValue, commit, model }) { - const mode = getValue(model, '/resources/kubedbComRedis/spec/mode') - if (mode === 'Cluster') { - commit('wizard/model$delete', '/resources/kubedbComRedis/spec/sentinelRef') - commit('wizard/model$delete', '/resources/kubedbComRedisSentinel_sentinel') - } else if (mode === 'Standalone') { - commit('wizard/model$delete', '/resources/kubedbComRedis/spec/replicas') - commit('wizard/model$delete', '/resources/kubedbComRedis/spec/sentinelRef') - commit('wizard/model$delete', '/resources/kubedbComRedisSentinel_sentinel') + function showPause() { + // watchDependency('discriminator#/backupConfigContext') + // watchDependency('discriminator#/config') + const contex = getValue(discriminator, '/backupConfigContext') + const configName = getValue(discriminator, '/config') + return !!configName && contex === 'Modify' } -} -function isEqualToDatabaseMode({ getValue, watchDependency, model }, value) { - watchDependency('model#/activeDatabaseMode') - const mode = getValue(model, '/activeDatabaseMode') - return mode === value -} + 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 showSentinelNameAndNamespace({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/createSentinel') - const verd = getValue(discriminator, '/createSentinel') + function showConfigList() { + // watchDependency('discriminator#/backupConfigContext') + const contex = getValue(discriminator, '/backupConfigContext') + return contex === 'Modify' || contex === 'Delete' + } - return !verd -} + 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 onCreateSentinelChange({ discriminator, getValue, commit, model }) { - const verd = getValue(discriminator, '/createSentinel') + function showScheduleBackup() { + const operationQuery = storeGet('/route/params/actions') || '' + const isBackupOperation = operationQuery === 'edit-self-backupconfiguration' ? true : false + return !isBackupOperation + } - if (verd === true) { - const sentinelObj = getValue(model, '/resources/kubedbComRedisSentinel_sentinel') + 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 : '' + } - if (!sentinelObj) { - const redisSpec = getValue(model, '/resources/kubedbComRedis/spec') + function initRepositoryChoiseForEdit() { + const stashAppscodeComRepository_repo = getValue( + model, + '/resources/stashAppscodeComRepository_repo', + ) + const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' + setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) - const { version, tls, storage, monitor, deletionPolicy } = redisSpec || {} + 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: '/resources/kubedbComRedisSentinel_sentinel/spec', - value: { - version, - tls, - storage, - monitor, - deletionPolicy, - }, - force: true, + path: modelPath, + value: session, }) } - } else if (verd === false) { - commit('wizard/model$delete', '/resources/kubedbComRedisSentinel_sentinel') } -} -function setCreateSentinel({ model, getValue }) { - const sentinelObj = getValue(model, '/resources/kubedbComRedisSentinel_sentinel') - - return !!sentinelObj -} -// ************************** TLS ******************************88 + 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/kubedbComRedis/metadata/labels') + const bindingValues = { + apiVersion: 'catalog.appscode.com/v1alpha1', + kind: 'RedisBinding', + metadata: { + labels, + name: dbName, + namespace: dbNamespace, + }, + spec: { + sourceRef: { + name: dbName, + namespace: dbNamespace, + }, + }, + } -function setApiGroup() { - return 'cert-manager.io' -} + if (value) { + commit('wizard/model$update', { + path: '/resources/catalogAppscodeComRedisBinding', + value: bindingValues, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/catalogAppscodeComRedisBinding') + } + } -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - watchDependency('model#/resources/kubedbComRedis/spec/tls/issuerRef/apiGroup') - watchDependency('model#/resources/kubedbComRedis/spec/tls/issuerRef/kind') - watchDependency('model#/metadata/release/namespace') - const apiGroup = getValue(model, '/resources/kubedbComRedis/spec/tls/issuerRef/apiGroup') - const kind = getValue(model, '/resources/kubedbComRedis/spec/tls/issuerRef/kind') - const namespace = getValue(model, '/metadata/release/namespace') + function isBindingAlreadyOn() { + const value = getValue(model, '/resources') + const keys = Object.keys(value) + const isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComRedisBinding') + return isExposeBinding + } - let url - if (kind === 'Issuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/namespaces/${namespace}/issuers` - } else if (kind === 'ClusterIssuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/clusterissuers` + function objectCopy(obj) { + const temp = JSON.stringify(obj) + return JSON.parse(temp) } - if (!url) return [] + /********** Compute Autoscaling ***********/ - try { - const resp = await axios.get(url) + let autoscaleType = '' + let dbDetails = {} + let instance = '' - const resources = (resp && resp.data && resp.data.items) || [] + async function getDbDetails() { + const annotations = getValue( + model, + '/resources/autoscalingKubedbComRedisAutoscaler/metadata/annotations', + ) + instance = annotations?.['kubernetes.io/instance-type'] + + const owner = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + + const namespace = + storeGet('/route/query/namespace') || + getValue(model, '/resources/autoscalingKubedbComRedisAutoscaler/metadata/namespace') || + '' + const name = + storeGet('/route/params/name') || + getValue(model, '/resources/autoscalingKubedbComRedisAutoscaler/spec/databaseRef/name') || + '' + + if (namespace && name) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises/${name}`, + ) + dbDetails = resp.data || {} + + setDiscriminatorValue('/dbDetails', true) + } catch (e) { + console.log(e) + } + } - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + commit('wizard/model$update', { + path: `/metadata/release/name`, + value: name, + force: true, }) - return resources - } catch (e) { - console.log(e) - return [] - } -} - -function onIssuerRefChange({ model, getValue, commit }) { - const issuerRef = getValue(model, '/resources/kubedbComRedis/spec/tls/issuerRef') - - if (hasSentinelObject({ model, getValue })) { commit('wizard/model$update', { - path: '/resources/kubedbComRedisSentinel_sentinel/spec/tls/issuerRef', - value: issuerRef, + path: `/metadata/release/namespace`, + value: namespace, force: true, }) - } -} - -function setSSLMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComRedis/spec/sslMode') - return val || 'require' -} - -function showTlsConfigureSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configureTLS') - const configureStatus = getValue(discriminator, '/configureTLS') - return configureStatus -} - -function onTlsConfigureChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/configureTLS') - if (configureStatus) { commit('wizard/model$update', { - path: '/resources/kubedbComRedis/spec/tls', - value: { issuerRef: {}, certificates: [] }, + path: `/resources/autoscalingKubedbComRedisAutoscaler/spec/databaseRef/name`, + value: name, force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComRedis/spec/tls') - commit('wizard/model$delete', '/resources/kubedbComRedis/spec/sslMode') - } -} - -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} - -/****** Monitoring *********/ - -function showMonitoringSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/enableMonitoring') - const configureStatus = getValue(discriminator, '/enableMonitoring') - return configureStatus -} - -function onEnableMonitoringChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/enableMonitoring') - if (configureStatus) { commit('wizard/model$update', { - path: '/resources/kubedbComRedis/spec/monitor', - value: {}, + path: `/resources/autoscalingKubedbComRedisAutoscaler/metadata/labels`, + value: dbDetails.metadata.labels, force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComRedis/spec/monitor') } - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: configureStatus ? 'warning' : 'none', - force: true, - }) -} + function isKubedb() { + return !!storeGet('/route/params/actions') + } -function showCustomizeExporterSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/customizeExporter') - const configureStatus = getValue(discriminator, '/customizeExporter') - return configureStatus -} + function isConsole() { + const isKube = isKubedb() -function onCustomizeExporterChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/customizeExporter') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComRedis/spec/monitor/prometheus/exporter', - value: {}, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComRedis/spec/monitor/prometheus/exporter') + if (isKube) { + const dbName = storeGet('/route/params/name') || '' + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComRedisAutoscaler/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/autoscalingKubedbComRedisAutoscaler/metadata/name', + value: modifiedName, + force: true, + }) + const namespace = storeGet('/route/query/namespace') || '' + if (namespace) { + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComRedisAutoscaler/metadata/namespace', + value: namespace, + force: true, + }) + } + } + + return !isKube } -} -// ********************************* Initialization & Backup ************************************* -const stashAppscodeComRestoreSession_init = { - spec: { - repository: { - name: '', - }, - rules: [ - { - snapshots: ['latest'], - }, - ], - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} -const initScript = { - scriptPath: '', - secret: { - secretName: '', - }, -} -const stashAppscodeComRepository_init_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const stashAppscodeComRepository_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const restoreSessionInitRunTimeSettings = { - container: { - resources: { - requests: { - cpu: '', - memory: '', - }, - limits: { - cpu: '', - memory: '', - }, - }, - nice: { - adjustment: null, - }, - ionice: { - class: null, - classData: null, - }, - securityContext: { - privileged: false, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - env: [], - envFrom: [], - }, - pod: { - serviceAccountName: '', - imagePullSecrets: [], - securityContext: { - fsGroup: null, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - }, -} + async function getNamespaces() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -const stashAppscodeComBackupConfiguration = { - spec: { - repository: { - name: '', - }, - retentionPolicy: { - keepLast: 5, - name: 'keep-last-5', - prune: true, - }, - schedule: '*/5 * * * *', - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, + }) -function valueExists(value, getValue, path) { - const val = getValue(value, path) - if (val) return true - else return false -} + const resources = (resp && resp.data && resp.data.items) || [] -function initPrePopulateDatabase({ getValue, model }) { - const waitForInitialRestore = getValue( - model, - '/resources/kubedbComRedis/spec/init/waitForInitialRestore', - ) - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - const script = getValue(model, '/resources/kubedbComRedis/spec/init/script') + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } - return waitForInitialRestore || !!stashAppscodeComRestoreSession_init || !!script ? 'yes' : 'no' -} + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } -function onPrePopulateDatabaseChange({ commit, getValue, discriminator, model }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - if (prePopulateDatabase === 'no') { - // delete related properties - commit('wizard/model$update', { - path: '/resources/kubedbComRedis/spec/init/waitForInitialRestore', - value: false, - }) - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - commit('wizard/model$delete', '/resources/kubedbComRedis/spec/init/script') - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else { - const dbName = getValue(model, '/metadata/release/name') - // set stashAppscodeComRestoreSession_init if it doesn't exist - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { + function onNamespaceChange() { + const namespace = getValue(model, '/metadata/release/namespace') + const agent = getValue(model, '/resources/kubedbComRedis/spec/monitor/agent') + if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, + path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + value: [namespace], force: true, }) + } + } + function initMetadata() { + const dbName = + getValue(model, '/resources/autoscalingKubedbComRedisAutoscaler/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/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, + path: '/resources/autoscalingKubedbComRedisAutoscaler/metadata/name', + value: modifiedName, force: true, }) + + // delete the other type object from vuex wizard model + if (type === 'compute') + commit('wizard/model$delete', '/resources/autoscalingKubedbComRedisAutoscaler/spec/storage') + if (type === 'storage') + commit('wizard/model$delete', '/resources/autoscalingKubedbComRedisAutoscaler/spec/compute') + } + + async function fetchTopologyMachines() { + const instance = hasAnnotations() + + 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 initDataSource({ getValue, model }) { - const script = getValue(model, '/resources/kubedbComRedis/spec/init/script') - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - if (script) return 'script' - else if (stashAppscodeComRestoreSession_init) return 'stashBackup' - else return undefined -} + function setTrigger(path) { + let value = getValue(model, `/resources/${path}`) + return value === 'On' // Returns boolean instead of string + } -function onDataSourceChange({ commit, getValue, discriminator, model }) { - const dataSource = getValue(discriminator, '/dataSource') + function onTriggerChange(type) { + const trigger = getValue(discriminator, `/${type}/trigger`) + const commitPath = `/resources/autoscalingKubedbComRedisAutoscaler/spec/${type}/trigger` - commit('wizard/model$update', { - path: '/resources/kubedbComRedis/spec/init/waitForInitialRestore', - value: dataSource === 'stashBackup', - force: true, - }) + commit('wizard/model$update', { + path: commitPath, + value: trigger ? 'On' : 'Off', + force: true, + }) + } - if (dataSource === 'script') { - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') + function hasAnnotations() { + const annotations = + getValue(model, '/resources/autoscalingKubedbComRedisAutoscaler/metadata/annotations') || {} + const instance = annotations['kubernetes.io/instance-type'] - // create a new script if there is no script property - if (!valueExists(model, getValue, '/resources/kubedbComRedis/spec/init/script')) - commit('wizard/model$update', { - path: '/resources/kubedbComRedis/spec/init/script', - value: initScript, - }) - } else if (dataSource === 'stashBackup') { - commit('wizard/model$delete', '/resources/kubedbComRedis/spec/init/script') + return !!instance + } - // create a new stashAppscodeComRestoreSession_init if there is no stashAppscodeComRestoreSession_init property - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - const dbName = getValue(model, '/metadata/release/name') + function setAllowedMachine(minmax) { + const mx = instance?.includes(',') ? instance.split(',')[1] : '' + const mn = instance?.includes(',') ? instance.split(',')[0] : '' + const machineName = minmax === 'min' ? mn : mx - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - }) + // Find the machine details from topologyMachines + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] + const machineData = nodeGroups.find((item) => item.topologyValue === machineName) - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) + // 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: '', } } -} -// // for script -function initVolumeType({ getValue, model }) { - const configMap = getValue(model, '/resources/kubedbComRedis/spec/init/script/configMap/name') - const secret = getValue(model, '/resources/kubedbComRedis/spec/init/script/secret/secretName') + function getMachines(minmax) { + // watchDependency('discriminator#/topologyMachines') + const depends = minmax === 'min' ? 'max' : 'min' + const dependantPath = `/allowedMachine-${depends}` - if (configMap) return 'configMap' - else if (secret) return 'secret' - else return undefined -} + // watchDependency(`discriminator#${dependantPath}`) + const dependantMachineObj = getValue(discriminator, dependantPath) + const dependantMachine = dependantMachineObj?.machine || '' -function onVolumeTypeChange({ commit, getValue, discriminator, model }) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - if (sourceVolumeType === 'configMap') { - // add configMap object and delete secret object - commit('wizard/model$delete', '/resources/kubedbComRedis/spec/init/script/secret') + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] - if (!valueExists(model, getValue, '/resources/kubedbComRedis/spec/init/script/configMap')) { - commit('wizard/model$update', { - path: '/resources/kubedbComRedis/spec/init/script/configMap', - value: { - name: '', - }, - }) - } - } else if (sourceVolumeType === 'secret') { - // delete configMap object and add secret object - commit('wizard/model$delete', '/resources/kubedbComRedis/spec/init/script/configMap') + const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) - if (!valueExists(model, getValue, '/resources/kubedbComRedis/spec/init/script/secret')) { - commit('wizard/model$update', { - path: '/resources/kubedbComRedis/spec/init/script/secret', + // 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: { - secretName: '', + machine: item.topologyValue, + cpu: item.allocatable?.cpu, + memory: item.allocatable?.memory, }, - }) - } - } -} + } + }) -function showInitializationForm({ getValue, discriminator, watchDependency }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - watchDependency('discriminator#/prePopulateDatabase') - return prePopulateDatabase === 'yes' -} + const filteredMachine = machines?.filter((item, ind) => + minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, + ) -function showScriptOrStashForm({ getValue, discriminator, watchDependency }, value) { - const dataSource = getValue(discriminator, '/dataSource') - watchDependency('discriminator#/dataSource') - return dataSource === value -} + return dependantIndex === -1 ? machines : filteredMachine + } -function showConfigMapOrSecretName({ getValue, discriminator, watchDependency }, value) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - watchDependency('discriminator#/sourceVolumeType') - return sourceVolumeType === value -} + function onMachineChange(type) { + const annoPath = '/resources/autoscalingKubedbComRedisAutoscaler/metadata/annotations' + const annotations = getValue(model, annoPath) || {} + const instance = annotations['kubernetes.io/instance-type'] -// for stash backup -function initializeNamespace({ getValue, model }) { - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} + // 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 -function showRepositorySelectOrCreate({ getValue, discriminator, watchDependency }, value) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') + // 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/autoscalingKubedbComRedisAutoscaler/spec/compute/${type}` - return repositoryChoise === value -} + 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 onInitRepositoryChoiseChange({ getValue, discriminator, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - if (repositoryChoise === 'select') { - // delete stashAppscodeComRepository_init_repo from model - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else if (repositoryChoise === 'create') { - // add stashAppscodeComRepository_init_repo to model - commit('wizard/model$update', { - path: 'resources/stashAppscodeComRepository_init_repo', - value: stashAppscodeComRepository_init_repo, - }) + function hasNoAnnotations() { + return !hasAnnotations() + } - const repositoryName = `${getValue(model, '/metadata/release/name')}-init-repo` - // set this name in stashAppscodeComRestoreSession_init + function setControlledResources(type) { + const list = ['cpu', 'memory'] + const path = `/resources/autoscalingKubedbComRedisAutoscaler/spec/compute/${type}/controlledResources` commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: repositoryName, + path: path, + value: list, + force: true, }) + return list } -} -function initCustomizeRestoreJobRuntimeSettings({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} + 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 initCustomizeRestoreJobRuntimeSettingsForBackup({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} + function isNodeTopologySelected() { + // watchDependency( + // 'model#/resources/autoscalingKubedbComRedisAutoscaler/spec/compute/nodeTopology/name', + // ) + const nodeTopologyName = + getValue( + model, + '/resources/autoscalingKubedbComRedisAutoscaler/spec/compute/nodeTopology/name', + ) || '' + return !!nodeTopologyName.length + } -function onCustomizeRestoreJobRuntimeSettingsChange({ commit, getValue, discriminator, model }) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', + function showOpsRequestOptions() { + if (isKubedb() === true) return true + // watchDependency('model#/resources/autoscalingKubedbComRedisAutoscaler/spec/databaseRef/name') + // watchDependency('discriminator#/autoscalingType') + return ( + !!getValue(model, '/resources/autoscalingKubedbComRedisAutoscaler/spec/databaseRef/name') && + !!getValue(discriminator, '/autoscalingType') ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - value: restoreSessionInitRunTimeSettings, - }) + } + + function setApplyToIfReady() { + return 'IfReady' + } + + function dbTypeEqualsTo(type) { + // watchDependency('discriminator#/dbDetails') + + const { spec } = dbDetails || {} + const { cluster, sentinelRef } = spec || {} + let verd = '' + if (cluster) verd = 'cluster' + else { + if (sentinelRef) verd = 'sentinel' + else verd = 'standalone' } + clearSpecModel(verd) + return type === verd && spec } -} -function onCustomizeRestoreJobRuntimeSettingsChangeForBackup({ - commit, - getValue, - discriminator, - model, -}) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', + function clearSpecModel(dbtype) { + if (dbtype === 'standalone') { + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComRedisAutoscaler/spec/${autoscaleType}/cluster`, ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - value: {}, - force: true, + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComRedisAutoscaler/spec/${autoscaleType}/sentinel`, + ) + } else if (dbtype === 'cluster') { + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComRedisAutoscaler/spec/${autoscaleType}/standalone`, + ) + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComRedisAutoscaler/spec/${autoscaleType}/sentinel`, + ) + } else if (dbtype === 'sentinel') { + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComRedisAutoscaler/spec/${autoscaleType}/standalone`, + ) + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComRedisAutoscaler/spec/${autoscaleType}/cluster`, + ) + } + } + + 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 showRuntimeForm({ discriminator, getValue, watchDependency }, value) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - watchDependency('discriminator#/customizeRestoreJobRuntimeSettings') - return customizeRestoreJobRuntimeSettings === value -} + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } -async function getImagePullSecrets({ getValue, model, watchDependency, axios, storeGet }) { - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - let resources = await getNamespacedResourceList(axios, storeGet, { - namespace, - group: 'core', - version: 'v1', - resource: 'secrets', - }) + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) - resources = resources.filter((item) => { - const validType = ['kubernetes.io/dockerconfigjson'] - return validType.includes(item.type) - }) + const resources = (resp && resp.data && resp.data.items) || [] - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: { name: name }, + 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') -// FOR Backup Configuration + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` -// schedule bakcup + let ans = [] + try { + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) -function getBackupConfigsAndAnnotations(getValue, model) { - const stashAppscodeComBackupConfiguration = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration', - ) - const kubedbComRedisAnnotations = - getValue(model, '/resources/kubedbComRedis/metadata/annotations') || {} - - const isBluePrint = Object.keys(kubedbComRedisAnnotations).some( - (k) => - k === 'stash.appscode.com/backup-blueprint' || - k === 'stash.appscode.com/schedule' || - k.startsWith('params.stash.appscode.com/'), - ) + const items = (resp && resp.data && resp.data.items) || [] + ans = items + } catch (e) { + console.log(e) + } - return { - stashAppscodeComBackupConfiguration, - isBluePrint, + return ans } -} - -function deletekubedbComRedisAnnotation(getValue, model, commit) { - const annotations = getValue(model, '/resources/kubedbComRedis/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/kubedbComRedis/metadata/annotations', - value: filteredAnnotations, - }) -} -function addkubedbComRedisAnnotation(getValue, model, commit, key, value, force) { - const annotations = getValue(model, '/resources/kubedbComRedis/metadata/annotations') || {} + function hasSentinelObject() { + const sentinelObj = getValue(model, '/resources/kubedbComRedisSentinel_sentinel') - if (annotations[key] === undefined) { - annotations[key] = value - } else if (force) { - annotations[key] = value + return !!sentinelObj } - commit('wizard/model$update', { - path: '/resources/kubedbComRedis/metadata/annotations', - value: annotations, - force: true, - }) -} + /****** Monitoring *********/ -function initScheduleBackupForEdit({ getValue, model, setDiscriminatorValue }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) + function showMonitoringSection() { + // watchDependency('discriminator#/enableMonitoring') + const configureStatus = getValue(discriminator, '/enableMonitoring') + return configureStatus + } - initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) + function onEnableMonitoringChange() { + const configureStatus = getValue(discriminator, '/enableMonitoring') + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComRedis/spec/monitor', + value: {}, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/kubedbComRedis/spec/monitor') + } - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: configureStatus ? 'warning' : 'none', + force: true, + }) + } -function initScheduleBackup({ getValue, model }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) + function showCustomizeExporterSection() { + // watchDependency('discriminator#/customizeExporter') + const configureStatus = getValue(discriminator, '/customizeExporter') + return configureStatus + } - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} + function onCustomizeExporterChange() { + const configureStatus = getValue(discriminator, '/customizeExporter') + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComRedis/spec/monitor/prometheus/exporter', + value: {}, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/kubedbComRedis/spec/monitor/prometheus/exporter') + } + } -function onScheduleBackupChange({ commit, getValue, discriminator, model }) { - const scheduleBackup = getValue(discriminator, '/scheduleBackup') + function isValueExistInModel(path) { + const modelValue = getValue(model, path) || null + return !!modelValue + } - if (scheduleBackup === 'no') { - // delete stashAppscodeComBackupConfiguration - commit('wizard/model$delete', '/resources/stashAppscodeComBackupConfiguration') - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') - // delete annotation from kubedbComRedis annotation - deletekubedbComRedisAnnotation(getValue, model, commit) - } else { - const { isBluePrint } = getBackupConfigsAndAnnotations(getValue, model) + // function onNamespaceChange() { + // const namespace = getValue(model, '/metadata/release/namespace') + // const agent = getValue(model, '/resources/kubedbComRedis/spec/monitor/agent') + // if (agent === 'prometheus.io') { + // commit('wizard/model$update', { + // path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + // value: [namespace], + // force: true, + // }) + // } + // } - // create stashAppscodeComBackupConfiguration and initialize it if not exists + function onLabelChange() { + const labels = getValue(model, '/resources/kubedbComRedis/spec/metadata/labels') - const dbName = getValue(model, '/metadata/release/name') + const agent = getValue(model, '/resources/kubedbComRedis/spec/monitor/agent') - if ( - !valueExists(model, getValue, '/resources/stashAppscodeComBackupConfiguration') && - !isBluePrint - ) { + if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration', - value: stashAppscodeComBackupConfiguration, + path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', + value: labels, + force: true, }) + } + } + + function onAgentChange() { + const agent = getValue(model, '/resources/kubedbComRedis/spec/monitor/agent') + if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, + path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', + value: [], + force: true, + }) + + onNamespaceChange() + onLabelChange() + } else { + commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') + } + + if (hasSentinelObject()) { + commit('wizard/model$update', { + path: '/resources/kubedbComRedisSentinel_sentinel/spec/monitor/agent', + value: agent, force: true, }) } } -} -// backup form -function showBackupForm({ getValue, discriminator, watchDependency }) { - const scheduleBackup = getValue(discriminator, '/scheduleBackup') - watchDependency('discriminator#/scheduleBackup') + 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/redisopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` + } + + function setValueFrom() { + if (isConfigMapTypeValueFrom()) { + return 'configMap' + } else if (isSecretTypeValueFrom()) { + return 'secret' + } else { + return 'input' + } + } - if (scheduleBackup === 'yes') return true - else return false -} + 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, + }) + } + } -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({ storeGet, axios, getValue, model, setDiscriminatorValue }) { - // 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/kubedbComRedis') - initialDbMetadata = objectCopy(dbResource.metadata) - - // 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 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, - ) + // function isEqualToValueFromType(value) { + // //watchDependency('discriminator#/valueFromType') + // const valueFrom = getValue(discriminator, '/valueFromType') + // return valueFrom === value + // } - // 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, getValue, discriminator }) { - watchDependency('discriminator#/isBackupDataLoaded') - return !!getValue(discriminator, '/isBackupDataLoaded') -} - -async function setBackupType() { - return 'BackupConfig' -} - -async function getTypes() { - const arr = [ - { - description: 'Create, Delete or Modify BackupConfig', - text: 'BackupConfig', - value: 'BackupConfig', - }, - { - description: 'Enable/Disable BackupBlueprint', - text: 'BackupBlueprint', - value: 'BackupBlueprint', - }, - ] - return arr -} - -function onBackupTypeChange({ commit, getValue, discriminator }) { - 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/kubedbComRedis', - value: objectCopy(dbResource), - force: true, - }) -} - -function isBackupType({ watchDependency, getValue, discriminator }, 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({ getValue, discriminator, commit, model, storeGet }) { - const blueprintSwitch = getValue(discriminator, '/blueprintEnabled') - if (blueprintSwitch) addLabelAnnotation(commit, storeGet, 'annotations') - else deleteLabelAnnotation(commit, 'annotations') -} - -function setArchiverSwitch() { - const archiver = dbResource?.spec?.archiver - return !!archiver -} - -function onArchiverChange({ getValue, discriminator, commit }) { - const archiverSwitch = getValue(discriminator, '/archiverEnabled') - const path = 'resources/kubedbComRedis/spec/archiver' - if (archiverSwitch) { - commit('wizard/model$update', { - path: path, - value: initialArchiver ? initialArchiver : archiverObjectToCommit, - }) - } else { - commit('wizard/model$delete', path) - } -} - -function addLabelAnnotation(commit, storeGet, 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/kubedbComRedis/metadata/${type}`, - value: obj, - force: true, - }) -} - -function deleteLabelAnnotation(commit, 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/kubedbComRedis/metadata/${type}`, - value: obj, - force: true, - }) -} - -function getContext() { - if (isBackupOn) return ['Create', 'Delete', 'Modify'] - return ['Create'] -} - -function onContextChange({ getValue, discriminator, commit, model }) { - 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, - }) - } -} - -function getConfigList({ storeGet }) { - 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({ getValue, discriminator, commit, storeGet, model }) { - 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, getValue, discriminator }) { - watchDependency('discriminator#/backupConfigContext') - watchDependency('discriminator#/config') - const contex = getValue(discriminator, '/backupConfigContext') - const configName = getValue(discriminator, '/config') - return !!configName && contex === 'Modify' -} - -function showConfigList({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/backupConfigContext') - const contex = getValue(discriminator, '/backupConfigContext') - return contex === 'Modify' || contex === 'Delete' -} - -function showSchedule({ watchDependency, getValue, discriminator }) { - 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 getNamespaceArray() { - return namespaceList -} - -// invoker form -function initBackupInvoker() { - return 'backupConfiguration' -} - -function onBackupInvokerChange({ getValue, discriminator, commit, model, storeGet }) { - const kind = storeGet('/resource/layout/result/resource/kind') - const backupInvoker = getValue(discriminator, '/backupInvoker') - const annotations = getValue(model, '/resources/kubedbComRedis/metadata/annotations') + async function resourceNames(group, version, resource) { + const namespace = getValue(model, '/metadata/release/namespace') + // watchDependency('model#/metadata/release/namespace') - // get name namespace labels to set in db resource when backup is not enabled initially - - if (backupInvoker === 'backupConfiguration') { - commit('wizard/model$update', { - path: '/resources/coreKubestashComBackupConfiguration', - value: initialModel, - force: true, + let resources = await getNamespacedResourceList(axios, storeGet, { + namespace, + group, + version, + resource, }) - if ( - !dbResource.metadata?.annotations?.['blueprint.kubestash.com/name'] && - !dbResource.metadata?.annotations?.['blueprint.kubestash.com/namespace'] - ) { - delete annotations['blueprint.kubestash.com/name'] - delete annotations['blueprint.kubestash.com/namespace'] - commit('wizard/model$update', { - path: '/resources/kubedbComRedis/metadata/annotations', - value: annotations, - force: true, + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) }) } - } else if (backupInvoker === 'backupBlueprint') { - if (!isBackupOn) { - commit('wizard/model$delete', '/resources/coreKubestashComBackupConfiguration') - } - annotations['blueprint.kubestash.com/name'] = `${kind.toLowerCase()}-blueprint` - annotations['blueprint.kubestash.com/namespace'] = 'kubedb' - commit('wizard/model$update', { - path: '/resources/kubedbComRedis/metadata/annotations', - value: annotations, - force: true, + + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } }) } -} - -function showInvokerForm({ getValue, discriminator, watchDependency }, value) { - const backupInvoker = getValue(discriminator, '/backupInvoker') - watchDependency('discriminator#/backupInvoker') - - return backupInvoker === value -} - -// backup configuration form -function initalizeTargetReferenceName({ getValue, model, watchDependency }) { - const databaseName = getValue(model, '/metadata/release/name') - watchDependency('model#/metadata/release/name') - - return databaseName -} - -// restore session repository -function setInitialRestoreSessionRepo({ getValue, model }) { - const value = getValue(model, 'resources/stashAppscodeComRepository_init_repo') - return value ? 'create' : 'select' -} - -// backup config repository -function initRepositoryChoise({ getValue, model }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - - if (stashAppscodeComRepository_repo) return 'create' - else return 'select' -} - -function initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' - setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) - - return repoInitialSelectionStatus -} -function onRepositoryChoiseChange({ getValue, discriminator, watchDependency, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - if (repositoryChoise === 'select') { - // delete the stashAppscodeComRepository_repo - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') - } else if (repositoryChoise === 'create') { - // create new stashAppscodeComRepository_repo - if (!valueExists(model, getValue, '/resources/stashAppscodeComRepository_repo')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRepository_repo', - value: stashAppscodeComRepository_repo, - }) - const repositoryName = `${getValue(model, '/metadata/release/name')}-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) - } - } -} + 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/kubedbComRedis/spec/monitor/prometheus/exporter/env/${index}/valueFrom/configMapKeyRef/name`, + ) -function onRepositoryNameChange({ getValue, model, commit }) { - const repositoryName = getValue(model, 'resources/stashAppscodeComRepository_repo/metadata/name') - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) -} + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/configMapKeyRef/name') -// backup blueprint form -function getMongoAnnotations(getValue, model) { - const annotations = getValue(model, '/resources/kubedbComRedis/metadata/annotations') - return { ...annotations } || {} -} + if (!configMapName) return [] -function initFromAnnotationValue({ getValue, model }, key) { - const annotations = getMongoAnnotations(getValue, model) - return annotations[key] -} + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/configmaps/${configMapName}`, + ) -function onBackupBlueprintNameChange({ getValue, discriminator, commit, model }) { - const backupBlueprintName = getValue(discriminator, '/backupBlueprintName') - addkubedbComRedisAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/backup-blueprint', - backupBlueprintName, - true, - ) -} + const configMaps = (resp && resp.data && resp.data.data) || {} -function onBackupBlueprintScheduleChange({ getValue, discriminator, commit, model }) { - const backupBlueprintSchedule = getValue(discriminator, '/schedule') - addkubedbComRedisAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/schedule', - backupBlueprintSchedule, - true, - ) -} + const configMapKeys = Object.keys(configMaps).map((item) => ({ + text: item, + value: item, + })) -function initFromAnnotationKeyValue({ getValue, model }, prefix) { - const annotations = getMongoAnnotations(getValue, model) - const newOb = {} - Object.keys(annotations).forEach((key) => { - if (key.startsWith(prefix)) { - const newKey = key.replace(prefix, '') - newOb[newKey] = annotations[key] + return configMapKeys + } catch (e) { + console.log(e) + return [] } - }) - return newOb -} - -function onTaskParametersChange({ getValue, discriminator, model, commit }) { - const taskParameters = getValue(discriminator, '/taskParameters') - - const taskParamterKeys = Object.keys(taskParameters).map( - (tp) => `params.stash.appscode.com/${tp}`, - ) - const oldAnnotations = getValue(model, '/resources/kubedbComRedis/metadata/annotations') || {} - const newAnnotations = {} - - const filteredAnnotationKeys = Object.keys(oldAnnotations).filter( - (key) => !taskParamterKeys.includes(key) && !key.startsWith('params.stash.appscode.com/'), - ) - - filteredAnnotationKeys.forEach((key) => { - newAnnotations[key] = oldAnnotations[key] - }) - - Object.keys(taskParameters).forEach((tpk) => { - newAnnotations[`params.stash.appscode.com/${tpk}`] = taskParameters[tpk] - }) - - commit('wizard/model$update', { - path: '/resources/kubedbComRedis/metadata/annotations', - value: newAnnotations, - }) -} - -function isValueExistInModel({ model, getValue }, path) { - const modelValue = getValue(model, path) - return !!modelValue -} - -function onNamespaceChange({ commit, model, getValue }) { - const namespace = getValue(model, '/metadata/release/namespace') - const agent = getValue(model, '/resources/kubedbComRedis/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', - value: [namespace], - force: true, - }) - } -} - -function onLabelChange({ commit, model, getValue }) { - const labels = getValue(model, '/resources/kubedbComRedis/spec/metadata/labels') - - const agent = getValue(model, '/resources/kubedbComRedis/spec/monitor/agent') - - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) } -} - -function onNameChange({ commit, model, getValue }) { - const dbName = getValue(model, '/metadata/release/name') - const agent = getValue(model, '/resources/kubedbComRedis/spec/monitor/agent') + 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') - const labels = getValue(model, '/resources/kubedbComRedis/spec/metadata/labels') - - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, - }) - } + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }, + ) - const scheduleBackup = getValue(model, '/resources/stashAppscodeComBackupConfiguration') + const secrets = (resp && resp.data && resp.data.items) || [] - if (scheduleBackup) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_repo') - if (creatingNewRepo) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: `${dbName}-repo`, - force: true, + const filteredSecrets = secrets.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) }) - } - } - const prePopulateDatabase = getValue(model, '/resources/stashAppscodeComRestoreSession_init') - - if (prePopulateDatabase) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_init_repo') - if (creatingNewRepo) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: `${dbName}-init-repo`, - force: true, + 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 [] } } - // to reset configSecret name field - const hasSecretConfig = getValue(model, '/resources/secret_config') - if (hasSecretConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComRedis/spec/configSecret/name', - value: `${dbName}-config`, - force: true, - }) - } -} - -function returnFalse() { - return false -} - -function onAgentChange({ commit, model, getValue }) { - const agent = getValue(model, '/resources/kubedbComRedis/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', - value: [], - force: true, - }) - - onNamespaceChange({ commit, model, getValue }) - onLabelChange({ commit, model, getValue }) - } else { - commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') - } - - if (hasSentinelObject({ model, getValue })) { - commit('wizard/model$update', { - path: '/resources/kubedbComRedisSentinel_sentinel/spec/monitor/agent', - value: agent, - force: true, - }) - } -} - -function onServiceMonitorChange({ model, getValue, commit }) { - const serviceMonitor = getValue( - model, - '/resources/kubedbComRedis/spec/monitor/prometheus/serviceMonitor', - ) - - if (hasSentinelObject({ model, getValue })) { - commit('wizard/model$update', { - path: '/resources/kubedbComRedisSentinel_sentinel/spec/monitor/prometheus/serviceMonitor', - value: serviceMonitor, - force: true, - }) - } -} - -/************************************* Database Secret Section ********************************************/ - -function getCreateAuthSecret({ model, getValue }) { - const authSecret = getValue(model, '/resources/kubedbComRedis/spec/authSecret') - - return !authSecret -} - -function showExistingSecretSection({ getValue, watchDependency, discriminator }) { - watchDependency('discriminator#/createAuthSecret') - const hasAuthSecretName = getValue(discriminator, '/createAuthSecret') - return !hasAuthSecretName -} - -function showPasswordSection({ getValue, watchDependency, discriminator }) { - return !showExistingSecretSection({ - getValue, - watchDependency, - discriminator, - }) -} - -function setAuthSecretPassword({ model, getValue }) { - const encodedPassword = getValue(model, '/resources/secret_auth/data/password') - return encodedPassword ? decodePassword({}, encodedPassword) : '' -} - -function onAuthSecretPasswordChange({ getValue, discriminator, commit }) { - const stringPassword = getValue(discriminator, '/password') - - if (stringPassword) { - commit('wizard/model$update', { - path: '/resources/secret_auth/data/password', - value: encodePassword({}, stringPassword), - force: true, - }) - commit('wizard/model$update', { - path: '/resources/secret_auth/data/username', - value: encodePassword({}, 'root'), - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/secret_auth') - } -} - -function disableInitializationSection({ model, getValue, watchDependency }) { - const initialized = getValue(model, '/resources/kubedbComRedis/spec/init/initialized') - watchDependency('model#/resources/kubedbComRedis/spec/init/initialized') - return !!initialized -} - -// eslint-disable-next-line no-empty-pattern -function encodePassword({}, value) { - return btoa(value) -} - -// eslint-disable-next-line no-empty-pattern -function decodePassword({}, value) { - return atob(value) -} - -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/resources/kubedbComRedis/spec/authSecret') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/resources/secret_auth') - } -} - -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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 } }, - }, - }, + 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/kubedbComRedis/spec/monitor/prometheus/exporter/env/${index}/valueFrom/secretKeyRef/name`, ) - const secrets = (resp && resp.data && resp.data.items) || [] + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/secretKeyRef/name') - const filteredSecrets = secrets.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) + if (!secretName) return [] - 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 [] - } -} + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets/${secretName}`, + ) -//////////////////////////////////////// Service Monitor ////////////////////////////////////////////////////// + const secret = (resp && resp.data && resp.data.data) || {} -function isEqualToServiceMonitorType({ rootModel, watchDependency }, value) { - watchDependency('rootModel#/spec/type') - return rootModel && rootModel.spec && rootModel.spec.type === value -} + const secretKeys = Object.keys(secret).map((item) => ({ + text: item, + value: item, + })) -//////////////////// custom config ///////////////// -function onConfigurationSourceChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSource') - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_config') - } else { - const value = getValue(model, '/resources/secret_config') - if (!value) { - commit('wizard/model$update', { - path: '/resources/secret_config', - value: {}, - force: true, - }) + return secretKeys + } catch (e) { + console.log(e) + return [] } - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComRedis/spec/configSecret/name', - value: configSecretName, - force: true, - }) - } -} - -function onConfigurationChange({ getValue, commit, discriminator, model }) { - const value = getValue(discriminator, '/configuration') - commit('wizard/model$update', { - path: '/resources/secret_config/stringData/redis.conf', - value: value, - force: true, - }) - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComRedis/spec/configSecret/name', - value: configSecretName, - force: true, - }) -} - -function setConfigurationSource({ model, getValue }) { - const modelValue = getValue(model, '/resources/secret_config') - if (modelValue) { - return 'create-new-config' } - return 'use-existing-config' -} - -function setSecretConfigNamespace({ getValue, model, watchDependency }) { - watchDependency('model#/metadata/release/namespace') - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} - -function setConfiguration({ model, getValue }) { - return getValue(model, '/resources/secret_config/stringData/redis.conf') -} - -function setConfigurationFiles({ model, getValue }) { - const value = getValue(model, '/resources/secret_config/data/redis.conf') - return atob(value) -} - -function onSetCustomConfigChange({ discriminator, getValue, commit }) { - const value = getValue(discriminator, '/setCustomConfig') - - if (value === 'no') { - commit('wizard/model$delete', '/resources/kubedbComRedis/spec/configSecret') - commit('wizard/model$delete', '/resources/secret_config') - } -} - -function getOpsRequestUrl({ storeGet, model, getValue, mode }, 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 + `/create-opsrequest-${reqType.toLowerCase()}?namespace=${namespace}` - - if (mode === 'standalone-step') return pathConstructedForKubedb - else - return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/redisopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` -} - -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } -} - -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} - -function showScheduleBackup({ storeGet }) { - const operationQuery = storeGet('/route/params/actions') || '' - const isBackupOperation = operationQuery === 'edit-self-backupconfiguration' ? true : false - return !isBackupOperation -} -function showBackupOptions({ discriminator, getValue, watchDependency }, backup) { - const backupEnabled = getValue(discriminator, '/backupEnabled') - if (backupEnabled) { - if (backup === 'alert') return true - else return false - } else { - if (backup === 'alert') return false - else return true + function returnFalse() { + return false } -} - -function isBlueprintOption({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/blueprintOptions') - const blueprintOptions = getValue(discriminator, '/blueprintOptions') - return blueprintOptions === value -} - -function ifUsagePolicy({ discriminator, getValue, watchDependency, model }, value) { - watchDependency( - 'model#/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', - ) - const usagePolicy = getValue( - model, - '/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', - ) - return usagePolicy === value -} -async function getBlueprints({ getValue, model, setDiscriminatorValue, axios, storeGet }, backup) { - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const url = `clusters/${username}/${clusterName}/proxy/core.kubestash.com/v1alpha1/backupblueprints` + /********** Binding ***********/ - try { - const resp = await axios.get(url) - let data = resp.data.items - return data - } catch (e) { - console.log(e) + function isBindingAlreadyOn() { + const value = getValue(model, '/resources') + const keys = Object.keys(value) + const isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComRedisBinding') + return isExposeBinding } -} - -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} - -async function fetchNamespaces({ axios, storeGet }) { - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const group = storeGet('/route/params/group') - const version = storeGet('/route/params/version') - const resource = storeGet('/route/params/resource') - const url = `clusters/${username}/${clusterName}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews` - - try { - const resp = await axios.post(url, { - _recurringCall: false, - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', + 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/kubedbComRedis/metadata/labels') + const bindingValues = { + apiVersion: 'catalog.appscode.com/v1alpha1', + kind: 'RedisBinding', + metadata: { + labels, + name: dbName, + namespace: dbNamespace, + }, spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], + sourceRef: { + name: dbName, + namespace: dbNamespace, + }, }, - }) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] - } - } catch (e) { - console.log(e) - } - return [] -} - -async function fetchNames( - { getValue, axios, storeGet, watchDependency, discriminator }, - version, - type, - discriminatorName, -) { - watchDependency(`discriminator#/${discriminatorName}`) - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const namespace = getValue(discriminator, `${discriminatorName}`) - const url = - type !== 'secrets' - ? `clusters/${username}/${clusterName}/proxy/storage.kubestash.com/${version}/namespaces/${namespace}/${type}` - : `clusters/${username}/${clusterName}/proxy/core/${version}/namespaces/${namespace}/${type}` - try { - if (namespace) { - const resp = await axios.get(url) - let data = resp.data.items - if (type === 'secrets') data = data.filter((ele) => !!ele.data['RESTIC_PASSWORD']) - data = data.map((ele) => ele.metadata.name) - return data } - } catch (e) { - console.log(e) - } - return [] -} - -function initBlueprint() { - return 'create' -} - -function initUsagePolicy() { - return 'Same' -} - -function onInputChange( - { getValue, discriminator, commit, model }, - modelPath, - field, - subfield, - discriminatorName, -) { - const value = getValue(discriminator, `/${discriminatorName}`) - const backends = getValue(model, modelPath) || [] - if (field !== 'encryptionSecret') backends[0][field][subfield] = value - else backends[0]['repositories'][0][field][subfield] = value - commit('wizard/model$update', { - path: modelPath, - value: backends, - }) -} - -function onInputChangeSchedule( - { getValue, discriminator, commit, model }, - modelPath, - discriminatorName, -) { - const value = getValue(discriminator, `/${discriminatorName}`) - const session = getValue(model, modelPath) - session[0].scheduler.schedule = value - commit('wizard/model$update', { - path: modelPath, - value: session, - }) -} - -function getDefault({ getValue, model }, modelPath, field, subfield) { - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') return backends[0][field][subfield] - else { - return backends[0]['repositories'][0][field][subfield] - } -} - -function getDefaultSchedule({ getValue, model, watchDependency }, modelPath) { - watchDependency('discriminator#/config') - const session = getValue(model, modelPath) - return session?.length ? session[0]?.scheduler.schedule : '' -} - -///////////////////////// Autoscaler /////////////////// -let autoscaleType = '' -let dbDetails = {} -function isConsole({ storeGet, commit }) { - const isKube = isKubedb({ storeGet }) - - if (isKube) { - const dbName = storeGet('/route/params/name') || '' - commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComRedisAutoscaler/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/autoscalingKubedbComRedisAutoscaler/metadata/name', - value: modifiedName, - force: true, - }) - const namespace = storeGet('/route/query/namespace') || '' - if (namespace) { + if (value) { commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComRedisAutoscaler/metadata/namespace', - value: namespace, + path: '/resources/catalogAppscodeComRedisBinding', + value: bindingValues, force: true, }) + } else { + commit('wizard/model$delete', '/resources/catalogAppscodeComRedisBinding') } } - return !isKube -} - -function isKubedb({ storeGet }) { - return !!storeGet('/route/params/actions') -} - -function showOpsRequestOptions({ model, getValue, watchDependency, storeGet, discriminator }) { - if (isKubedb({ storeGet }) === true) return true - watchDependency('model#/resources/autoscalingKubedbComRedisAutoscaler/spec/databaseRef/name') - watchDependency('discriminator#/autoscalingType') - return ( - !!getValue(model, '/resources/autoscalingKubedbComRedisAutoscaler/spec/databaseRef/name') && - !!getValue(discriminator, '/autoscalingType') - ) -} - -async function getNamespaces({ axios, storeGet }) { - 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({ axios, storeGet, model, getValue, watchDependency }) { - watchDependency('model#/resources/autoscalingKubedbComRedisAutoscaler/metadata/namespace') - const namespace = getValue( - model, - '/resources/autoscalingKubedbComRedisAutoscaler/metadata/namespace', - ) - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises`, - { - 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({ commit, setDiscriminatorValue, axios, storeGet, getValue, model }) { - const owner = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - const namespace = - storeGet('/route/query/namespace') || - getValue(model, '/resources/autoscalingKubedbComRedisAutoscaler/metadata/namespace') || - '' - const name = - storeGet('/route/params/name') || - getValue(model, '/resources/autoscalingKubedbComRedisAutoscaler/spec/databaseRef/name') || - '' - - if (namespace && name) { - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises/${name}`, - ) - dbDetails = resp.data || {} - setDiscriminatorValue('/dbDetails', true) - } catch (e) { - console.log(e) - } - } - - commit('wizard/model$update', { - path: `/metadata/release/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/metadata/release/namespace`, - value: namespace, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComRedisAutoscaler/spec/databaseRef/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComRedisAutoscaler/metadata/labels`, - value: dbDetails.metadata.labels, - force: true, - }) -} - -async function dbTypeEqualsTo({ axios, storeGet, watchDependency, model, getValue, commit }, type) { - watchDependency('discriminator#/dbDetails') - - const { spec } = dbDetails || {} - const { cluster, sentinelRef } = spec || {} - let verd = '' - if (cluster) verd = 'cluster' - else { - if (sentinelRef) verd = 'sentinel' - else verd = 'standalone' - } - clearSpecModel({ commit }, verd) - return type === verd && spec -} - -function clearSpecModel({ commit }, dbtype) { - if (dbtype === 'standalone') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComRedisAutoscaler/spec/${autoscaleType}/cluster`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComRedisAutoscaler/spec/${autoscaleType}/sentinel`, - ) - } else if (dbtype === 'cluster') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComRedisAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComRedisAutoscaler/spec/${autoscaleType}/sentinel`, - ) - } else if (dbtype === 'sentinel') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComRedisAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComRedisAutoscaler/spec/${autoscaleType}/cluster`, - ) - } -} - -function initMetadata({ getValue, discriminator, model, commit, storeGet }) { - const dbName = - getValue(model, '/resources/autoscalingKubedbComRedisAutoscaler/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/autoscalingKubedbComRedisAutoscaler/metadata/name', - value: modifiedName, - force: true, - }) - - // delete the other type object from model - if (type === 'compute') - commit('wizard/model$delete', '/resources/autoscalingKubedbComRedisAutoscaler/spec/storage') - if (type === 'storage') - commit('wizard/model$delete', '/resources/autoscalingKubedbComRedisAutoscaler/spec/compute') -} - -function onNamespaceChange({ model, getValue, commit }) { - const namespace = getValue( - model, - '/resources/autoscalingKubedbComRedisAutoscaler/metadata/namespace', - ) - if (!namespace) { - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComRedisAutoscaler/spec/databaseRef/name', - ) - } -} - -function ifScalingTypeEqualsTo( - { storeGet, watchDependency, getValue, discriminator, model }, - type, -) { - watchDependency('discriminator#/autoscalingType') - watchDependency('model#/resources/autoscalingKubedbComRedisAutoscaler/spec/databaseRef/name') - - const operation = storeGet('/route/params/actions') || '' - if (operation.length) { - const splitOp = operation.split('-') - if (splitOp.length > 2) autoscaleType = splitOp[2] - } else autoscaleType = getValue(discriminator, '/autoscalingType') || '' - const isDatabaseSelected = !!getValue( - model, - '/resources/autoscalingKubedbComRedisAutoscaler/spec/databaseRef/name', - ) - return autoscaleType === type && isDatabaseSelected -} - -async function fetchNodeTopology({ axios, storeGet }) { - 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, getValue }) { - watchDependency( - 'model#/resources/autoscalingKubedbComRedisAutoscaler/spec/compute/nodeTopology/name', - ) - const nodeTopologyName = - getValue( - model, - '/resources/autoscalingKubedbComRedisAutoscaler/spec/compute/nodeTopology/name', - ) || '' - return !!nodeTopologyName.length -} - -function setControlledResources({ commit }, type) { - const list = ['cpu', 'memory'] - const path = `/resources/autoscalingKubedbComRedisAutoscaler/spec/compute/${type}/controlledResources` - commit('wizard/model$update', { - path: path, - value: list, - force: true, - }) - return list -} - -function setTrigger({ model, getValue }, path) { - let value = getValue(model, `/resources/${path}`) - if (value) return value - return 'On' -} - -function setApplyToIfReady() { - return 'IfReady' -} - -function handleUnit({ commit, model, getValue }, 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' + function setValueFromDbDetails(path) { + const value = getValue(model, path) + return value + } + + 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 } } } - updatedValue.push({ threshold, appliesUpto }) + return ret }) - if (JSON.stringify(updatedValue) !== JSON.stringify(value)) { - commit('wizard/model$update', { - path: `/resources/${path}`, - value: updatedValue, - force: true, - }) - } - } else { - if (!isNaN(value)) { - value += 'Gi' + + if (filteredEnv.length) commit('wizard/model$update', { - path: `/resources/${path}`, - value: value, + path: '/resources/kubedbComRedis/spec/monitor/prometheus/exporter/env', + value: filteredEnv, force: true, }) - } } -} - -function objectCopy(obj) { - const temp = JSON.stringify(obj) - return JSON.parse(temp) -} - -function isBindingAlreadyOn({ model, getValue }) { - const value = getValue(model, '/resources') - const keys = Object.keys(value) - isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComRedisBinding') - return isExposeBinding -} -async function addOrRemoveBinding({ commit, model, getValue, discriminator }) { - const value = getValue(discriminator, `/binding`) - const dbName = getValue(model, '/metadata/release/name') - const dbNamespace = getValue(model, '/metadata/release/namespace') - const labels = getValue(model, '/resources/kubedbComRedis/metadata/labels') - const bindingValues = { - apiVersion: 'catalog.appscode.com/v1alpha1', - kind: 'RedisBinding', - metadata: { - labels, - name: dbName, - namespace: dbNamespace, - }, - spec: { - sourceRef: { - name: dbName, - namespace: dbNamespace, - }, - }, - } + function initEnvArray() { + const env = getValue(model, '/resources/kubedbComRedis/spec/monitor/prometheus/exporter/env') - if (value) { - await commit('wizard/model$update', { - path: '/resources/catalogAppscodeComRedisBinding', - value: bindingValues, - force: true, - }) - } else { - await commit('wizard/model$delete', '/resources/catalogAppscodeComRedisBinding') + return env || [] } -} - -async function fetchTopologyMachines({ axios, getValue, storeGet, model, setDiscriminatorValue }) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComRedisAutoscaler/metadata/annotations', - ) - const 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 isEqualToTemp(value, index) { + //watchDependency('discriminator#/valueFromType') + const valueFrom = getValue(discriminator, `/env/${index}/temp/valueFromType`) + return valueFrom === value } -} -function setAllowedMachine({ model, getValue }, minmax) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComRedisAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - const mx = instance?.includes(',') ? instance.split(',')[1] : '' - const mn = instance?.includes(',') ? instance.split(',')[0] : '' - - if (minmax === 'min') return mn - else return mx -} - -async function getMachines({ getValue, watchDependency, discriminator }, minmax) { - watchDependency('discriminator#/topologyMachines') - const depends = minmax === 'min' ? 'max' : 'min' - const dependantPath = `/allowedMachine-${depends}` - - watchDependency(`discriminator#${dependantPath}`) - const dependantMachine = getValue(discriminator, dependantPath) - - const nodeGroups = getValue(discriminator, '/topologyMachines') || [] - - const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) - - const machines = nodeGroups?.map((item) => { - const subText = `CPU: ${item.allocatable.cpu}, Memory: ${item.allocatable.memory}` - const text = item.topologyValue - return { text, subText, value: item.topologyValue } - }) - console.log(machines) - - const filteredMachine = machines?.filter((item, ind) => - minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, - ) - - return dependantIndex === -1 ? machines : filteredMachine -} - -function hasAnnotations({ model, getValue }, type) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComRedisAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - - return !!instance -} - -function hasNoAnnotations({ model, getValue }) { - return !hasAnnotations({ model, getValue }) -} - -function onMachineChange({ model, getValue, discriminator, commit }, type) { - const annoPath = '/resources/autoscalingKubedbComRedisAutoscaler/metadata/annotations' - const annotations = getValue(model, annoPath) - const instance = annotations['kubernetes.io/instance-type'] - - const minMachine = getValue(discriminator, '/allowedMachine-min') - const maxMachine = getValue(discriminator, '/allowedMachine-max') - const minMaxMachine = `${minMachine},${maxMachine}` - annotations['kubernetes.io/instance-type'] = minMaxMachine - - const machines = getValue(discriminator, `/topologyMachines`) || [] - const minMachineObj = machines.find((item) => item.topologyValue === minMachine) - const maxMachineObj = machines.find((item) => item.topologyValue === maxMachine) - const minMachineAllocatable = minMachineObj?.allocatable - const maxMachineAllocatable = maxMachineObj?.allocatable - const allowedPath = `/resources/autoscalingKubedbComRedisAutoscaler/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 initMonitoring() { + const env = + getValue(model, '/resources/kubedbComRedis/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 { - handleUnit, - isConsole, - getNamespaces, - getDbs, - isKubedb, - getDbDetails, - dbTypeEqualsTo, - clearSpecModel, - initMetadata, - onNamespaceChange, - ifScalingTypeEqualsTo, - fetchNodeTopology, - isNodeTopologySelected, - setControlledResources, - setTrigger, - setApplyToIfReady, - showOpsRequestOptions, - fetchNames, - fetchNamespaces, - isRancherManaged, - onInputChangeSchedule, - getDefaultSchedule, - getBlueprints, - ifUsagePolicy, - initUsagePolicy, - isBlueprintOption, - initBlueprint, - getDefault, - onInputChange, - showBackupOptions, - showScheduleBackup, - isVariantAvailable, - fetchJsons, - disableLableChecker, - isEqualToModelPathValue, - isNotEqualToModelPathValue, - getResources, - isEqualToDiscriminatorPath, - setValueFromModel, - getNamespacedResourceList, - getRedisSentinels, - getResourceList, - resourceNames, - unNamespacedResourceNames, - returnTrue, - returnStringYes, - hasSentinelObject, - getRedisVersions, - onVersionChange, - ondeletionPolicyChange, - showAuthPasswordField, - showAuthSecretField, - showNewSecretCreateField, - showSentinelNameAndNamespace, - onCreateSentinelChange, - setCreateSentinel, - setDatabaseMode, - getStorageClassNames, - deleteDatabaseModePath, - isEqualToDatabaseMode, - setApiGroup, - getIssuerRefsName, - onIssuerRefChange, - setSSLMode, - showTlsConfigureSection, - onTlsConfigureChange, - getAliasOptions, - showMonitoringSection, - onEnableMonitoringChange, - showCustomizeExporterSection, - onCustomizeExporterChange, - valueExists, - initPrePopulateDatabase, - onPrePopulateDatabaseChange, - initDataSource, - onDataSourceChange, - initVolumeType, - onVolumeTypeChange, - showInitializationForm, - showScriptOrStashForm, - showConfigMapOrSecretName, - initializeNamespace, - showRepositorySelectOrCreate, - onInitRepositoryChoiseChange, - initCustomizeRestoreJobRuntimeSettings, - initCustomizeRestoreJobRuntimeSettingsForBackup, - onCustomizeRestoreJobRuntimeSettingsChange, - onCustomizeRestoreJobRuntimeSettingsChangeForBackup, - showRuntimeForm, - getImagePullSecrets, - getBackupConfigsAndAnnotations, - deletekubedbComRedisAnnotation, - addkubedbComRedisAnnotation, - initScheduleBackup, - initScheduleBackupForEdit, - onScheduleBackupChange, - showBackupForm, - initBackupInvoker, - onBackupInvokerChange, - showInvokerForm, - initalizeTargetReferenceName, - setInitialRestoreSessionRepo, - initRepositoryChoise, - initRepositoryChoiseForEdit, - onRepositoryChoiseChange, - onRepositoryNameChange, - getMongoAnnotations, - initFromAnnotationValue, - onBackupBlueprintNameChange, - onBackupBlueprintScheduleChange, - initFromAnnotationKeyValue, - onTaskParametersChange, - isValueExistInModel, - onNamespaceChange, - onLabelChange, - onNameChange, - returnFalse, - onAgentChange, - onServiceMonitorChange, - getCreateAuthSecret, - showExistingSecretSection, - showPasswordSection, - disableInitializationSection, - setAuthSecretPassword, - onAuthSecretPasswordChange, - encodePassword, - decodePassword, - onCreateAuthSecretChange, - getSecrets, - isEqualToServiceMonitorType, - onConfigurationSourceChange, - onConfigurationChange, - setConfigurationSource, - setSecretConfigNamespace, - setConfiguration, - setConfigurationFiles, - onSetCustomConfigChange, - getOpsRequestUrl, - getCreateNameSpaceUrl, - setStorageClass, - - initBackupData, - isBackupDataLoadedTrue, - setBackupType, - getTypes, - isBackupType, - getContext, - onContextChange, - getConfigList, - onConfigChange, - showPause, - showSchedule, - showConfigList, - setBlueprintSwitch, - onBlueprintChange, - setArchiverSwitch, - onArchiverChange, - onBackupTypeChange, - getNamespaceArray, - isBindingAlreadyOn, - addOrRemoveBinding, - getMachines, - setAllowedMachine, - hasAnnotations, - hasNoAnnotations, - fetchTopologyMachines, - onMachineChange, + 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, + + getDbDetails, + isKubedb, + isConsole, + getNamespaces, + isRancherManaged, + onNamespaceChange, + initMetadata, + fetchTopologyMachines, + setTrigger, + onTriggerChange, + hasAnnotations, + setAllowedMachine, + getMachines, + onMachineChange, + hasNoAnnotations, + setControlledResources, + fetchNodeTopology, + isNodeTopologySelected, + showOpsRequestOptions, + setApplyToIfReady, + dbTypeEqualsTo, + handleUnit, + + getOpsRequestUrl, + isValueExistInModel, + onEnableMonitoringChange, + showMonitoringSection, + onAgentChange, + getResources, + isEqualToModelPathValue, + onCustomizeExporterChange, + showCustomizeExporterSection, + onLabelChange, + setValueFrom, + onValueFromChange, + resourceNames, + getConfigMapKeys, + getSecrets, + getSecretKeys, + isConfigMapTypeValueFrom, + isSecretTypeValueFrom, + getNamespacedResourceList, + returnFalse, + onEnvArrayChange, + initEnvArray, + isEqualToTemp, + initMonitoring, + + isBindingAlreadyOn, + addOrRemoveBinding, + + setValueFromDbDetails, + } } diff --git a/charts/kubedbcom-singlestore-editor-options/ui/create-ui.yaml b/charts/kubedbcom-singlestore-editor-options/ui/create-ui.yaml index 543652568e..984927985d 100644 --- a/charts/kubedbcom-singlestore-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-singlestore-editor-options/ui/create-ui.yaml @@ -1,407 +1,463 @@ -steps: -- form: - discriminator: - bundleApiLoaded: - default: false - type: boolean +step: +- type: single-step-form + loader: initBundle + elements: + - if: + type: function + name: returnFalse + init: + type: func + value: initBundle + label: '' + type: label-element + - type: label-element + label: '' + subtitle: Select the SingleStore version you want to deploy on Kubernetes. The chosen version determines the SingleStore engine features, compatibility, and runtime behavior of your distributed SQL database. + - disableUnselect: true + loader: getAdminOptions|databases/Singlestore/versions + if: + type: function + name: isToggleOn|databases/Singlestore/versions + label: Database Version + schema: schema/properties/spec/properties/admin/properties/databases/properties/Singlestore/properties/versions/properties/default + type: select + - init: + type: func + value: getDefault|databases/Singlestore/mode + loader: getAdminOptions|databases/Singlestore/mode + isHorizontal: true + if: + type: function + name: isToggleOn|databases/Singlestore/mode + label: Database Mode + watcher: + func: toggleTls + paths: + - schema/properties/spec/properties/mode + schema: schema/properties/spec/properties/mode + type: radio + - elements: + - type: label-element + label: '' + subtitle: Aggregator nodes handle query processing and coordination. Configure replicas, storage, and resource allocation for efficient query execution and result aggregation. + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setReplicaNumber + label: Replica number + schema: schema/properties/spec/properties/topology/properties/aggregator/properties/replicas + type: input + - label: Storage Size + schema: schema/properties/spec/properties/topology/properties/aggregator/properties/persistence/properties/size + type: input + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/topology/properties/aggregator/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu|topology/aggregator + disable: isMachineNotCustom|topology/aggregator + if: + type: function + name: isMachineCustom|topology/aggregator + label: CPU + loader: setLimits|cpu|topology/aggregator + watcher: + func: setRequests|cpu|topology/aggregator + paths: + - schema/properties/spec/properties/topology/properties/aggregator/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/topology/properties/aggregator/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/aggregator/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory|topology/aggregator + disable: isMachineNotCustom|topology/aggregator + if: + type: function + name: isMachineCustom|topology/aggregator + label: Memory + loader: setLimits|memory|topology/aggregator + watcher: + func: setRequests|memory|topology/aggregator + paths: + - schema/properties/spec/properties/topology/properties/aggregator/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/topology/properties/aggregator/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/aggregator/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + if: + type: function + name: isEqualToModelPathValue|Topology|/spec/mode + label: Aggregator + showLabels: true + type: block-layout + - elements: + - type: label-element + label: '' + subtitle: Leaf nodes store and manage data partitions. Configure replicas, storage, and resource allocation for optimal data storage and query performance. + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setReplicaNumber + label: Replica number + schema: schema/properties/spec/properties/topology/properties/leaf/properties/replicas + type: input + - label: Storage Size + schema: schema/properties/spec/properties/topology/properties/leaf/properties/persistence/properties/size + type: input + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/topology/properties/leaf/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu|topology/leaf + disable: isMachineNotCustom|topology/leaf + if: + type: function + name: isMachineCustom|topology/leaf + label: CPU + loader: setLimits|cpu|topology/leaf + watcher: + func: setRequests|cpu|topology/leaf + paths: + - schema/properties/spec/properties/topology/properties/leaf/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/topology/properties/leaf/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/leaf/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory|topology/leaf + disable: isMachineNotCustom|topology/leaf + if: + type: function + name: isMachineCustom|topology/leaf + label: Memory + loader: setLimits|memory|topology/leaf + watcher: + func: setRequests|memory|topology/leaf + paths: + - schema/properties/spec/properties/topology/properties/leaf/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/topology/properties/leaf/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/leaf/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + if: + type: function + name: isEqualToModelPathValue|Topology|/spec/mode + label: Leaf + showLabels: true + type: block-layout + - elements: + - type: label-element + label: '' + subtitle: Select a machine profile to allocate CPU and memory resources for your distributed SQL database. Choose 'custom' to manually specify resource requirements or select a predefined profile. + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: CPU + loader: setLimits|cpu + watcher: + func: setRequests|cpu + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: Memory + loader: setLimits|memory + watcher: + func: setRequests|memory + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + if: + type: function + name: isEqualToModelPathValue|Standalone|/spec/mode + label: Machine Profile + showLabels: true + type: block-layout + - elements: + - type: horizontal-layout + showLabels: true + elements: + - loader: getAdminOptions|storageClasses + if: + type: function + name: isToggleOn|storageClasses + label: Storage Class + schema: schema/properties/spec/properties/admin/properties/storageClasses/properties/default + type: select + - label: Storage Size + schema: schema/properties/spec/properties/persistence/properties/size + type: input + if: + type: function + name: isEqualToModelPathValue|Standalone|/spec/mode + type: block-layout + - loader: getSecrets + label: License Secret + refresh: true + schema: schema/properties/spec/properties/licenseSecret/properties/name + type: select + - description: Configure Credentials, Deployment Mode etc. elements: - - computed: initBundle - if: returnFalse - type: label-element - - disableUnselect: true - fetch: getAdminOptions|databases/Singlestore/versions - if: isToggleOn|databases/Singlestore/versions - label: - text: labels.database.version - schema: - $ref: schema#/properties/spec/properties/admin/properties/databases/properties/Singlestore/properties/versions/properties/default - type: select - - computed: getDefault|databases/Singlestore/mode - fetch: getAdminOptions|databases/Singlestore/mode - hasDescription: true - if: isToggleOn|databases/Singlestore/mode - label: - text: labels.database.mode - onChange: toggleTls - schema: - $ref: schema#/properties/spec/properties/mode - type: radio - - elements: - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/topology/properties/aggregator/properties/persistence/properties/size - type: input - - computed: setReplicaNumber - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/topology/properties/aggregator/properties/replicas - type: input - - computed: setMachineToCustom - customClass: mt-10 - fetch: getMachineListForOptions - label: - text: labels.machine - schema: - $ref: schema#/properties/spec/properties/topology/properties/aggregator/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu|topology/aggregator - disabled: isMachineNotCustom|topology/aggregator - if: isMachineCustom|topology/aggregator - label: - text: labels.cpu - onChange: setRequests|cpu|topology/aggregator - schema: - $ref: schema#/properties/spec/properties/topology/properties/aggregator/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory|topology/aggregator - disabled: isMachineNotCustom|topology/aggregator - if: isMachineCustom|topology/aggregator - label: - text: labels.cpu - onChange: setRequests|memory|topology/aggregator - schema: - $ref: schema#/properties/spec/properties/topology/properties/aggregator/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - if: isEqualToModelPathValue|Topology|/spec/mode - label: - text: Aggregator - show_label: true - type: single-step-form - elements: - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/topology/properties/leaf/properties/persistence/properties/size - type: input - - computed: setReplicaNumber - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/topology/properties/leaf/properties/replicas - type: input - - computed: setMachineToCustom - customClass: mt-10 - fetch: getMachineListForOptions - label: - text: labels.machine - schema: - $ref: schema#/properties/spec/properties/topology/properties/leaf/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu|topology/leaf - disabled: isMachineNotCustom|topology/leaf - if: isMachineCustom|topology/leaf - label: - text: labels.cpu - onChange: setRequests|cpu|topology/leaf - schema: - $ref: schema#/properties/spec/properties/topology/properties/leaf/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory|topology/leaf - disabled: isMachineNotCustom|topology/leaf - if: isMachineCustom|topology/leaf - label: - text: labels.memory - onChange: setRequests|memory|topology/leaf - schema: - $ref: schema#/properties/spec/properties/topology/properties/leaf/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - if: isEqualToModelPathValue|Topology|/spec/mode - label: - text: Leaf - show_label: true - type: single-step-form - - elements: - - computed: setMachineToCustom - customClass: mt-10 - fetch: getMachineListForOptions - label: - text: labels.machine - schema: - $ref: schema#/properties/spec/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.cpu - onChange: setRequests|cpu - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.memory - onChange: setRequests|memory - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - if: isEqualToModelPathValue|Standalone|/spec/mode - label: - text: labels.machine_profile - show_label: true - type: single-step-form - - fetch: getAdminOptions|storageClasses - if: isToggleOn|storageClasses - label: - text: labels.storage.class - schema: - $ref: schema#/properties/spec/properties/admin/properties/storageClasses/properties/default + - type: label-element + label: '' + subtitle: Add custom labels and annotations to your database resources for organization, monitoring, and integration with other Kubernetes tools and services. + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/annotations + hideBlock: true + label: Labels & Annotations + showLabels: true + type: block-layout + - init: + type: func + value: getDefault|deletionPolicy + customClass: mt-20 + if: + type: function + name: isToggleOn|deletionPolicy + label: Deletion Policy + watcher: + func: setStorageClass + paths: + - schema/properties/spec/properties/deletionPolicy + options: + - description: options.deletionPolicy.delete.description + text: Delete + value: Delete + - description: options.deletionPolicy.halt.description + text: Halt + value: Halt + - description: options.deletionPolicy.wipeOut.description + text: WipeOut + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: DoNotTerminate + value: DoNotTerminate + schema: schema/properties/spec/properties/deletionPolicy type: select - - if: isEqualToModelPathValue|Standalone|/spec/mode - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/persistence/properties/size + - if: + type: function + name: getDefaultValue|spec/admin/authCredential/customize + label: Provide Authentication Credentials? + watcher: + func: onAuthChange + paths: + - temp/createAuthSecret + schema: temp/createAuthSecret + type: switch + - if: + type: function + name: showReferSecretSwitch + label: Refer existing Secret? + watcher: + func: onReferSecretChange + paths: + - temp/referSecret + schema: temp/referSecret + type: switch + - loader: getReferSecrets + if: + type: function + name: showSecretDropdown + label: Secret + schema: schema/properties/spec/properties/authSecret/properties/name + type: select + - if: + type: function + name: showReferSecret + label: Password + schema: schema/properties/spec/properties/authSecret/properties/password type: input - - fetch: getSecrets - label: - text: labels.licenseSecret - refresh: true - schema: - $ref: schema#/properties/spec/properties/licenseSecret/properties/name + - if: + type: function + name: getDefaultValue|spec/admin/customConfiguration + label: Configure Database? + watcher: + func: clearConfiguration + paths: + - temp/configDatabase + schema: temp/configDatabase + type: switch + - if: + type: function + name: isConfigDatabaseOn + label: Configuration + schema: schema/properties/spec/properties/configuration + type: textarea + - if: + type: function + name: isToggleOn|deployment + label: Deployment Mode + options: + - description: shared + text: Shared + value: Shared + - description: Dedicated + text: Dedicated + value: Dedicated + schema: schema/properties/spec/properties/admin/properties/deployment/properties/default + type: radio + - if: + type: function + name: isToggleOn|clusterTier + isHorizontal: true + label: Cluster Tier + options: + - text: General Purpose + value: GeneralPurpose + - text: Memory Optimized + value: MemoryOptimized + - text: CPU Optimized + value: CPUOptimized + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/default + type: radio + - disableUnselect: true + loader: getAdminOptions|clusterTier/placement + if: + type: function + name: isToggleOn|clusterTier/placement + label: Placement Policy + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default type: select - - accordion: true - description: - text: Configure Credentials, Deployment Mode etc. - discriminator: - configDatabase: - default: false - type: boolean - createAuthSecret: - default: false - type: boolean - referSecret: - default: false - type: boolean - elements: - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties - type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties - type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - computed: getDefault|deletionPolicy - customClass: mt-20 - if: isToggleOn|deletionPolicy - 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/spec/properties/deletionPolicy - type: select - - if: getDefaultValue|spec/admin/authCredential/customize - label: - text: Provide Authentication Credentials? - onChange: onAuthChange - schema: - $ref: discriminator#/createAuthSecret - type: switch - - if: showReferSecretSwitch - label: - text: Refer existing Secret? - onChange: onReferSecretChange - schema: - $ref: discriminator#/referSecret - type: switch - - fetch: getReferSecrets - if: showSecretDropdown - label: - text: Secret - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/name - type: select - - if: showReferSecret - label: - text: labels.password - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/password - type: input - - computed: isConfigAvailable - if: getDefaultValue|spec/admin/customConfiguration - label: - text: Configure Database? - onChange: clearConfiguration - schema: - $ref: discriminator#/configDatabase + - disableUnselect: true + loader: getNodeTopology + if: + type: function + name: isToggleOn|clusterTier/nodeTopology + label: Node Topology + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + type: select + hideBlock: true + label: Advanced Configuration + showLabels: true + type: block-layout + - description: Enable Backup, Monitoring, TLS etc. + elements: + - elements: + - init: + type: func + value: setMonitoring + label: Enable Monitoring + watcher: + func: updateAlertValue + paths: + - temp/monitoring + schema: temp/monitoring type: switch - - if: isConfigDatabaseOn - label: - text: Configuration - schema: - $ref: schema#/properties/spec/properties/configuration - type: editor - - hasDescription: true - if: isToggleOn|deployment - label: - text: labels.deployment.name - options: - - description: labels.deployment.shared - text: Shared - value: Shared - - description: labels.deployment.dedicated - text: Dedicated - value: Dedicated - schema: - $ref: schema#/properties/spec/properties/admin/properties/deployment/properties/default - type: radio - - if: isToggleOn|clusterTier - isHorizontal: true - label: - text: labels.clusterTier + - customClass: mt-10 + if: + type: function + name: showAlerts + label: Alert Options options: - - text: General Purpose - value: GeneralPurpose - - text: Memory Optimized - value: MemoryOptimized - - text: CPU Optimized - value: CPUOptimized - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/default - type: radio - - disableUnselect: true - fetch: getAdminOptions|clusterTier/placement - if: isToggleOn|clusterTier/placement - label: - text: labels.placement - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + - text: None + value: none + - text: Critical + value: critical + - text: Warning + value: warning + - text: Info + value: info + schema: schema/properties/form/properties/alert/properties/enabled type: select - - disableUnselect: true - fetch: getNodeTopology - if: isToggleOn|clusterTier/nodeTopology - label: - text: labels.nodeTopology - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default - type: select - hideForm: true - label: - text: Advanced Configuration - show_label: true - type: single-step-form - - accordion: true - description: - text: Enable Backup, Monitoring, TLS etc. - discriminator: - backup: - default: false - type: boolean - elements: - - discriminator: - monitoring: - default: false - type: boolean - elements: - - computed: setMonitoring - label: - text: labels.enable_monitoring - onChange: updateAlertValue - schema: - $ref: discriminator#/monitoring - type: switch - - customClass: mt-10 - if: showAlerts - label: - text: labels.alert.options - options: - - text: None - value: none - - text: Critical - value: critical - - text: Warning - value: warning - - text: Info - value: info - schema: - $ref: schema#/properties/form/properties/alert/properties/enabled - sortable: true - type: select - if: isToggleOn|monitoring - type: single-step-form - - computed: setBackup - if: isToggleOn|backup - label: - text: Enable Backup? - onChange: onBackupSwitch - schema: - $ref: discriminator#/backup - type: switch - - elements: - - computed: toggleTls - label: - text: Enable TLS? - schema: - $ref: schema#/properties/spec/properties/admin/properties/tls/properties/default - type: switch - - fetch: getAdminOptions|clusterIssuers - if: showIssuer - label: - text: labels.clusterIssuers - required: true - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterIssuers/properties/default - type: select - if: isEqualToModelPathValue|Topology|/spec/mode - type: single-step-form - - if: isToggleOn|expose - label: - text: Expose via Gateway? - schema: - $ref: schema#/properties/spec/properties/admin/properties/expose/properties/default + if: + type: function + name: isToggleOn|monitoring + type: block-layout + - init: + type: func + value: setBackup + if: + type: function + name: isToggleOn|backup + label: Enable Backup? + watcher: + func: onBackupSwitch + paths: + - temp/backup + schema: temp/backup + type: switch + - elements: + - init: + type: func + value: toggleTls|true + label: Enable TLS? + schema: schema/properties/spec/properties/admin/properties/tls/properties/default type: switch - if: showAdditionalSettings - label: - text: Additional Options - show_label: true - type: single-step-form - type: single-step-form + - loader: getAdminOptions|clusterIssuers + if: + type: function + name: showIssuer + label: Cluster Issuers + validation: + type: required + schema: schema/properties/spec/properties/admin/properties/clusterIssuers/properties/default + type: select + if: + type: function + name: isEqualToModelPathValue|Topology|/spec/mode + type: block-layout + - if: + type: function + name: isToggleOn|expose + label: Expose via Gateway? + schema: schema/properties/spec/properties/admin/properties/expose/properties/default + type: switch + if: + type: function + name: showAdditionalSettings + label: Additional Options + showLabels: true + type: block-layout id: options - title: steps.0.label + # title: steps.0.label type: multi-step-form diff --git a/charts/kubedbcom-singlestore-editor-options/ui/functions.js b/charts/kubedbcom-singlestore-editor-options/ui/functions.js index 05671774a1..768f9db149 100644 --- a/charts/kubedbcom-singlestore-editor-options/ui/functions.js +++ b/charts/kubedbcom-singlestore-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -315,1063 +317,1114 @@ const modeDetails = { }, } -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) -function showAuthSecretField({ discriminator, getValue, watchDependency }) { - return !showAuthPasswordField({ - discriminator, - getValue, - watchDependency, - }) -} + setDiscriminatorValue('bundleApiLoaded', false) + setDiscriminatorValue('createAuthSecret', false) + setDiscriminatorValue('referSecret', false) + setDiscriminatorValue('configDatabase', false) + setDiscriminatorValue('monitoring', false) + setDiscriminatorValue('backup', false) -async function getResources({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function clearArbiterHidden() { + commit('wizard/model$update', { + path: `/spec/arbiter/enabled`, + value: false, + force: true, + }) - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + commit('wizard/model$update', { + path: `/spec/hidden/enabled`, + value: false, + force: true, + }) + } - const resources = (resp && resp.data && resp.data.items) || [] + function clearConfiguration() { + const configOn = getValue(discriminator, '/configDatabase') - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return resources -} + if (!configOn) { + commit('wizard/model$delete', '/spec/configuration') + } + } -async function getMySqlVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + const dedicatedOnChange = () => { + const val = getValue(model, 'form/capi/dedicated') + if (!val) { + commit('wizard/model$delete', 'form/capi/zones') + commit('wizard/model$delete', 'form/capi/sku') + } + } - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, - }, - }, + async function fetchJsons() { + 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, + } } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) + function filterNodeTopology(list, tier, provider) { + // first filter the list from value that exists from the filtered list got from API + const filteredlist = list - const resources = (resp && resp.data && resp.data.items) || [] + // filter the list based on clusterTier + if (provider === 'EKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('c') + else if (tier === 'MemoryOptimized') return item.startsWith('r') + else return !item.startsWith('c') && !item.startsWith('r') + }) + } else if (provider === 'AKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') + else if (tier === 'MemoryOptimized') + return ( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + else + return ( + !(item.startsWith('f') || item.startsWith('fx')) && + !( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + ) + }) + } else if (provider === 'GKE') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') + return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') + else if (tier === 'MemoryOptimized') + return ( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + else + return ( + !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && + !( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + ) + }) + } else return filteredlist + } - // keep only non deprecated versions - const filteredMySqlVersions = resources.filter((item) => item.spec && !item.spec.deprecated) + function getCreateNameSpaceUrl() { + const user = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - filteredMySqlVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredMySqlVersions -} + const domain = storeGet('/domain') || '' + if (domain.includes('bb.test')) { + return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } + } -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/spec/authSecret/name') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/spec/authSecret/password') + function getDefault(type) { + const val = getValue(model, `/spec/admin/${type}/default`) || '' + return val } -} -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') + function getDefaultValue(path) { + const val = getValue(model, `/${path}`) || '' + return val + } - if (owner && cluster && namespace) { + let array = [] + function getMachineListForOptions() { + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + if (available.length) { + array = available.map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + else { + let subText = '', + text = '' + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + text = machineData.name ? machineData.name : machineData.id + } + return { text, subText, value: machine } + } + }) + } else { + array = machineList + .map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { text, subText, value: machine } + }) + .filter((val) => !!val) + } + return array + } + + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, { - params: { - filter: { - items: { - data: { username: null, password: null }, - metadata: { name: null }, - type: null, + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, }, - }, + ], }, }, ) - - const secrets = (resp && resp.data && resp.data.items) || [] - - const filteredSecrets = secrets.filter((item) => { - const validType = [ - 'kubernetes.io/service-account-token', - 'Opaque', - 'kubernetes.io/basic-auth', - ] - 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 + if (resp.data?.status?.projects) { + const projects = resp.data?.status?.projects + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } } catch (e) { console.log(e) } + return [] } - return [] -} -function getMachineListForOptions({ model, getValue }) { - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - let array = [] + async function getReferSecrets() { + const referSecret = getValue(discriminator, '/referSecret') + if (!referSecret) { + return [] + } - if (available.length) { - array = available.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - else { - let subText = '', - text = '' - const machineData = machinesFromPreset.find((val) => val.id === machine) - if (machineData) { - subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` - text = machineData.name ? machineData.name : machineData.id - } - return { text, subText, value: machine } - } - }) - } else { - array = machineList - .map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/metadata/release/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` + + const options = [] + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) }) - .filter((val) => !!val) + } catch (e) { + console.log(e) + } + return options } - return array -} - -function setMachineToCustom({ getValue, model }) { - const machine = getValue(model, '/spec/admin/machineProfiles/default') - return machine || 'custom' -} -async function fetchJsons({ axios, itemCtx }) { - let ui = {} - let language = {} - let functions = {} - const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - 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}`, + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, ) - // 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 updateAgentValue({ commit }, val) { - commit('wizard/model$update', { - path: '/spec/monitoring/agent', - value: val ? 'prometheus.io/operator' : '', - force: true, - }) - - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: val ? 'warning' : 'none', - force: true, - }) -} + const resources = (resp && resp.data && resp.data.items) || [] -function setReplicaNumber({ model, getValue }) { - const modelPathValue = getValue(model, '/spec/mode') - if (modelPathValue === 'Topology') { - return 2 - } else return 1 -} -function setRouterNumber({ model, getValue }) { - const modelPathValue = getValue(model, '/spec/mode') - if (modelPathValue === 'Topology') { - return 3 - } else return 1 -} - -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true + }) + return resources } -} -const ifCapiProviderIsNotEmpty = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/provider') - const val = getValue(model, '/form/capi/provider') - if (val) return true -} + 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') + + if (owner && cluster && namespace) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { + items: { + data: { username: null, password: null }, + metadata: { name: null }, + type: null, + }, + }, + }, + }, + ) -const showMultiselectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') + const secrets = (resp && resp.data && resp.data.items) || [] - if (val === 'capz' && ifDedicated({ model, getValue })) return true -} + const filteredSecrets = secrets.filter((item) => { + const validType = [ + 'kubernetes.io/service-account-token', + 'Opaque', + 'kubernetes.io/basic-auth', + ] + return validType.includes(item.type) + }) -const showSelectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') - if (val !== 'capz' && ifDedicated({ model, getValue })) return true -} + 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 [] + } -const ifDedicated = ({ model, getValue }) => { - const val = getValue(model, 'form/capi/dedicated') - if (val) return true -} + async function getSKU() { + // watchDependency('model#/form/capi/zones') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const zones = getValue(model, 'form/capi/zones') || [] + if (zones.length) { + try { + let url = `clustersv2/${owner}/${cluster}/vms?` + if (typeof zones === 'string') { + url += `zones=${encodeURIComponent(zones)}` + } else { + zones.forEach((item) => { + url += `zones=${encodeURIComponent(item)}&` + }) + url = url.slice(0, -1) + } + const resp = await axios.get(url) + const val = resp.data.map((item) => { + return { + value: item.name, + text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, + } + }) + return val + } catch (e) { + console.log(e) + return [] + } + } + } -const dedicatedOnChange = ({ model, getValue, commit }) => { - const val = getValue(model, 'form/capi/dedicated') - if (!val) { - commit('wizard/model$delete', 'form/capi/zones') - commit('wizard/model$delete', 'form/capi/sku') + async function getZones() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const isDedicated = getValue(model, 'form/capi/dedicated') + if (isDedicated) { + try { + const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) + const val = resp.data.map((item) => { + return { value: item, text: item } + }) + return val + } catch (e) { + console.log(e) + return [] + } + } } -} -const ifZones = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/zones') - watchDependency('model#/form/capi/dedicated') - const zones = getValue(model, 'form/capi/zones') || [] - const isDedicated = getValue(model, 'form/capi/dedicated') - if (zones.length && isDedicated) return true -} + const ifCapiProviderIsNotEmpty = () => { + // watchDependency('model#/form/capi/provider') + const val = getValue(model, '/form/capi/provider') + if (val) return true + } -const zonesOnChange = ({ model, getValue, commit }) => { - const zones = getValue(model, 'form/capi/zones') || [] - if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') -} + const ifDedicated = () => { + const val = getValue(model, 'form/capi/dedicated') + if (val) return true + } -async function getZones({ storeGet, axios, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const isDedicated = getValue(model, 'form/capi/dedicated') - if (isDedicated) { - try { - const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) - const val = resp.data.map((item) => { - return { value: item, text: item } - }) - return val - } catch (e) { - console.log(e) - return [] - } + const ifZones = () => { + // watchDependency('model#/form/capi/zones') + // watchDependency('model#/form/capi/dedicated') + const zones = getValue(model, 'form/capi/zones') || [] + const isDedicated = getValue(model, 'form/capi/dedicated') + if (zones.length && isDedicated) return true } -} -async function getSKU({ storeGet, axios, model, getValue, watchDependency }) { - watchDependency('model#/form/capi/zones') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const zones = getValue(model, 'form/capi/zones') || [] - if (zones.length) { + let placement = [] + let versions = [] + let storageClass = [] + let clusterIssuers = [] + let nodetopologiesShared = [] + let nodetopologiesDedicated = [] + let features = [] + async function initBundle() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + + let db = getValue(model, '/metadata/resource/kind') + db = db.toLowerCase() + let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` + const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` + try { - let url = `clustersv2/${owner}/${cluster}/vms?` - if (typeof zones === 'string') { - url += `zones=${encodeURIComponent(zones)}` - } else { - zones.forEach((item) => { - url += `zones=${encodeURIComponent(item)}&` + const resp = await axios.get(url) + features = resp.data.features || [] + placement = resp.data.placementpolicies || [] + versions = resp.data.versions || [] + storageClass = resp.data.storageclasses || [] + clusterIssuers = resp.data.clusterissuers || [] + nodetopologiesDedicated = resp.data.dedicated || [] + nodetopologiesShared = resp.data.shared || [] + + const response = await axios.get(annotationUrl) + const annotations = response.data?.metadata?.annotations || {} + const uidRange = annotations['openshift.io/sa.scc.uid-range'] + if (uidRange) { + const val = uidRange.split('/')[0] + commit('wizard/model$update', { + path: '/spec/openshift/securityContext/runAsUser', + value: val, + force: true, }) - url = url.slice(0, -1) } - const resp = await axios.get(url) - const val = resp.data.map((item) => { - return { - value: item.name, - text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, - } - }) - return val } catch (e) { console.log(e) - return [] } - } -} -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} - -function setStorageClass({ model, getValue, commit, discriminator, watchDependency }) { - const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' - let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' - const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] - const suffix = '-retain' - - const simpleClassList = storageClassList.filter((item) => { - return !item.endsWith(suffix) - }) - const retainClassList = storageClassList.filter((item) => { - return item.endsWith(suffix) - }) - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] - } else { - storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] - } - - const isChangeable = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'storageClasses', - ) - if (isChangeable && storageClass) { commit('wizard/model$update', { - path: '/spec/admin/storageClasses/default', - value: storageClass, + path: '/spec/deletionPolicy', + value: getDefault('deletionPolicy'), force: true, }) - } -} -function showAlerts({ watchDependency, model, getValue, discriminator }) { - watchDependency('discriminator#/monitoring') - const isMonitorEnabled = getValue(discriminator, '/monitoring') - return ( - isMonitorEnabled && isToggleOn({ getValue, model, discriminator, watchDependency }, 'alert') - ) -} - -function onBackupSwitch({ discriminator, getValue, commit }) { - const isBackupOn = getValue(discriminator, '/backup') - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: isBackupOn ? 'KubeStash' : '', - force: true, - }) -} - -function clearArbiterHidden({ commit }) { - commit('wizard/model$update', { - path: `/spec/arbiter/enabled`, - value: false, - force: true, - }) - - commit('wizard/model$update', { - path: `/spec/hidden/enabled`, - value: false, - force: true, - }) -} + if (!getValue(model, `/spec/admin/databases/Singlestore/mode/toggle`)) { + let defMode = getDefault('databases/Singlestore/mode') || '' + if (defMode === '') { + const arr = getValue(model, '/spec/databases/Singlestore/mode/available') || [] + if (arr.length) defMode = arr[0] + } + commit('wizard/model$update', { + path: '/spec/mode', + value: defMode, + force: true, + }) + } -let placement = [] -let versions = [] -let storageClass = [] -let clusterIssuers = [] -let nodetopologiesShared = [] -let nodetopologiesDedicated = [] -let features = [] -async function initBundle({ commit, model, getValue, axios, storeGet, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - - let db = getValue(model, '/metadata/resource/kind') - db = db.toLowerCase() - let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` - const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - - try { - const resp = await axios.get(url) - features = resp.data.features || [] - placement = resp.data.placementpolicies || [] - versions = resp.data.versions || [] - storageClass = resp.data.storageclasses || [] - clusterIssuers = resp.data.clusterissuers || [] - nodetopologiesDedicated = resp.data.dedicated || [] - nodetopologiesShared = resp.data.shared || [] - - const response = await axios.get(annotationUrl) - const annotations = response.data?.metadata?.annotations || {} - const uidRange = annotations['openshift.io/sa.scc.uid-range'] - if (uidRange) { - const val = uidRange.split('/')[0] + if (!features.includes('tls')) { + commit('wizard/model$update', { + path: '/spec/admin/tls/default', + value: false, + force: true, + }) + } + if (!features.includes('binding')) { + commit('wizard/model$update', { + path: '/spec/admin/expose/default', + value: false, + force: true, + }) + } + if (!features.includes('monitoring')) { + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: '', + force: true, + }) commit('wizard/model$update', { - path: '/spec/openshift/securityContext/runAsUser', - value: val, + path: '/form/alert/enabled', + value: 'none', force: true, }) } - } catch (e) { - console.log(e) + if (!features.includes('backup')) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: '', + force: true, + }) + } + + setDiscriminatorValue('/bundleApiLoaded', true) } - commit('wizard/model$update', { - path: '/spec/deletionPolicy', - value: getDefault({ getValue, model }, 'deletionPolicy'), - force: true, - }) - - if (!getValue(model, `/spec/admin/databases/Singlestore/mode/toggle`)) { - let defMode = getDefault({ getValue, model }, 'databases/Singlestore/mode') || '' - if (defMode === '') { - const arr = getValue(model, '/spec/databases/Singlestore/mode/available') || [] - if (arr.length) defMode = arr[0] - } - commit('wizard/model$update', { - path: '/spec/mode', - value: defMode, - force: true, - }) + function isConfigDatabaseOn() { + // watchDependency('discriminator#/configDatabase') + return getValue(discriminator, '/configDatabase') } - if (!features.includes('tls')) { - commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: false, - force: true, - }) + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value } - if (!features.includes('binding')) { - commit('wizard/model$update', { - path: '/spec/admin/expose/default', - value: false, - force: true, - }) + + function isMachineCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue === 'custom' + } + + function isMachineNotCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue !== 'custom' && !!modelPathValue + } + + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } + + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false } - if (!features.includes('monitoring')) { + + function notEqualToDatabaseMode(mode) { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + return modelPathValue && modelPathValue !== mode + } + + function onAuthChange() { commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', + path: '/spec/authSecret/name', value: '', force: true, }) commit('wizard/model$update', { - path: '/form/alert/enabled', - value: 'none', + path: '/spec/authSecret/password', + value: '', force: true, }) } - if (!features.includes('backup')) { - commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, - force: true, - }) + + function onBackupSwitch() { + const isBackupOn = getValue(discriminator, '/backup') commit('wizard/model$update', { path: '/spec/backup/tool', - value: '', + value: isBackupOn ? 'KubeStash' : '', force: true, }) } - setDiscriminatorValue('/bundleApiLoaded', true) -} - -function fetchOptions({ model, getValue, commit }, type) { - let kind = getValue(model, '/metadata/resource/kind') - - let returnArray = [] - if (type === 'clusterTier/placement') { - returnArray = placement - } else if (type === `databases/${kind}/versions`) { - returnArray = versions - } else if (type === 'storageClasses') { - returnArray = storageClass - } else if (type === 'clusterIssuers') { - returnArray = clusterIssuers + function onCreateAuthSecretChange() { + const createAuthSecret = getValue(discriminator, '/createAuthSecret') + if (createAuthSecret) { + commit('wizard/model$delete', '/spec/authSecret/name') + } else if (createAuthSecret === false) { + commit('wizard/model$delete', '/spec/authSecret/password') + } } - if (returnArray.length === 1) { - const path = `/spec/admin/${type}/default` + function onReferSecretChange() { commit('wizard/model$update', { - path: path, - value: returnArray[0], + path: '/spec/authSecret/name', + value: '', force: true, }) } - return returnArray -} + function returnFalse() { + return false + } -function getAdminOptions({ getValue, model, watchDependency, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') + function setBackup() { + const backup = getValue(model, '/spec/backup/tool') + const val = getValue(model, '/spec/admin/backup/enable/default') + return backup === 'KubeStash' && features.includes('backup') && val + } - const options = getValue(model, `/spec/admin/${type}/available`) || [] + function setLimits(resource, type) { + const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' + // watchDependency(`model#${path}`) + const selectedMachine = getValue(model, path) || 'custom' + const reqCommitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + const comparePath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + + const resourceValue = getValue(model, comparePath) + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + let cpu = '', + memory = '' + if (available.length && selectedMachine !== 'custom') { + const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) + if (machineData) { + cpu = machineData.limits.cpu + memory = machineData.limits.memory + } + } else { + if (selectedMachine === 'custom') { + cpu = resourceValue + memory = resourceValue + } else { + cpu = machines[selectedMachine].resources.limits.cpu + memory = machines[selectedMachine].resources.limits.memory + } + } - if (options.length === 0) { - return fetchOptions({ model, getValue, commit }, type) + if (resource === 'memory') { + commit('wizard/model$update', { + path: reqCommitPath, + value: memory, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: memory, + force: true, + }) + return memory + } else { + commit('wizard/model$update', { + path: reqCommitPath, + value: cpu, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: cpu, + force: true, + }) + return cpu + } } - if (type.endsWith('/mode')) { - return ( - options?.map((item) => ({ - description: modeDetails[item]?.description || '', - text: modeDetails[item]?.text || '', - value: item, - })) || [] - ) + + function setMachineToCustom() { + const machine = getValue(model, '/spec/admin/machineProfiles/default') + return machine || 'custom' } - return options -} -function checkIfFeatureOn({ getValue, model }, type) { - let val = getValue(model, `/spec/admin/${type}/toggle`) - if (type === 'backup' || type === 'archiver') { - val = getValue(model, `/spec/admin/${type}/enable/toggle`) + function setMonitoring() { + const agent = getValue(model, '/spec/admin/monitoring/agent') || '' + return !!agent } - const backupVal = getValue(model, '/spec/backup/tool') - - if (type === 'backup') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } else if (type === 'tls') { - return features.includes('tls') && val - } else if (type === 'expose') { - return features.includes('binding') && val - } else if (type === 'monitoring') { - return features.includes('monitoring') && val - } else if (type === 'archiver') { - return features.includes('backup') && backupVal === 'KubeStash' && val + + function setReplicaNumber() { + const modelPathValue = getValue(model, '/spec/mode') + if (modelPathValue === 'Topology') { + return 2 + } else return 1 } -} -function isToggleOn({ getValue, model, discriminator, watchDependency }, type) { - watchDependency('discriminator#/bundleApiLoaded') - watchDependency('model#/spec/admin/deployment/default') - const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') - let deploymentType = getValue(model, `/spec/admin/deployment/default`) - if ( - type === 'tls' || - type === 'backup' || - type === 'expose' || - type === 'monitoring' || - type === 'archiver' - ) { - return checkIfFeatureOn({ getValue, model }, type) - } else if ( - type === 'clusterTier' || - type === 'clusterTier/placement' || - type === 'clusterTier/nodeTopology' - ) { - if (deploymentType === 'Dedicated' && bundleApiLoaded) return true - else return false - } else if (type === 'deployment') { - const deploymentType = getValue(model, '/spec/admin/deployment/default') - if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + function setRequests(resource, type) { + const modelPath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + + const fullpath = `/spec/podResources/machine` + const modelPathValue = getValue(model, fullpath) + + commit('wizard/model$update', { + path: commitPath, + value: val, + force: true, + }) + + if (modelPathValue === 'custom') { + return + } + let commitCpuMemory, ModelPathValue + if (resource && type) { + const fullPath = `/spec/${type}/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/${type}/podResources/resources/requests/${resource}` + } else { + const fullPath = `/spec/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/podResources/resources/requests/${resource}` + } + let cpuMemoryValue + array.forEach((item) => { + if (item.value === ModelPathValue) { + // Parse subText like "CPU: 2, Memory: 2Gi" + const subText = item.subText || '' + if (resource === 'cpu') { + // Extract CPU value + const cpuMatch = subText.match(/CPU:\s*([^,]+)/) + cpuMemoryValue = cpuMatch ? cpuMatch[1].trim() : '' + } else if (resource === 'memory') { + // Extract Memory value + const memoryMatch = subText.match(/Memory:\s*(.+)/) + cpuMemoryValue = memoryMatch ? memoryMatch[1].trim() : '' + } + } + }) + commit('wizard/model$update', { + path: commitCpuMemory, + value: cpuMemoryValue, + force: true, + }) + return cpuMemoryValue + } + + function setRouterNumber() { + const modelPathValue = getValue(model, '/spec/mode') + if (modelPathValue === 'Topology') { + return 3 + } else return 1 + } + + function setStorageClass() { + const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' + let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' + const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] + const suffix = '-retain' + + const simpleClassList = storageClassList.filter((item) => { + return !item.endsWith(suffix) + }) + const retainClassList = storageClassList.filter((item) => { + return item.endsWith(suffix) + }) + if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { + storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] + } else { + storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + } + + const isChangeable = isToggleOn('storageClasses') + if (isChangeable && storageClass) { commit('wizard/model$update', { - path: '/spec/admin/deployment/default', - value: 'Shared', + path: '/spec/admin/storageClasses/default', + value: storageClass, force: true, }) } - return ( - getValue(model, `/spec/admin/${type}/toggle`) && - nodetopologiesDedicated.length && - bundleApiLoaded - ) - } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded -} + } -async function getNodeTopology({ model, getValue, axios, storeGet, watchDependency }) { - watchDependency('model#/spec/admin/deployment/default') - watchDependency('model#/spec/admin/clusterTier/default') - const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' - const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' - let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + function showAdditionalSettings() { + // watchDependency('discriminator#/bundleApiLoaded') + return features.length + } - const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + function showAlerts() { + // watchDependency('discriminator#/monitoring') + const isMonitorEnabled = getValue(discriminator, '/monitoring') + return isMonitorEnabled && isToggleOn('alert') + } - if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared - else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + function showArbiter() { + // watchDependency('model#/spec/arbiter/enabled') + const isArbiterOn = getValue(model, '/spec/arbiter/enabled') || '' + const notStandalone = notEqualToDatabaseMode('Standalone') + return isArbiterOn && notStandalone + } - const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) - return filteredList -} + function showAuthPasswordField() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !modelPathValue && showReferSecret() + } -function filterNodeTopology(list, tier, provider) { - // first filter the list from value that exists from the filtered list got from API - const filteredlist = list + function showAuthSecretField() { + return !showAuthPasswordField() + } - // filter the list based on clusterTier - if (provider === 'EKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('c') - else if (tier === 'MemoryOptimized') return item.startsWith('r') - else return !item.startsWith('c') && !item.startsWith('r') - }) - } else if (provider === 'AKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - else - return ( - !(item.startsWith('f') || item.startsWith('fx')) && - !( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - ) - }) - } else if (provider === 'GKE') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') - return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - else - return ( - !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && - !( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - ) - }) - } else return filteredlist -} + function showHidden() { + // watchDependency('model#/spec/hidden/enabled') + const isHiddenOn = getValue(model, '/spec/hidden/enabled') || '' + const notStandalone = notEqualToDatabaseMode('Standalone') + return isHiddenOn && notStandalone + } -function returnFalse() { - return false -} + function showIssuer() { + // watchDependency('model#/spec/admin/tls/default') + const isTlsEnabled = getValue(model, '/spec/admin/tls/default') + const isIssuerToggleEnabled = isToggleOn('clusterIssuers') + return isTlsEnabled && isIssuerToggleEnabled + } -function isConfigDatabaseOn({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configDatabase') - return getValue(discriminator, '/configDatabase') -} -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} -function showStorageSizeField({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - const validType = [] - return !validType.includes(modelPathValue) -} -function showHidden({ watchDependency, model, getValue }) { - watchDependency('model#/spec/hidden/enabled') - const isHiddenOn = getValue(model, '/spec/hidden/enabled') || '' - const notStandalone = notEqualToDatabaseMode({ model, getValue, watchDependency }, 'Standalone') - return isHiddenOn && notStandalone -} -function notEqualToDatabaseMode({ model, getValue, watchDependency }, mode) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - return modelPathValue && modelPathValue !== mode -} -function showArbiter({ watchDependency, model, getValue }) { - watchDependency('model#/spec/arbiter/enabled') - const isArbiterOn = getValue(model, '/spec/arbiter/enabled') || '' - const notStandalone = notEqualToDatabaseMode({ model, getValue, watchDependency }, 'Standalone') - return isArbiterOn && notStandalone -} -function clearConfiguration({ discriminator, getValue, commit }) { - const configOn = getValue(discriminator, '/configDatabase') + const showMultiselectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') - if (!configOn) { - commit('wizard/model$delete', '/spec/configuration') + if (val === 'capz' && ifDedicated()) return true } -} -function showIssuer({ model, getValue, watchDependency, discriminator }) { - watchDependency('model#/spec/admin/tls/default') - const isTlsEnabled = getValue(model, '/spec/admin/tls/default') - const isIssuerToggleEnabled = isToggleOn( - { getValue, model, discriminator, watchDependency }, - 'clusterIssuers', - ) - return isTlsEnabled && isIssuerToggleEnabled -} -function onAuthChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/authSecret/password', - value: '', - force: true, - }) -} -function setMonitoring({ getValue, model }) { - const agent = getValue(model, '/spec/admin/monitoring/agent') || '' - return !!agent -} - -function setBackup({ model, getValue }) { - const backup = getValue(model, '/spec/backup/tool') - const val = getValue(model, '/spec/admin/backup/enable/default') - return backup === 'KubeStash' && features.includes('backup') && val -} + function showReferSecret() { + const modelPathValue = getValue(discriminator, '/createAuthSecret') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue + } -function isMachineCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue === 'custom' -} + function showReferSecretSwitch() { + const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue && showReferSecret() + } -function isMachineNotCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue !== 'custom' && !!modelPathValue -} -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], - }, - }, - ) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] - } - } catch (e) { - console.log(e) + function showSecretDropdown() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !!modelPathValue && showReferSecret() } - return [] -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + const showSelectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') + if (val !== 'capz' && ifDedicated()) return true + } -function updateAlertValue({ commit, model, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const alert = isMonitorEnabled ? 'warning' : 'none' - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: alert, - force: true, - }) - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} + function showStorageSizeField() { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + const validType = [] + return !validType.includes(modelPathValue) + } -function setLimits({ model, getValue, commit, watchDependency }, resource, type) { - const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' - watchDependency(`model#${path}`) - const selectedMachine = getValue(model, path) || 'custom' - const reqCommitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - const comparePath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - - const resourceValue = getValue(model, comparePath) - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - - let cpu = '', - memory = '' - if (available.length && selectedMachine !== 'custom') { - const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) - if (machineData) { - cpu = machineData.limits.cpu - memory = machineData.limits.memory - } - } else { - if (selectedMachine === 'custom') { - cpu = resourceValue - memory = resourceValue - } else { - cpu = machines[selectedMachine].resources.limits.cpu - memory = machines[selectedMachine].resources.limits.memory - } + function toggleTls(isTlsInit) { + let modelPathValue = getValue(model, '/spec/mode') + commit('wizard/model$update', { + path: '/spec/admin/tls/default', + value: modelPathValue !== 'Standalone', + force: true, + }) + commit('wizard/model$update', { + path: '/spec/admin/tls/toggle', + value: modelPathValue !== 'Standalone', + force: true, + }) + if (isTlsInit) return isTlsInit } - if (resource === 'memory') { + function updateAgentValue(val) { commit('wizard/model$update', { - path: reqCommitPath, - value: memory, + path: '/spec/monitoring/agent', + value: val ? 'prometheus.io/operator' : '', force: true, }) + + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: comparePath, - value: memory, + path: '/form/alert/enabled', + value: val ? 'warning' : 'none', force: true, }) - return memory - } else { + } + + function updateAlertValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const alert = isMonitorEnabled ? 'warning' : 'none' + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: reqCommitPath, - value: cpu, + path: '/form/alert/enabled', + value: alert, force: true, }) + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' commit('wizard/model$update', { - path: comparePath, - value: cpu, + path: '/spec/admin/monitoring/agent', + value: agent, force: true, }) - return cpu } -} -function setRequests({ getValue, model, commit }, resource, type) { - const modelPath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - const val = getValue(model, modelPath) - commitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - commit('wizard/model$update', { - path: commitPath, - value: val, - force: true, - }) -} + const zonesOnChange = () => { + const zones = getValue(model, 'form/capi/zones') || [] + if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') + } -function toggleTls({ commit, model, getValue, watchDependency }) { - let modelPathValue = getValue(model, '/spec/mode') - commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: modelPathValue !== 'Standalone', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/admin/tls/toggle', - value: modelPathValue !== 'Standalone', - force: true, - }) -} + function fetchOptions(type) { + let kind = getValue(model, '/metadata/resource/kind') + + let returnArray = [] + if (type === 'clusterTier/placement') { + returnArray = placement + } else if (type === `databases/${kind}/versions`) { + returnArray = versions + } else if (type === 'storageClasses') { + returnArray = storageClass + } else if (type === 'clusterIssuers') { + returnArray = clusterIssuers + } -function showAdditionalSettings({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return features.length -} + if (returnArray.length === 1) { + const path = `/spec/admin/${type}/default` + commit('wizard/model$update', { + path: path, + value: returnArray[0], + force: true, + }) + } -function getDefault({ getValue, model }, type) { - const val = getValue(model, `/spec/admin/${type}/default`) || '' - return val -} + return returnArray + } -function isConfigAvailable({ getValue, model }) { - const val = getValue(model, '/spec/configuration') - return val !== '' -} + function getAdminOptions(type) { + // watchDependency('discriminator#/bundleApiLoaded') -async function getReferSecrets({ getValue, model, storeGet, axios, discriminator }) { - const referSecret = getValue(discriminator, '/referSecret') - if (!referSecret) { - return [] + const options = getValue(model, `/spec/admin/${type}/available`) || [] + + if (options.length === 0) { + return fetchOptions(type) + } + if (type.endsWith('/mode')) { + return ( + options?.map((item) => ({ + description: modeDetails[item]?.description || '', + text: modeDetails[item]?.text || '', + value: item, + })) || [] + ) + } + return options } - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/metadata/release/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - - const options = [] - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) - } catch (e) { - console.log(e) + async function getNodeTopology() { + // watchDependency('model#/spec/admin/deployment/default') + // watchDependency('model#/spec/admin/clusterTier/default') + const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' + const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' + let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + + const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + + if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared + else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + + const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) + return filteredList } - return options -} -function showAuthPasswordField({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + let backupToolInitialValue = '' + function checkIfFeatureOn(type) { + let val = getValue(model, `/spec/admin/${type}/toggle`) + if (type === 'backup' || type === 'archiver') { + val = getValue(model, `/spec/admin/${type}/enable/toggle`) + } + const backupVal = getValue(model, '/spec/backup/tool') + if (type === 'backup') { + if (backupToolInitialValue === '') { + backupToolInitialValue = + features.includes('backup') && backupVal === 'KubeStash' && val ? 'on' : 'off' + return features.includes('backup') && backupVal === 'KubeStash' && val + } else { + if (backupToolInitialValue === 'on') { + return true + } else { + return false + } + } + } else if (type === 'tls') { + return features.includes('tls') && val + } else if (type === 'expose') { + return features.includes('binding') && val + } else if (type === 'monitoring') { + return features.includes('monitoring') && val + } else if (type === 'archiver') { + return features.includes('backup') && val + } + } + function isToggleOn(type) { + // watchDependency('discriminator#/bundleApiLoaded') + // watchDependency('model#/spec/admin/deployment/default') + const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') + let deploymentType = getValue(model, `/spec/admin/deployment/default`) + if ( + type === 'tls' || + type === 'backup' || + type === 'expose' || + type === 'monitoring' || + type === 'archiver' + ) { + return checkIfFeatureOn(type) + } else if ( + type === 'clusterTier' || + type === 'clusterTier/placement' || + type === 'clusterTier/nodeTopology' + ) { + if (deploymentType === 'Dedicated' && bundleApiLoaded) return true + else return false + } else if (type === 'deployment') { + const deploymentType = getValue(model, '/spec/admin/deployment/default') + if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + commit('wizard/model$update', { + path: '/spec/admin/deployment/default', + value: 'Shared', + force: true, + }) + } + return ( + getValue(model, `/spec/admin/${type}/toggle`) && + nodetopologiesDedicated.length && + bundleApiLoaded + ) + } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded + } -function showSecretDropdown({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + async function getMySqlVersions(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function showReferSecret({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/createAuthSecret') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue -} + const queryParams = { + filter: { + items: { + metadata: { name: null }, + spec: { version: null, deprecated: null }, + }, + }, + } -function getDefaultValue({ getValue, model }, path) { - const val = getValue(model, `/${path}`) || '' - return val -} + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: queryParams, + }, + ) -function showReferSecretSwitch({ model, getValue, watchDependency, discriminator }) { - const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + const resources = (resp && resp.data && resp.data.items) || [] -function onReferSecretChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) -} + // keep only non deprecated versions + const filteredMySqlVersions = resources.filter((item) => item.spec && !item.spec.deprecated) + + filteredMySqlVersions.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + const specVersion = (item.spec && item.spec.version) || '' + item.text = `${name} (${specVersion})` + item.value = name + return true + }) + return filteredMySqlVersions + } -return { - showReferSecretSwitch, - onReferSecretChange, - getDefaultValue, - isRancherManaged, - showSecretDropdown, - showReferSecret, - getReferSecrets, - isConfigAvailable, - initBundle, - returnFalse, - setLimits, - setRequests, - toggleTls, - getNamespaces, - updateAlertValue, - getAdminOptions, - isToggleOn, - showAlerts, - getNodeTopology, - clearArbiterHidden, - returnFalse, - showHidden, - isConfigDatabaseOn, - notEqualToDatabaseMode, - filterNodeTopology, - onAuthChange, - setMonitoring, - isMachineNotCustom, - isMachineCustom, - showIssuer, - showArbiter, - clearConfiguration, - showStorageSizeField, - onBackupSwitch, - isVariantAvailable, - fetchJsons, - showAuthPasswordField, - isEqualToModelPathValue, - showAuthSecretField, - getResources, - getMySqlVersions, - onCreateAuthSecretChange, - getSecrets, - getMachineListForOptions, - setMachineToCustom, - updateAgentValue, - getCreateNameSpaceUrl, - ifCapiProviderIsNotEmpty, - ifDedicated, - dedicatedOnChange, - ifZones, - zonesOnChange, - getZones, - getSKU, - showMultiselectZone, - showSelectZone, - setStorageClass, - setReplicaNumber, - setRouterNumber, - setBackup, - showAdditionalSettings, - getDefault, + return { + clearArbiterHidden, + clearConfiguration, + dedicatedOnChange, + fetchJsons, + filterNodeTopology, + getCreateNameSpaceUrl, + getDefault, + getDefaultValue, + getMachineListForOptions, + getNamespaces, + getReferSecrets, + getResources, + getSecrets, + getSKU, + getZones, + ifCapiProviderIsNotEmpty, + ifDedicated, + ifZones, + initBundle, + isConfigDatabaseOn, + isEqualToModelPathValue, + isMachineCustom, + isMachineNotCustom, + isRancherManaged, + isVariantAvailable, + notEqualToDatabaseMode, + onAuthChange, + onBackupSwitch, + onCreateAuthSecretChange, + onReferSecretChange, + returnFalse, + setBackup, + setLimits, + setMachineToCustom, + setMonitoring, + setReplicaNumber, + setRequests, + setRouterNumber, + setStorageClass, + showAdditionalSettings, + showAlerts, + showArbiter, + showAuthPasswordField, + showAuthSecretField, + showHidden, + showIssuer, + showMultiselectZone, + showReferSecret, + showReferSecretSwitch, + showSecretDropdown, + showSelectZone, + showStorageSizeField, + toggleTls, + updateAgentValue, + updateAlertValue, + zonesOnChange, + fetchOptions, + getAdminOptions, + getNodeTopology, + checkIfFeatureOn, + isToggleOn, + getMySqlVersions, + } } diff --git a/charts/kubedbcom-singlestore-editor/ui/edit-ui.yaml b/charts/kubedbcom-singlestore-editor/ui/edit-ui.yaml index 0ff9c964e7..59b975b0e5 100644 --- a/charts/kubedbcom-singlestore-editor/ui/edit-ui.yaml +++ b/charts/kubedbcom-singlestore-editor/ui/edit-ui.yaml @@ -1,1110 +1,1086 @@ -steps: -- form: - elements: - - disabled: true - label: - text: labels.database.name - onChange: onNameChange - schema: - $ref: schema#/properties/metadata/properties/release/properties/name - type: input - type: single-step-form - id: basic - title: steps.0.label -- form: - discriminator: - repoInitialSelectionStatus: - type: string - scheduleBackup: - default: "yes" - type: string +type: multi-step-form +step: + - type: single-step-form + id: backupconfiguration + # label: Backup + schema: schema/ elements: - - computed: initScheduleBackupForEdit - if: showScheduleBackup - label: - text: labels.backup.title - onChange: onScheduleBackupChange + - type: radio + label: Schedule a Backup? + schema: temp/properties/scheduleBackup + isHorizontal: true options: - - text: options.yesOrNo.yes.text - value: "yes" - - text: options.yesOrNo.no.text - value: "no" - schema: - $ref: discriminator#/properties/scheduleBackup - type: radio - - discriminator: - backupType: - type: string - isBackupDataLoaded: - default: false - type: boolean + - text: 'Yes' + value: 'yes' + - text: 'No' + value: 'no' + if: + type: function + name: showScheduleBackup + init: + type: func + value: initScheduleBackupForEdit + watcher: + func: onScheduleBackupChange + paths: + - temp/properties/scheduleBackup + - type: block-layout + label: Backup Form + showLabels: false + loader: initBackupData + if: + type: function + name: showBackupForm elements: - - computed: initBackupData - if: returnFalse - type: input - - computed: setBackupType - fetch: getTypes - hasDescription: true - if: isBackupDataLoadedTrue - label: - text: Select Backup Type - onChange: onBackupTypeChange - schema: - $ref: discriminator#/backupType - type: radio - - discriminator: - backupConfigContext: - type: string - config: - type: string - paused: - default: false - type: boolean - schedule: - type: string + - type: radio + label: Select Backup Type + schema: temp/properties/backupType + isHorizontal: true + options: + - text: BackupConfig + value: BackupConfig + description: 'Create, Delete or Modify BackupConfig' + - text: BackupBlueprint + value: BackupBlueprint + description: Enable/Disable BackupBlueprint + if: + type: function + name: isBackupDataLoadedTrue + init: + type: func + value: setBackupType + loader: getTypes + watcher: + func: onBackupTypeChange + paths: + - temp/properties/backupType + - type: block-layout + label: Config + if: + type: function + name: isBackupType|BackupConfig + elements: + - type: select + label: Select Context + schema: temp/properties/backupConfigContext + validation: + type: required + loader: getContext + watcher: + func: onContextChange + paths: + - temp/properties/backupConfigContext + - type: select + label: Select BackupConfig + schema: temp/properties/config + validation: + type: required + if: + type: function + name: showConfigList + loader: getConfigList + watcher: + func: onConfigChange + paths: + - temp/properties/config + - type: input + label: Schedule + schema: temp/properties/schedule + validation: + type: required + if: + type: function + name: showSchedule + loader: + name: getDefaultSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions + watchPaths: + - temp/properties/config + watcher: + func: onInputChangeSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions|schedule + paths: + - temp/properties/schedule + - type: switch + label: Paused + fullwidth: true + schema: schema/properties/resources/properties/coreKubestashComBackupConfiguration/properties/spec/properties/paused + if: + type: function + name: showPause + watcher: + func: setPausedValue + paths: + - temp/properties/config + init: + type: func + value: setPausedValue + - type: block-layout + label: Blueprint + if: + type: function + name: isBackupType|BackupBlueprint + elements: + - type: switch + label: Enable Backup Blueprint + fullwidth: true + schema: temp/properties/blueprintEnabled + init: + type: func + value: setBlueprintSwitch + watcher: + func: onBlueprintChange + paths: + - temp/properties/blueprintEnabled + - type: block-layout + label: Archiver + if: + type: function + name: isBackupType|Archiver + elements: + - type: switch + label: Enable Archiver + fullwidth: true + schema: temp/properties/archiverEnabled + init: + type: func + value: setArchiverSwitch + watcher: + func: onArchiverChange + paths: + - temp/properties/archiverEnabled + + - type: single-step-form + id: compute-autoscaler + loader: getDbDetails + elements: + - type: block-layout + if: + type: function + name: isConsole + elements: + - type: input + label: Name + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/metadata/properties/name + - type: select + label: Select Namespace + loader: getNamespaces + if: + type: function + name: isRancherManaged + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/metadata/properties/namespace + - type: select + label: Select Db + loader: getDbs + validation: + type: required + refresh: true + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/databaseRef/properties/name + watcher: + func: initMetadata + paths: + - schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/databaseRef/properties/name + + - type: radio + if: + type: function + name: isConsole + label: Select Type + validation: + type: required + schema: temp/properties/autoscalingType + watcher: + func: initMetadata + paths: + - temp/properties/autoscalingType + options: + - text: Compute + value: compute + description: Scale your CPU Memory based on resource usage + - text: Storage + value: storage + description: Expand your database size based on volume usage + + - type: block-layout + label: Topology + if: + type: function + name: dbTypeEqualsTo|topology + showLabels: false + loader: fetchTopologyMachines + # schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute + elements: + # Aggregator section + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComSinglestoreAutoscaler/spec/compute/aggregator/trigger + schema: temp/properties/compute/properties/aggregator/properties/trigger + watcher: + func: onTriggerChange|compute/aggregator + paths: + - temp/properties/compute/properties/aggregator/properties/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/aggregator/properties/podLifeTimeThreshold + customClass: width-300 + - type: block-layout + label: Aggregator + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/aggregator + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/aggregator/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-aggregator-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|aggregator|min + loader: + name: getMachines|aggregator|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-aggregator-max + watcher: + func: onMachineChange|aggregator + paths: + - temp/properties/allowedMachine-aggregator-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/aggregator/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/aggregator/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-aggregator-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|aggregator|max + loader: + name: getMachines|aggregator|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-aggregator-min + watcher: + func: onMachineChange|aggregator + paths: + - temp/properties/allowedMachine-aggregator-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/aggregator/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/aggregator/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|aggregator + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/aggregator/properties/controlledResources + + # Leaf section + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComSinglestoreAutoscaler/spec/compute/leaf/trigger + schema: temp/properties/compute/properties/leaf/properties/trigger + watcher: + func: onTriggerChange|compute/leaf + paths: + - temp/properties/compute/properties/leaf/properties/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/leaf/properties/podLifeTimeThreshold + customClass: width-300 + - type: block-layout + label: Leaf + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/leaf + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/leaf/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-leaf-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|leaf|min + loader: + name: getMachines|leaf|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-leaf-max + watcher: + func: onMachineChange|leaf + paths: + - temp/properties/allowedMachine-leaf-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/leaf/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/leaf/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-leaf-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|leaf|max + loader: + name: getMachines|leaf|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-leaf-min + watcher: + func: onMachineChange|leaf + paths: + - temp/properties/allowedMachine-leaf-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/leaf/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/leaf/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|leaf + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/leaf/properties/controlledResources + + # combined mode - node only + - type: block-layout + label: Combined + if: + type: function + name: dbTypeEqualsTo|standalone + showLabels: false + loader: fetchTopologyMachines + # schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute elements: - - fetch: getContext - label: - text: Select Context - onChange: onContextChange - required: true - schema: - $ref: discriminator#/backupConfigContext - type: select - - fetch: getConfigList - if: showConfigList - label: - text: Select BackupConfig - onChange: onConfigChange - required: true - schema: - $ref: discriminator#/config - type: select - - computed: getDefaultSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions - if: showSchedule - label: - text: Schedule - onChange: onInputChangeSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions|schedule - required: true - schema: - $ref: discriminator#/schedule - type: input - - if: showPause - label: - text: Paused - schema: - $ref: schema#/properties/resources/properties/coreKubestashComBackupConfiguration/properties/spec/properties/paused - type: switch - if: isBackupType|BackupConfig - type: single-step-form - - discriminator: - blueprintEnabled: - default: false - type: boolean + # Node section + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComSinglestoreAutoscaler/spec/compute/node/trigger + schema: temp/properties/compute/properties/node/properties/trigger + watcher: + func: onTriggerChange|compute/node + paths: + - temp/properties/compute/properties/node/properties/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/node/properties/podLifeTimeThreshold + customClass: width-300 + - type: block-layout + label: Node + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/node + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/node/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-node-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|node|min + loader: + name: getMachines|node|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-node-max + watcher: + func: onMachineChange|node + paths: + - temp/properties/allowedMachine-node-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/node/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/node/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-node-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|node|max + loader: + name: getMachines|node|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-node-min + watcher: + func: onMachineChange|node + paths: + - temp/properties/allowedMachine-node-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/node/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/node/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|node + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/node/properties/controlledResources + + - type: block-layout + label: Node Topology + if: + type: function + name: hasNoAnnotations + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/nodeTopology elements: - - computed: setBlueprintSwitch - label: - text: Enable Backup Blueprint - onChange: onBlueprintChange - schema: - $ref: discriminator#/blueprintEnabled - type: switch - if: isBackupType|BackupBlueprint - type: single-step-form - - discriminator: - archiverEnabled: - default: false - type: boolean + - type: select + label: Select Node Topology + loader: fetchNodeTopology + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name + - type: threshold-input + label: ScaleUp Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage + - type: threshold-input + label: ScaleDown Diff Percentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage + + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + # schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/opsRequestOptions elements: - - computed: setArchiverSwitch - label: - text: Enable Archiver - onChange: onArchiverChange - schema: - $ref: discriminator#/archiverEnabled - type: switch - if: isBackupType|Archiver - 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: - dbDetails: - default: false - type: boolean + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: storage-autoscaler + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: Select Db - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: Select Type - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - discriminator: - topologyMachines: - default: [] - type: array + - type: block-layout + showLabels: false elements: - - fetch: fetchTopologyMachines - if: returnFalse - schema: - $ref: discriminator#/topologyMachines - type: input - - elements: - - computed: setTrigger|autoscalingKubedbComSinglestoreAutoscaler/spec/compute/aggregator/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/aggregator/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/aggregator/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/aggregator/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-aggregator-max: - type: string - allowedMachine-aggregator-min: - type: string + - type: block-layout + showLabels: false elements: - - computed: setAllowedMachine|aggregator|min - disableUnselect: true - fetch: getMachines|aggregator|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|aggregator - schema: - $ref: discriminator#/properties/allowedMachine-aggregator-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/aggregator/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/aggregator/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/aggregator/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|aggregator|max - disableUnselect: true - fetch: getMachines|aggregator|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|aggregator - schema: - $ref: discriminator#/properties/allowedMachine-aggregator-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/aggregator/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/aggregator/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/aggregator/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|aggregator - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/aggregator/properties/controlledResources - type: multiselect - if: dbTypeEqualsTo|topology - label: - text: Aggregator - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/aggregator - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComSinglestoreAutoscaler/spec/compute/leaf/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/leaf/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/leaf/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/leaf/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-leaf-max: - type: string - allowedMachine-leaf-min: - type: string + # aggregator storage + - type: switch + label: Trigger + fullwidth: true + if: + type: function + name: dbTypeEqualsTo|topology + init: + type: func + value: setTrigger|autoscalingKubedbComSinglestoreAutoscaler/spec/storage/aggregator/trigger + schema: temp/properties/storage/properties/aggregator/properties/trigger + watcher: + func: onTriggerChange|storage/aggregator + paths: + - temp/properties/storage/properties/aggregator/properties/trigger + - type: label-element + 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. + if: + type: function + name: dbTypeEqualsTo|topology + - type: select + label: Mode + description: Select how the storage expansion should be handled. + if: + type: function + name: dbTypeEqualsTo|topology + options: + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/aggregator/properties/expansionMode + - type: block-layout + label: Aggregator + if: + type: function + name: dbTypeEqualsTo|topology + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/aggregator + elements: + - type: threshold-input + label: UsageThreshold (%) + subtitle: Set the threshold percentage of storage usage to trigger scaling. + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/aggregator/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/aggregator/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComSinglestore/spec/topology/aggregator/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComSinglestoreAutoscaler/spec/storage/aggregator/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/aggregator/properties/scalingRules + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/aggregator/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComSinglestoreAutoscaler/spec/storage/aggregator/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/aggregator/properties/upperBound + + - type: block-layout + showLabels: false elements: - - computed: setAllowedMachine|leaf|min - disableUnselect: true - fetch: getMachines|leaf|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|leaf - schema: - $ref: discriminator#/properties/allowedMachine-leaf-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/leaf/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/leaf/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/leaf/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|leaf|max - disableUnselect: true - fetch: getMachines|leaf|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|leaf - schema: - $ref: discriminator#/properties/allowedMachine-leaf-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/leaf/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/leaf/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/leaf/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|leaf - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/leaf/properties/controlledResources - type: multiselect - if: dbTypeEqualsTo|topology - label: - text: Leaf - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/leaf - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComSinglestoreAutoscaler/spec/compute/node/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/node/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/node/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/node/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-node-max: - type: string - allowedMachine-node-min: - type: string + # leaf storage + - type: switch + label: Trigger + fullwidth: true + if: + type: function + name: dbTypeEqualsTo|topology + init: + type: func + value: setTrigger|autoscalingKubedbComSinglestoreAutoscaler/spec/storage/leaf/trigger + schema: temp/properties/storage/properties/leaf/properties/trigger + watcher: + func: onTriggerChange|storage/leaf + paths: + - temp/properties/storage/properties/leaf/properties/trigger + - type: label-element + 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. + if: + type: function + name: dbTypeEqualsTo|topology + - type: select + label: Mode + description: Select how the storage expansion should be handled. + if: + type: function + name: dbTypeEqualsTo|topology + options: + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/leaf/properties/expansionMode + - type: block-layout + label: Leaf + if: + type: function + name: dbTypeEqualsTo|topology + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/leaf + elements: + - type: threshold-input + label: UsageThreshold (%) + subtitle: Set the threshold percentage of storage usage to trigger scaling. + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/leaf/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/leaf/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComSinglestore/spec/topology/leaf/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComSinglestoreAutoscaler/spec/storage/leaf/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/leaf/properties/scalingRules + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/leaf/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComSinglestoreAutoscaler/spec/storage/leaf/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/leaf/properties/upperBound + + - type: block-layout + showLabels: false elements: - - computed: setAllowedMachine|node|min - disableUnselect: true - fetch: getMachines|node|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|node - schema: - $ref: discriminator#/properties/allowedMachine-node-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/node/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/node/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/node/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|node|max - disableUnselect: true - fetch: getMachines|node|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|node - schema: - $ref: discriminator#/properties/allowedMachine-node-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/node/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/node/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/node/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|node - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/node/properties/controlledResources - type: multiselect - if: dbTypeEqualsTo|standalone - label: - text: node - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/node - show_label: true - type: single-step-form - - elements: - - fetch: fetchNodeTopology - label: - text: SelectNodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name - type: select - - if: isNodeTopologySelected - label: - text: ScaleUp Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage - type: input - - if: isNodeTopologySelected - label: - text: ScaleDown Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage - type: input - if: hasNoAnnotations - label: - text: NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/compute/properties/nodeTopology - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: compute-autoscaler - title: steps.9.label -- form: - discriminator: - enableMonitoring: - default: true - type: boolean - elements: - - label: - text: labels.to_update_exporter_resources - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - function: getOpsRequestUrl|VerticalScaling - - computed: isValueExistInModel|/resources/kubedbComSinglestore/spec/monitor - 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/kubedbComSinglestore/properties/spec/properties/monitor/properties/agent - type: radio - - elements: - - label: - text: labels.scrapping_interval - schema: - $ref: schema#/properties/resources/properties/kubedbComSinglestore/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval - type: input - if: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComSinglestore/spec/monitor/agent - label: - text: labels.service_monitor_configuration - show_label: true - type: single-step-form - - elements: - - elements: - - addFormLabel: labels.endpoint - element: + # node storage (standalone) + - type: switch + label: Trigger + fullwidth: true + if: + type: function + name: dbTypeEqualsTo|standalone + init: + type: func + value: setTrigger|autoscalingKubedbComSinglestoreAutoscaler/spec/storage/node/trigger + schema: temp/properties/storage/properties/node/properties/trigger + watcher: + func: onTriggerChange|storage/node + paths: + - temp/properties/storage/properties/node/properties/trigger + - type: label-element + 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. + if: + type: function + name: dbTypeEqualsTo|standalone + - type: select + label: Mode + description: Select how the storage expansion should be handled. + if: + type: function + name: dbTypeEqualsTo|standalone + options: + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/node/properties/expansionMode + - type: block-layout + label: Node + if: + type: function + name: dbTypeEqualsTo|standalone + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/node 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/kubedbComSinglestore/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/kubedbComSinglestore/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: - - if: returnFalse - label: - text: labels.resources - schema: - $ref: schema#/properties/resources/properties/kubedbComSinglestore/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/kubedbComSinglestore/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/kubedbComSinglestore/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup - type: input - - label: - text: labels.port - schema: - $ref: schema#/properties/resources/properties/kubedbComSinglestore/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/kubedbComSinglestore/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args/items - type: input - label: - text: labels.args - schema: - $ref: schema#/properties/resources/properties/kubedbComSinglestore/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args - type: list-input-form - - alias: reusable_env - chart: - name: uibytebuildersdev-component-env - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComSinglestore/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: - discriminator: - dbDetails: - default: false - type: boolean + - type: threshold-input + label: UsageThreshold (%) + subtitle: Set the threshold percentage of storage usage to trigger scaling. + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/node/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/node/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComSinglestore/spec/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComSinglestoreAutoscaler/spec/storage/node/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/node/properties/scalingRules + - type: input + label: UpperBound + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/node/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComSinglestoreAutoscaler/spec/storage/node/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/node/properties/upperBound + + - type: block-layout + label: OpsRequest Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: monitoring + loader: initMonitoring elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - computed: getDbDetails - if: returnFalse - type: input - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: Select Db - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: Select Type - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComSinglestoreAutoscaler/spec/storage/aggregator/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/aggregator/properties/trigger - type: select - - label: - text: Expansion Mode - options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/aggregator/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/aggregator/properties/usageThreshold - type: input - - addFormLabel: ScalingRules - element: - elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/aggregator/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/aggregator/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComSinglestoreAutoscaler/spec/storage/aggregator/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/aggregator/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComSinglestoreAutoscaler/spec/storage/aggregator/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/aggregator/properties/upperBound - type: input - if: dbTypeEqualsTo|topology - label: - text: Standalone - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/aggregator - show_label: true - type: single-step-form - type: single-step-form - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComSinglestoreAutoscaler/spec/storage/leaf/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/leaf/properties/trigger - type: select - - label: - text: Expansion Mode + - type: label-element + label: To update Exporter Resource section click on Create OpsRequest + - type: anchor + label: Create OpsRequest + schema: temp/properties/opsRequestUrl + init: + type: func + value: getOpsRequestUrl|scale-vertically + - type: switch + label: Enable Monitoring + fullwidth: true + schema: temp/properties/enableMonitoring + init: + type: func + value: isValueExistInModel|/resources/kubedbComSinglestore/spec/monitor + watcher: + func: onEnableMonitoringChange + paths: + - temp/properties/enableMonitoring + - type: block-layout + if: + type: function + name: showMonitoringSection + elements: + - type: radio + label: Select a Monitoring Method + schema: schema/properties/resources/properties/kubedbComSinglestore/properties/spec/properties/monitor/properties/agent + isHorizontal: true options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/leaf/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/leaf/properties/usageThreshold - type: input - - addFormLabel: ScalingRules - element: + - text: Prometheus Operator + value: prometheus.io/operator + description: Inject metric exporter sidecar and creates a ServiceMonitor + - text: Custom ServiceMonitor + value: prometheus.io + description: Injects the metric exporter sidecar and let you customize ServiceMonitor + - text: Custom Scrapper + value: prometheus.io/builtin + description: Inject metric exporter sidecar and add Prometheus annotations to the stats Service + init: + type: static + value: prometheus.io/operator + watcher: + func: onAgentChange + paths: + - schema/properties/resources/properties/kubedbComSinglestore/properties/spec/properties/monitor/properties/agent + - type: block-layout + label: ServiceMonitor Configuration + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComSinglestore/spec/monitor/agent + elements: + - label: Scrapping Interval + schema: schema/properties/resources/properties/kubedbComSinglestore/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval + type: input + - type: block-layout + label: Service Monitor + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComSinglestore/spec/monitor/agent + elements: + - type: array-object-form + label: Endpoints + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/endpoints elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/leaf/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/leaf/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComSinglestoreAutoscaler/spec/storage/leaf/scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/leaf/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComSinglestoreAutoscaler/spec/storage/leaf/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/leaf/properties/upperBound - type: input - if: dbTypeEqualsTo|topology - label: - text: Standalone - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/leaf - show_label: true - type: single-step-form - type: single-step-form - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComSinglestoreAutoscaler/spec/storage/node/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/node/properties/trigger - type: select - - label: - text: Expansion Mode - options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/node/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/node/properties/usageThreshold - type: input - - addFormLabel: ScalingRules - element: + - type: switch + label: Honor labels + fullwidth: true + schema: honorLabels + - type: input + label: Interval + schema: interval + validation: + type: required + - type: input + label: Path + schema: path + validation: + type: required + - type: input + label: Port + schema: port + validation: + type: required + - type: select + multiple: true + label: Match Namespaces + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/namespaceSelector/properties/matchNames + loader: getResources|core|v1|namespaces + if: + type: function + name: returnFalse + - type: block-layout + showLabels: false + # schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector + if: + type: function + name: returnFalse elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/node/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/node/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComSinglestoreAutoscaler/spec/storage/node/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/node/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComSinglestoreAutoscaler/spec/storage/node/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/node/properties/upperBound - type: input - if: dbTypeEqualsTo|standalone - label: - text: Standalone - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/storage/properties/node - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSinglestoreAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: storage-autoscaler - title: steps.10.label -- form: - discriminator: - binding: - default: false - type: boolean + - type: object-item + label: Labels + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector/properties/matchLabels + - type: object-item + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/metadata/properties/labels + label : Labels + buttonClass: is-light is-outlined + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComSinglestore/spec/monitor/agent + # individualItemDisabilityCheck: disableLableChecker + - type: label-element + label: Exporter Configuration + schema: '' + - type: switch + label: Customize Exporter Sidecar + fullwidth: true + schema: temp/properties/customizeExporter + init: + type: static + value: true + watcher: + func: onCustomizeExporterChange + paths: + - temp/properties/customizeExporter + - type: block-layout + label: Customer Exporter Section + showLabels: false + if: + type: function + name: showCustomizeExporterSection + elements: + - type: machine-compare + label: Resources + schema: schema/properties/resources/properties/kubedbComSinglestore/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/resources + if: + type: function + name: returnFalse + - type: label-element + label: Security Context + schema: '' + - type: input + schema: schema/properties/resources/properties/kubedbComSinglestore/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsUser + label: Run as User + - type: input + schema: schema/properties/resources/properties/kubedbComSinglestore/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup + label: Run as Group + - type: input + schema: schema/properties/resources/properties/kubedbComSinglestore/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/port + label: Port + - type: array-item-form + label: Args + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/kubedbComSinglestore/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args + init: + type: static + value: ['--compatible-mode'] + element: + type: input + label: Args + # isSubsection: true + - type: block-layout + label: Metadata + showLabels: false + elements: + - type: array-object-form + init: + type: func + value: initEnvArray + label: Environment Variables + buttonClass: is-light is-outlined + watcher: + func: onEnvArrayChange + paths: + - temp/properties/env + schema: temp/properties/env + elements: + - type: input + label: Name + schema: name + validation: + type: required + - type: radio + label: Value From + schema: temp/properties/valueFromType + validation: + type: required + init: + type: func + value: setValueFrom + options: + - text: Input + value: input + - text: Secret + value: secret + - text: ConfigMap + value: configMap + watcher: + func: onValueFromChange + paths: + - temp/properties/valueFromType + - type: input + label: Value + schema: value + validation: + type: required + if: + name: isEqualToTemp|input + type: function + - type: select + if: + type: function + name: isEqualToTemp|configMap + label: ConfigMap Name + schema: valueFrom/properties/configMapKeyRef/properties/name + loader: + name: resourceNames|core|v1|configmaps + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: ConfigMap Key + schema: valueFrom/properties/configMapKeyRef/properties/key + if: + type: function + name: isEqualToTemp|configMap + loader: + name: getConfigMapKeys + watchPaths: + - schema/resources/kubedbComSinglestore/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/configMapKeyRef/name + - schema/metadata/release/namespace + - type: select + label: Secret Name + schema: valueFrom/properties/secretKeyRef/properties/name + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecrets + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: Secret Key + schema: valueFrom/properties/secretKeyRef/properties/key + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecretKeys + watchPaths: + - schema/resources/kubedbComSinglestore/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/secretKeyRef/name + - schema/metadata/release/namespace + + - type: single-step-form + id: binding elements: - - computed: isBindingAlreadyOn - label: - text: Expose Database - onChange: addOrRemoveBinding - schema: - $ref: discriminator#/properties/binding - type: switch - type: single-step-form - id: binding - title: Gateway Binding -type: multi-step-form + - type: switch + label: Expose Database + schema: temp/properties/binding + fullwidth: true + init: + type: func + value: isBindingAlreadyOn + watcher: + func: addOrRemoveBinding + paths: + - temp/properties/binding \ No newline at end of file diff --git a/charts/kubedbcom-singlestore-editor/ui/functions.js b/charts/kubedbcom-singlestore-editor/ui/functions.js index e979c53f20..0cf3b346e7 100644 --- a/charts/kubedbcom-singlestore-editor/ui/functions.js +++ b/charts/kubedbcom-singlestore-editor/ui/functions.js @@ -1,3279 +1,1699 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + // ************************* common functions ******************************************** // eslint-disable-next-line no-empty-pattern -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}`, +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-aggregator-min', '') + setDiscriminatorValue('/allowedMachine-aggregator-max', '') + setDiscriminatorValue('/allowedMachine-leaf-min', '') + setDiscriminatorValue('/allowedMachine-leaf-max', '') + setDiscriminatorValue('/allowedMachine-node-min', '') + setDiscriminatorValue('/allowedMachine-node-max', '') + + function initScheduleBackupForEdit() { + const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( + getValue, + model, ) - // declare evaluate the functionString to get the functions Object - const evalFunc = new Function(functionString.data || '') - functions = evalFunc() - } catch (e) { - console.log(e) + + initRepositoryChoiseForEdit() + + if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' + else return 'no' } - return { - ui: ui.data || {}, - language: language.data || {}, - functions, + function initScheduleBackup() { + const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( + getValue, + model, + ) + + if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' + else return 'no' } -} -function disableLableChecker({ itemCtx }) { - const { key } = itemCtx - if (key.startsWith('app.kubernetes.io') || key.includes('helm')) return true - else return false -} + function onScheduleBackupChange() { + const scheduleBackup = getValue(discriminator, '/scheduleBackup') -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} + if (scheduleBackup === 'no') { + // delete stashAppscodeComBackupConfiguration + commit('wizard/model$delete', '/resources/stashAppscodeComBackupConfiguration') + commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') + // delete annotation from kubedbComSinglestore annotation + deleteKubeDbComSinglestoreDbAnnotation(getValue, model, commit) + } else { + const { isBluePrint } = getBackupConfigsAndAnnotations(getValue, model) -async function getResources({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + // create stashAppscodeComBackupConfiguration and initialize it if not exists - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + const dbName = getValue(model, '/metadata/release/name') - const resources = (resp && resp.data && resp.data.items) || [] + 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, + }) + } + } + } - 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 valueExists(value, getValue, path) { + const val = getValue(value, path) + if (val) return true + else return false } -} -function isEqualToDiscriminatorPath( - { discriminator, getValue, watchDependency }, - value, - discriminatorPath, -) { - watchDependency('discriminator#' + discriminatorPath) - const discriminatorValue = getValue(discriminator, discriminatorPath) - return discriminatorValue === value -} + function getBackupConfigsAndAnnotations(getValue, model) { + const stashAppscodeComBackupConfiguration = getValue( + model, + '/resources/stashAppscodeComBackupConfiguration', + ) -function setValueFromModel({ getValue, model }, path) { - return getValue(model, path) -} + const coreKubestashComBackupConfiguration = getValue( + model, + '/resources/coreKubestashComBackupConfiguration', + ) + const kubeStashTarget = coreKubestashComBackupConfiguration?.spec?.target -function isNotShardModeSelected({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComSinglestore/spec') - const hasShardTopology = getValue(model, '/resources/kubedbComSinglestore/spec/shardTopology') - return !hasShardTopology -} + const mongoDB = getValue(model, '/resources/kubedbComSinglestore') + const mongoDbKind = mongoDB?.apiVersion?.split('/')?.at(0) -function isShardModeSelected({ model, getValue, watchDependency, commit }) { - const resp = !isNotShardModeSelected({ model, getValue, watchDependency }) - if (resp) { - commit('wizard/model$delete', '/resources/kubedbComSinglestore/spec/configSecret') - commit('wizard/model$delete', '/resources/secret_config') - } - return resp -} + let isKubeStash = false + if ( + mongoDB?.kind === kubeStashTarget.kind && + mongoDB?.metadata?.name === kubeStashTarget?.name && + mongoDB?.metadata?.namespace === kubeStashTarget?.namespace && + mongoDbKind === kubeStashTarget?.apiGroup + ) { + isKubeStash = true + } -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + const kubedbComSinglestoreAnnotations = + getValue(model, '/resources/kubedbComSinglestore/metadata/annotations') || {} - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + const isBluePrint = Object.keys(kubedbComSinglestoreAnnotations).some( + (k) => + k === 'stash.appscode.com/backup-blueprint' || + k === 'stash.appscode.com/schedule' || + k.startsWith('params.stash.appscode.com/'), + ) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }) + return { + stashAppscodeComBackupConfiguration, + isBluePrint, + isKubeStash, + } + } - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + function deleteKubeDbComSinglestoreDbAnnotation(getValue, model, commit) { + const annotations = + getValue(model, '/resources/kubedbComSinglestore/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/kubedbComSinglestore/metadata/annotations', + value: filteredAnnotations, + }) } - return ans -} + // backup form + function showBackupForm() { + const scheduleBackup = getValue(discriminator, '/scheduleBackup') + // watchDependency('discriminator#/scheduleBackup') + if (scheduleBackup === 'yes') return true + else return false + } -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 = {} + let instance = {} + + 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/kubedbComSinglestore') + initialDbMetadata = objectCopy(dbResource.metadata) + initialArchiver = dbResource.spec?.archiver ? objectCopy(dbResource.spec?.archiver) : undefined - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` + // 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 ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }) + let url = `/clusters/${user}/${cluster}/helm/packageview/values?name=${chartName}&sourceApiGroup=${sourceApiGroup}&sourceKind=${sourceKind}&sourceNamespace=${sourceNamespace}&sourceName=${sourceName}&version=${chartVersion}&format=json` - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) - } + if (spoke) + url = `/clusters/${user}/${spoke}/helm/packageview/values?name=${chartName}&sourceApiGroup=${sourceApiGroup}&sourceKind=${sourceKind}&sourceNamespace=${sourceNamespace}&sourceName=${sourceName}&version=${chartVersion}&format=json` - return ans -} + const resp = await axios.get(url) -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - 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) - }) - } + valuesFromWizard = objectCopy(resp.data?.resources?.coreKubestashComBackupConfiguration) || {} + } catch (e) { + console.log(e) + } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + // 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) + } } - }) -} -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) - - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) - } + // 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, + ) - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + // 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, + ) -function returnTrue() { - return true -} + // set backup switch here + isBackupOn = !!config -function returnStringYes() { - return 'yes' -} + // set initial data from stash-presets + const stashPreset = storeGet('/backup/stashPresets') + if (stashPreset) { + const { retentionPolicy, encryptionSecret, schedule, storageRef } = stashPreset -// ************************* Basic Info ********************************************** -async function getMongoDbVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + const tempBackends = valuesFromWizard.spec?.backends + tempBackends[0]['storageRef'] = storageRef + tempBackends[0]['retentionPolicy'] = retentionPolicy + valuesFromWizard.spec['backends'] = tempBackends - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, - }, - }, - } + 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}` - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) + tempSessions[0]['repositories'] = tempRepositories + tempSessions[0]['scheduler']['schedule'] = schedule + valuesFromWizard.spec['sessions'] = tempSessions + } - const resources = (resp && resp.data && resp.data.items) || [] + 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, + } - // keep only non deprecated versions - const filteredMongoDbVersions = resources.filter((item) => item.spec && !item.spec.deprecated) + setDiscriminatorValue('isBackupDataLoaded', true) + } - filteredMongoDbVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredMongoDbVersions - } catch (e) { - console.log(e) - return [] + function isBackupDataLoadedTrue() { + // watchDependency('discriminator#/isBackupDataLoaded') + return !!getValue(discriminator, '/isBackupDataLoaded') } -} -// ************************* Auth Secret Field ****************************************** -function showAuthPasswordField({ model, getValue, watchDependency }) { - watchDependency('model#/resources') - const modelPathValue = getValue(model, '/resources') - return !!( - modelPathValue && - modelPathValue.secret && - modelPathValue.secret.metadata && - modelPathValue.secret.metadata.name && - !showAuthSecretField({ model, getValue, watchDependency }) - ) -} + function setBackupType() { + return 'BackupConfig' + } -function showAuthSecretField({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComSinglestore/spec') - const modelPathValue = getValue(model, '/resources/kubedbComSinglestore/spec') - return !!(modelPathValue && modelPathValue.authSecret && modelPathValue.authSecret.name) -} + 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 showNewSecretCreateField({ model, getValue, watchDependency, commit }) { - const resp = - !showAuthSecretField({ model, getValue, watchDependency }) && - !showAuthPasswordField({ model, getValue, watchDependency }) - const secret = getValue(model, '/resources/secret_auth') - if (resp && !secret) { + function onBackupTypeChange() { + const type = getValue(discriminator, '/backupType') commit('wizard/model$update', { - path: '/resources/secret_auth', - value: { - data: { - password: '', - }, - }, + 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/kubedbComSinglestore', + value: objectCopy(dbResource), force: true, }) } - return resp -} -// ********************* Database Mode *********************** -function isNotStandaloneMode({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - return mode !== 'Standalone' -} - -function showCommonStorageClassAndSizeField({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - const validType = ['Standalone', 'Replicaset'] - return validType.includes(mode) -} -function setDatabaseMode({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/resources/kubedbComSinglestore/spec') + function isBackupType(type) { + // watchDependency('discriminator#/backupType') + const selectedType = getValue(discriminator, '/backupType') - watchDependency('model#/resources/kubedbComSinglestore/spec') - if (modelPathValue.shardTopology) { - return 'Sharded' - } else if (modelPathValue.replicaSet) { - return 'Replicaset' - } else { - return 'Standalone' + return selectedType === type } -} - -let storageClassList = [] -async function getStorageClassNames( - { axios, storeGet, commit, model, getValue, watchDependency, discriminator }, - mode, -) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const databaseModeShard = getValue(discriminator, '/activeDatabaseMode') === 'Sharded' - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/storage.k8s.io/v1/storageclasses`, - { - params: { - filter: { items: { metadata: { name: null, annotations: 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 - }) - storageClassList = resources - const path = - mode === 'shard' - ? '/resources/kubedbComSinglestore/spec/shardTopology/shard/storage/storageClassName' - : '/resources/kubedbComSinglestore/spec/storage/storageClassName' - const initialStorageClass = getValue(model, path) - if (!initialStorageClass) setStorageClass({ getValue, commit, model, discriminator }) - return resources -} -function setStorageClass({ getValue, commit, model, discriminator }) { - const deletionPolicy = getValue(model, 'resources/kubedbComSinglestore/spec/deletionPolicy') || '' - const suffix = '-retain' - let storageClass = '' + function setBlueprintSwitch() { + const annotations = initialDbMetadata?.annotations - const simpleClassList = storageClassList.filter((item) => { - return !item.metadata?.name?.endsWith(suffix) - }) + return !!( + annotations['blueprint.kubestash.com/name'] && + annotations['blueprint.kubestash.com/namespace'] + ) + } - const retainClassList = storageClassList.filter((item) => { - return item.metadata?.name?.endsWith(suffix) - }) + function onBlueprintChange() { + const blueprintSwitch = getValue(discriminator, '/blueprintEnabled') + if (blueprintSwitch) addLabelAnnotation('annotations') + else deleteLabelAnnotation('annotations') + } - const defaultSimpleList = simpleClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] - ) - }) + function setArchiverSwitch() { + const archiver = dbResource?.spec?.archiver + return !!archiver + } - const defaultRetainList = retainClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] - ) - }) - - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - if (simpleClassList.length > 1) { - const found = defaultSimpleList.length ? defaultSimpleList[0] : simpleClassList[0] - storageClass = found.value - } else if (simpleClassList.length === 1) { - storageClass = simpleClassList[0]?.value + function onArchiverChange() { + const archiverSwitch = getValue(discriminator, '/archiverEnabled') + const path = 'resources/kubedbComSinglestore/spec/archiver' + if (archiverSwitch) { + commit('wizard/model$update', { + path: path, + value: initialArchiver ? initialArchiver : archiverObjectToCommit, + }) } else { - const found = defaultRetainList.length - ? defaultRetainList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found + commit('wizard/model$delete', path) } - } else { - if (retainClassList.length > 1) { - const found = defaultRetainList.length ? defaultRetainList[0] : retainClassList[0] - storageClass = found.value - } else if (retainClassList.length === 1) { - storageClass = retainClassList[0]?.value + } + + 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 { - const found = defaultSimpleList.length - ? defaultSimpleList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found + obj['kubedb.com/archiver'] = 'true' } + + commit('wizard/model$update', { + path: `/resources/kubedbComSinglestore/metadata/${type}`, + value: obj, + force: true, + }) } - const mode = getValue(discriminator, '/activeDatabaseMode') + 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'] - if (mode === 'Sharded') { commit('wizard/model$update', { - path: '/resources/kubedbComSinglestore/spec/shardTopology/shard/storage/storageClassName', - value: storageClass, + path: `/resources/kubedbComSinglestore/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: '/resources/kubedbComSinglestore/spec/shardTopology/configServer/storage/storageClassName', - value: storageClass, + path: '/context', + value: context, force: true, }) - commit('wizard/model$delete', '/resources/kubedbComSinglestore/spec/storage') - } else { + 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/kubedbComSinglestore/spec/storage/storageClassName', - value: storageClass, + path: '/resources/coreKubestashComBackupConfiguration', + value: configDetails, force: true, }) } -} -function updateConfigServerStorageClass({ getValue, model, commit }) { - const storageClass = - getValue( - model, - '/resources/kubedbComSinglestore/spec/shardTopology/shard/storage/storageClassName', - ) || '' - commit('wizard/model$update', { - path: '/resources/kubedbComSinglestore/spec/shardTopology/configServer/storage/storageClassName', - value: storageClass, - 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 deleteDatabaseModePath({ discriminator, getValue, commit, model }) { - const mode = getValue(discriminator, '/activeDatabaseMode') - const modelSpec = getValue(model, '/resources/kubedbComSinglestore/spec') - if (mode === 'Sharded') { - commit('wizard/model$delete', '/resources/kubedbComSinglestore/spec/replicaSet') - commit('wizard/model$delete', '/resources/kubedbComSinglestore/spec/replicas') - commit('wizard/model$delete', '/resources/kubedbComSinglestore/spec/storage') - commit('wizard/model$delete', '/resources/kubedbComSinglestore/spec/podTemplate') - commit('wizard/model$delete', '/resources/kubedbComSinglestore/spec/configSecret') + function initRepositoryChoiseForEdit() { + const stashAppscodeComRepository_repo = getValue( + model, + '/resources/stashAppscodeComRepository_repo', + ) + const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' + setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) - commit('wizard/model$delete', '/resources/secret_config') + return repoInitialSelectionStatus + } - if (!modelSpec.shardTopology) { + 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: '/resources/kubedbComSinglestore/spec/shardTopology', - value: { - configServer: { - replicas: 3, - storage: { - resources: { - requests: { - storage: '', - }, - }, - }, - }, - mongos: { - replicas: 2, - }, - shard: { - replicas: 3, - shards: 3, - storage: { - resources: { - requests: { - storage: '', - }, - }, - }, - }, + path: modelPath, + value: session, + }) + } + } + + 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/kubedbComSinglestore/metadata/labels') + const bindingValues = { + apiVersion: 'catalog.appscode.com/v1alpha1', + kind: 'SinglestoreBinding', + metadata: { + labels, + name: dbName, + namespace: dbNamespace, + }, + spec: { + sourceRef: { + name: dbName, + namespace: dbNamespace, }, + }, + } + + if (value) { + commit('wizard/model$update', { + path: '/resources/catalogAppscodeComSinglestoreBinding', + value: bindingValues, force: true, }) + } else { + commit('wizard/model$delete', '/resources/catalogAppscodeComSinglestoreBinding') } - } else if (mode === 'Replicaset') { - commit('wizard/model$delete', '/resources/kubedbComSinglestore/spec/shardTopology') + } + + function isBindingAlreadyOn() { + const value = getValue(model, '/resources') + const keys = Object.keys(value) + const isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComSinglestoreBinding') + return isExposeBinding + } + + function objectCopy(obj) { + const temp = JSON.stringify(obj) + return JSON.parse(temp) + } + + /********** Compute Autoscaling ********** */ - commit('wizard/model$delete', '/resources/secret_shard_config') - commit('wizard/model$delete', '/resources/secret_configserver_config') - commit('wizard/model$delete', '/resources/secret_mongos_config') + let autoscaleType = '' + let dbDetails = {} - if (!modelSpec.replicaSet) { + function isConsole() { + const isKube = isKubedb() + + if (isKube) { + const dbName = storeGet('/route/params/name') || '' commit('wizard/model$update', { - path: '/resources/kubedbComSinglestore/spec/replicaSet', - value: { name: '' }, + path: '/resources/autoscalingKubedbComSinglestoreAutoscaler/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/kubedbComSinglestore/spec/replicas', - value: 3, + path: '/resources/autoscalingKubedbComSinglestoreAutoscaler/metadata/name', + value: modifiedName, force: true, }) + const namespace = storeGet('/route/query/namespace') || '' + if (namespace) { + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComSinglestoreAutoscaler/metadata/namespace', + value: namespace, + force: true, + }) + } } - } else if (mode === 'Standalone') { - commit('wizard/model$delete', '/resources/kubedbComSinglestore/spec/shardTopology') - commit('wizard/model$delete', '/resources/kubedbComSinglestore/spec/replicaSet') - commit('wizard/model$delete', '/resources/kubedbComSinglestore/spec/replicas') + return !isKube + } - commit('wizard/model$delete', '/resources/secret_shard_config') - commit('wizard/model$delete', '/resources/secret_configserver_config') - commit('wizard/model$delete', '/resources/secret_mongos_config') + function isKubedb() { + return !!storeGet('/route/params/actions') } -} -function isEqualToDatabaseMode({ getValue, watchDependency, discriminator }, value) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - return mode === value -} + function showOpsRequestOptions() { + if (isKubedb() === true) return true + // watchDependency( + // 'model#/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/databaseRef/name', + // ) + // watchDependency('discriminator#/autoscalingType') + return ( + !!getValue( + model, + '/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/databaseRef/name', + ) && !!getValue(discriminator, '/autoscalingType') + ) + } -// ************************** TLS ******************************88 + async function getNamespaces() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function setApiGroup() { - return 'cert-manager.io' -} + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, + }) -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - watchDependency('model#/resources/kubedbComSinglestore/spec/tls/issuerRef/apiGroup') - watchDependency('model#/resources/kubedbComSinglestore/spec/tls/issuerRef/kind') - watchDependency('model#/metadata/release/namespace') - const apiGroup = getValue(model, '/resources/kubedbComSinglestore/spec/tls/issuerRef/apiGroup') - const kind = getValue(model, '/resources/kubedbComSinglestore/spec/tls/issuerRef/kind') - const namespace = getValue(model, '/metadata/release/namespace') + const resources = (resp && resp.data && resp.data.items) || [] - let url - if (kind === 'Issuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/namespaces/${namespace}/issuers` - } else if (kind === 'ClusterIssuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/clusterissuers` + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) } - if (!url) return [] + async function getDbs() { + // watchDependency('model#/resources/autoscalingKubedbComSinglestoreAutoscaler/metadata/namespace') + const namespace = getValue( + model, + '/resources/autoscalingKubedbComSinglestoreAutoscaler/metadata/namespace', + ) + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - try { - const resp = await axios.get(url) + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/singlestores`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) const resources = (resp && resp.data && resp.data.items) || [] - resources.map((item) => { + return resources.map((item) => { const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + return { + text: name, + value: name, + } }) - return resources - } catch (e) { - console.log(e) - return [] } -} - -async function hasIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await getIssuerRefsName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !!(resp && resp.length) -} -async function hasNoIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await hasIssuerRefName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !resp -} - -function setClusterAuthMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComSinglestore/spec/clusterAuthMode') - return val || 'x509' -} - -function setSSLMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComSinglestore/spec/sslMode') - return val || 'requireSSL' -} - -function showTlsConfigureSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configureTLS') - const configureStatus = getValue(discriminator, '/configureTLS') - return configureStatus -} - -function onTlsConfigureChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/configureTLS') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComSinglestore/spec/tls', - value: { issuerRef: {}, certificates: [] }, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComSinglestore/spec/tls') - commit('wizard/model$delete', '/resources/kubedbComSinglestore/spec/clusterAuthMode') - commit('wizard/model$delete', '/resources/kubedbComSinglestore/spec/sslMode') - } -} - -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} - -/****** Monitoring *********/ - -function showMonitoringSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/enableMonitoring') - const configureStatus = getValue(discriminator, '/enableMonitoring') - return configureStatus -} - -function onEnableMonitoringChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/enableMonitoring') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComSinglestore/spec/monitor', - value: {}, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComSinglestore/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, getValue }) { - watchDependency('discriminator#/customizeExporter') - const configureStatus = getValue(discriminator, '/customizeExporter') - return configureStatus -} - -function onCustomizeExporterChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/customizeExporter') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComSinglestore/spec/monitor/prometheus/exporter', - value: {}, - force: true, - }) - } else { - commit( - 'wizard/model$delete', - '/resources/kubedbComSinglestore/spec/monitor/prometheus/exporter', - ) - } -} - -// ********************************* Initialization & Backup ************************************* -const stashAppscodeComRestoreSession_init = { - spec: { - repository: { - name: '', - }, - rules: [ - { - snapshots: ['latest'], - }, - ], - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} -const initScript = { - scriptPath: '', - secret: { - secretName: '', - }, -} -const stashAppscodeComRepository_init_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const stashAppscodeComRepository_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const restoreSessionInitRunTimeSettings = { - container: { - resources: { - requests: { - cpu: '', - memory: '', - }, - limits: { - cpu: '', - memory: '', - }, - }, - nice: { - adjustment: null, - }, - ionice: { - class: null, - classData: null, - }, - securityContext: { - privileged: false, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - env: [], - envFrom: [], - }, - pod: { - serviceAccountName: '', - imagePullSecrets: [], - securityContext: { - fsGroup: null, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - }, -} - -const stashAppscodeComBackupConfiguration = { - spec: { - repository: { - name: '', - }, - retentionPolicy: { - keepLast: 5, - name: 'keep-last-5', - prune: true, - }, - schedule: '*/5 * * * *', - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} - -function disableInitializationSection({ model, getValue, watchDependency }) { - const initialized = getValue(model, '/resources/kubedbComSinglestore/spec/init/initialized') - watchDependency('model#/resources/kubedbComSinglestore/spec/init/initialized') - return !!initialized -} - -function valueExists(value, getValue, path) { - const val = getValue(value, path) - if (val) return true - else return false -} - -function initPrePopulateDatabase({ getValue, model }) { - const waitForInitialRestore = getValue( - model, - '/resources/kubedbComSinglestore/spec/init/waitForInitialRestore', - ) - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - const script = getValue(model, '/resources/kubedbComSinglestore/spec/init/script') - - return waitForInitialRestore || !!stashAppscodeComRestoreSession_init || !!script ? 'yes' : 'no' -} - -function onPrePopulateDatabaseChange({ commit, getValue, discriminator, model }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - if (prePopulateDatabase === 'no') { - // delete related properties - commit('wizard/model$update', { - path: '/resources/kubedbComSinglestore/spec/init/waitForInitialRestore', - value: false, - }) - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - commit('wizard/model$delete', '/resources/kubedbComSinglestore/spec/init/script') - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else { - const dbName = getValue(model, '/metadata/release/name') - // set stashAppscodeComRestoreSession_init if it doesn't exist - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - force: true, - }) - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - } - } -} - -function initDataSource({ getValue, model }) { - const script = getValue(model, '/resources/kubedbComSinglestore/spec/init/script') - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - - if (script) return 'script' - else if (stashAppscodeComRestoreSession_init) return 'stashBackup' - else return undefined -} - -function onDataSourceChange({ commit, getValue, discriminator, model }) { - const dataSource = getValue(discriminator, '/dataSource') - - commit('wizard/model$update', { - path: '/resources/kubedbComSinglestore/spec/init/waitForInitialRestore', - value: dataSource === 'stashBackup', - force: true, - }) - - if (dataSource === 'script') { - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - - // create a new script if there is no script property - if (!valueExists(model, getValue, '/resources/kubedbComSinglestore/spec/init/script')) - commit('wizard/model$update', { - path: '/resources/kubedbComSinglestore/spec/init/script', - value: initScript, - }) - } else if (dataSource === 'stashBackup') { - commit('wizard/model$delete', '/resources/kubedbComSinglestore/spec/init/script') - - // create a new stashAppscodeComRestoreSession_init if there is no stashAppscodeComRestoreSession_init property - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - const dbName = getValue(model, '/metadata/release/name') - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - }) - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - } - } -} - -// // for script -function initVolumeType({ getValue, model }) { - const configMap = getValue( - model, - '/resources/kubedbComSinglestore/spec/init/script/configMap/name', - ) - const secret = getValue( - model, - '/resources/kubedbComSinglestore/spec/init/script/secret/secretName', - ) - - if (configMap) return 'configMap' - else if (secret) return 'secret' - else return undefined -} - -function onVolumeTypeChange({ commit, getValue, discriminator, model }) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - if (sourceVolumeType === 'configMap') { - // add configMap object and delete secret object - commit('wizard/model$delete', '/resources/kubedbComSinglestore/spec/init/script/secret') - - if ( - !valueExists(model, getValue, '/resources/kubedbComSinglestore/spec/init/script/configMap') - ) { - commit('wizard/model$update', { - path: '/resources/kubedbComSinglestore/spec/init/script/configMap', - value: { - name: '', - }, - }) - } - } else if (sourceVolumeType === 'secret') { - // delete configMap object and add secret object - commit('wizard/model$delete', '/resources/kubedbComSinglestore/spec/init/script/configMap') - - if (!valueExists(model, getValue, '/resources/kubedbComSinglestore/spec/init/script/secret')) { - commit('wizard/model$update', { - path: '/resources/kubedbComSinglestore/spec/init/script/secret', - value: { - secretName: '', - }, - }) - } - } -} - -function showInitializationForm({ getValue, discriminator, watchDependency }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - watchDependency('discriminator#/prePopulateDatabase') - return prePopulateDatabase === 'yes' -} - -function showScriptOrStashForm({ getValue, discriminator, watchDependency }, value) { - const dataSource = getValue(discriminator, '/dataSource') - watchDependency('discriminator#/dataSource') - return dataSource === value -} - -function showConfigMapOrSecretName({ getValue, discriminator, watchDependency }, value) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - watchDependency('discriminator#/sourceVolumeType') - return sourceVolumeType === value -} - -// for stash backup -function initializeNamespace({ getValue, model }) { - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} - -function showRepositorySelectOrCreate({ getValue, discriminator, watchDependency }, value) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - return repositoryChoise === value -} - -function onInitRepositoryChoiseChange({ getValue, discriminator, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - if (repositoryChoise === 'select') { - // delete stashAppscodeComRepository_init_repo from model - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else if (repositoryChoise === 'create') { - // add stashAppscodeComRepository_init_repo to model - commit('wizard/model$update', { - path: 'resources/stashAppscodeComRepository_init_repo', - value: stashAppscodeComRepository_init_repo, - }) - - const repositoryName = `${getValue(model, '/metadata/release/name')}-init-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: repositoryName, - }) - } -} - -function initCustomizeRestoreJobRuntimeSettings({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function initCustomizeRestoreJobRuntimeSettingsForBackup({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function onCustomizeRestoreJobRuntimeSettingsChange({ commit, getValue, discriminator, model }) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - value: restoreSessionInitRunTimeSettings, - }) - } - } -} - -function onCustomizeRestoreJobRuntimeSettingsChangeForBackup({ - commit, - getValue, - discriminator, - model, -}) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - value: {}, - force: true, - }) - } - } -} - -function showRuntimeForm({ discriminator, getValue, watchDependency }, value) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - watchDependency('discriminator#/customizeRestoreJobRuntimeSettings') - return customizeRestoreJobRuntimeSettings === value -} - -async function getImagePullSecrets({ getValue, model, watchDependency, axios, storeGet }) { - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - - let resources = await getNamespacedResourceList(axios, storeGet, { - namespace, - group: 'core', - version: 'v1', - resource: 'secrets', - }) - - resources = resources.filter((item) => { - const validType = ['kubernetes.io/dockerconfigjson'] - return validType.includes(item.type) - }) - - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: { name: name }, - } - }) -} - -function showBackupOptions({ discriminator, getValue, watchDependency }, backup) { - const backupEnabled = getValue(discriminator, '/backupEnabled') - if (backupEnabled) { - if (backup === 'alert') return true - else return false - } else { - if (backup === 'alert') return false - else return true - } -} - -function isBlueprintOption({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/blueprintOptions') - const blueprintOptions = getValue(discriminator, '/blueprintOptions') - return blueprintOptions === value -} - -function ifUsagePolicy({ discriminator, getValue, watchDependency, model }, value) { - watchDependency( - 'model#/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', - ) - const usagePolicy = getValue( - model, - '/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', - ) - return usagePolicy === value -} - -async function getBlueprints({ getValue, model, setDiscriminatorValue, axios, storeGet }, backup) { - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const url = `clusters/${username}/${clusterName}/proxy/core.kubestash.com/v1alpha1/backupblueprints` - - try { - const resp = await axios.get(url) - let data = resp.data.items - return data - } catch (e) { - console.log(e) - } -} - -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} - -async function fetchNamespaces({ axios, storeGet }) { - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const group = storeGet('/route/params/group') - const version = storeGet('/route/params/version') - const resource = storeGet('/route/params/resource') - - const url = `clusters/${username}/${clusterName}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews` - - try { - const resp = await axios.post(url, { - _recurringCall: false, - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], - }, - }) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] - } - } catch (e) { - console.log(e) - } - return [] -} - -async function fetchNames( - { getValue, axios, storeGet, watchDependency, discriminator }, - version, - type, - discriminatorName, -) { - watchDependency(`discriminator#/${discriminatorName}`) - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const namespace = getValue(discriminator, `${discriminatorName}`) - const url = - type !== 'secrets' - ? `clusters/${username}/${clusterName}/proxy/storage.kubestash.com/${version}/namespaces/${namespace}/${type}` - : `clusters/${username}/${clusterName}/proxy/core/${version}/namespaces/${namespace}/${type}` - try { - if (namespace) { - const resp = await axios.get(url) - let data = resp.data.items - if (type === 'secrets') data = data.filter((ele) => !!ele.data['RESTIC_PASSWORD']) - data = data.map((ele) => ele.metadata.name) - return data - } - } catch (e) { - console.log(e) - } - return [] -} - -// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// FOR Backup Configuration - -// schedule backup - -function getBackupConfigsAndAnnotations(getValue, model) { - const stashAppscodeComBackupConfiguration = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration', - ) - - const coreKubestashComBackupConfiguration = getValue( - model, - '/resources/coreKubestashComBackupConfiguration', - ) - const kubeStashTarget = coreKubestashComBackupConfiguration?.spec?.target - - const mongoDB = getValue(model, '/resources/kubedbComSinglestore') - const mongoDbKind = mongoDB?.apiVersion?.split('/')?.at(0) - - let isKubeStash = false - if ( - mongoDB?.kind === kubeStashTarget.kind && - mongoDB?.metadata?.name === kubeStashTarget?.name && - mongoDB?.metadata?.namespace === kubeStashTarget?.namespace && - mongoDbKind === kubeStashTarget?.apiGroup - ) { - isKubeStash = true - } - - const kubedbComSinglestoreAnnotations = - getValue(model, '/resources/kubedbComSinglestore/metadata/annotations') || {} - - const isBluePrint = Object.keys(kubedbComSinglestoreAnnotations).some( - (k) => - k === 'stash.appscode.com/backup-blueprint' || - k === 'stash.appscode.com/schedule' || - k.startsWith('params.stash.appscode.com/'), - ) - - return { - stashAppscodeComBackupConfiguration, - isBluePrint, - isKubeStash, - } -} - -function deleteKubeDbComMongDbAnnotation(getValue, model, commit) { - const annotations = getValue(model, '/resources/kubedbComSinglestore/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/kubedbComSinglestore/metadata/annotations', - value: filteredAnnotations, - }) -} - -function addKubeDbComMongDbAnnotation(getValue, model, commit, key, value, force) { - const annotations = getValue(model, '/resources/kubedbComSinglestore/metadata/annotations') || {} - - if (annotations[key] === undefined) { - annotations[key] = value - } else if (force) { - annotations[key] = value - } - - commit('wizard/model$update', { - path: '/resources/kubedbComSinglestore/metadata/annotations', - value: annotations, - force: true, - }) -} - -function initScheduleBackupForEdit({ getValue, model, setDiscriminatorValue }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function initScheduleBackup({ getValue, model }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function onScheduleBackupChange({ commit, getValue, discriminator, model }) { - 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 kubedbComSinglestore annotation - deleteKubeDbComMongDbAnnotation(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, - }) - } - } -} - -// backup form -function showBackupForm({ getValue, discriminator, watchDependency }) { - 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({ storeGet, axios, getValue, model, setDiscriminatorValue }) { - // 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/kubedbComSinglestore') - initialDbMetadata = objectCopy(dbResource.metadata) - - // 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 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, getValue, discriminator }) { - watchDependency('discriminator#/isBackupDataLoaded') - return !!getValue(discriminator, '/isBackupDataLoaded') -} - -async function setBackupType() { - return 'BackupConfig' -} - -async function getTypes() { - const arr = [ - { - description: 'Create, Delete or Modify BackupConfig', - text: 'BackupConfig', - value: 'BackupConfig', - }, - { - description: 'Enable/Disable BackupBlueprint', - text: 'BackupBlueprint', - value: 'BackupBlueprint', - }, - ] - return arr -} - -function onBackupTypeChange({ commit, getValue, discriminator }) { - 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/kubedbComSinglestore', - value: objectCopy(dbResource), - force: true, - }) -} - -function isBackupType({ watchDependency, getValue, discriminator }, 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({ getValue, discriminator, commit, model, storeGet }) { - const blueprintSwitch = getValue(discriminator, '/blueprintEnabled') - if (blueprintSwitch) addLabelAnnotation(commit, storeGet, 'annotations') - else deleteLabelAnnotation(commit, 'annotations') -} - -function setArchiverSwitch() { - const archiver = dbResource?.spec?.archiver - return !!archiver -} - -function onArchiverChange({ getValue, discriminator, commit }) { - const archiverSwitch = getValue(discriminator, '/archiverEnabled') - const path = 'resources/kubedbComSinglestore/spec/archiver' - if (archiverSwitch) { - commit('wizard/model$update', { - path: path, - value: initialArchiver ? initialArchiver : archiverObjectToCommit, - }) - } else { - commit('wizard/model$delete', path) - } -} - -function addLabelAnnotation(commit, storeGet, 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/kubedbComSinglestore/metadata/${type}`, - value: obj, - force: true, - }) -} - -function deleteLabelAnnotation(commit, 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/kubedbComSinglestore/metadata/${type}`, - value: obj, - force: true, - }) -} - -function getContext() { - if (isBackupOn) return ['Create', 'Delete', 'Modify'] - return ['Create'] -} - -function onContextChange({ getValue, discriminator, commit, model }) { - 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, - }) - } -} - -function getConfigList({ storeGet }) { - 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({ getValue, discriminator, commit, storeGet, model }) { - 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, getValue, discriminator }) { - watchDependency('discriminator#/backupConfigContext') - watchDependency('discriminator#/config') - const contex = getValue(discriminator, '/backupConfigContext') - const configName = getValue(discriminator, '/config') - return !!configName && contex === 'Modify' -} - -function showConfigList({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/backupConfigContext') - const contex = getValue(discriminator, '/backupConfigContext') - return contex === 'Modify' || contex === 'Delete' -} - -function showSchedule({ watchDependency, getValue, discriminator }) { - 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 getNamespaceArray() { - return namespaceList -} - -// backup configuration form -function initalizeTargetReferenceName({ getValue, model, watchDependency }) { - const databaseName = getValue(model, '/metadata/release/name') - watchDependency('model#/metadata/release/name') - - return databaseName -} - -// restore session repository -function setInitialRestoreSessionRepo({ getValue, model }) { - const value = getValue(model, 'resources/stashAppscodeComRepository_init_repo') - return value ? 'create' : 'select' -} - -// backup config repository -function initRepositoryChoise({ getValue, model }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - - if (stashAppscodeComRepository_repo) return 'create' - else return 'select' -} - -function initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' - setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) - - return repoInitialSelectionStatus -} - -function onRepositoryChoiseChange({ getValue, discriminator, watchDependency, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - if (repositoryChoise === 'select') { - // delete the stashAppscodeComRepository_repo - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') - } else if (repositoryChoise === 'create') { - // create new stashAppscodeComRepository_repo - if (!valueExists(model, getValue, '/resources/stashAppscodeComRepository_repo')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRepository_repo', - value: stashAppscodeComRepository_repo, - }) - const repositoryName = `${getValue(model, '/metadata/release/name')}-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) - } - } -} - -function onRepositoryNameChange({ getValue, model, commit }) { - const repositoryName = getValue(model, 'resources/stashAppscodeComRepository_repo/metadata/name') - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) -} - -function onInputChange( - { getValue, discriminator, commit, model }, - modelPath, - field, - subfield, - discriminatorName, -) { - const value = getValue(discriminator, `/${discriminatorName}`) - const backends = getValue(model, modelPath) || [] - if (field !== 'encryptionSecret') backends[0][field][subfield] = value - else backends[0]['repositories'][0][field][subfield] = value - commit('wizard/model$update', { - path: modelPath, - value: backends, - }) -} - -function setFileValueFromStash({ getValue, commit, model }, modelPath, field, subfield, value) { - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') backends[0][field][subfield] = value - else backends[0]['repositories'][0][field][subfield] = value - commit('wizard/model$update', { - path: modelPath, - value: backends, - }) -} - -function onInputChangeSchedule( - { getValue, discriminator, commit, model }, - modelPath, - discriminatorName, -) { - const value = getValue(discriminator, `/${discriminatorName}`) - const session = getValue(model, modelPath) - session[0].scheduler.schedule = value - commit('wizard/model$update', { - path: modelPath, - value: session, - }) -} - -function setInitSchedule( - { getValue, discriminator, watchDependency, commit, model }, - modelPath, - value, -) { - const session = getValue(model, modelPath) - session[0].scheduler.schedule = value - commit('wizard/model$update', { - path: modelPath, - value: session, - }) -} - -function getDefault({ getValue, model }, modelPath, field, subfield) { - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') return backends[0][field][subfield] - else { - return backends[0]['repositories'][0][field][subfield] - } -} - -function getDefaultSchedule({ getValue, model, watchDependency }, modelPath) { - watchDependency('discriminator#/config') - const session = getValue(model, modelPath) - return session?.length ? session[0]?.scheduler.schedule : '' -} - -// backup blueprint form -function getMongoAnnotations(getValue, model) { - const annotations = getValue(model, '/resources/kubedbComSinglestore/metadata/annotations') - return { ...annotations } || {} -} - -function initFromAnnotationValue({ getValue, model }, key) { - const annotations = getMongoAnnotations(getValue, model) - return annotations[key] -} - -function onBackupBlueprintNameChange({ getValue, discriminator, commit, model }) { - const backupBlueprintName = getValue(discriminator, '/backupBlueprintName') - addKubeDbComMongDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/backup-blueprint', - backupBlueprintName, - true, - ) -} - -function onBackupBlueprintScheduleChange({ getValue, discriminator, commit, model }) { - const backupBlueprintSchedule = getValue(discriminator, '/schedule') - addKubeDbComMongDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/schedule', - backupBlueprintSchedule, - true, - ) -} - -function initFromAnnotationKeyValue({ getValue, model }, prefix) { - const annotations = getMongoAnnotations(getValue, model) - const newOb = {} - Object.keys(annotations).forEach((key) => { - if (key.startsWith(prefix)) { - const newKey = key.replace(prefix, '') - newOb[newKey] = annotations[key] + async function getDbDetails() { + const annotations = getValue( + model, + '/resources/autoscalingKubedbComSinglestoreAutoscaler/metadata/annotations', + ) + instance = annotations['kubernetes.io/instance-type'] + const owner = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + const namespace = + storeGet('/route/query/namespace') || + getValue(model, '/resources/autoscalingKubedbComSinglestoreAutoscaler/metadata/namespace') || + '' + const name = + storeGet('/route/params/name') || + getValue( + model, + '/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/databaseRef/name', + ) || + '' + + if (namespace && name) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/singlestores/${name}`, + ) + dbDetails = resp.data || {} + setDiscriminatorValue('/dbDetails', true) + } catch (e) { + console.log(e) + } } - }) - return newOb -} - -function onTaskParametersChange({ getValue, discriminator, model, commit }) { - const taskParameters = getValue(discriminator, '/taskParameters') - const taskParamterKeys = Object.keys(taskParameters).map( - (tp) => `params.stash.appscode.com/${tp}`, - ) - const oldAnnotations = - getValue(model, '/resources/kubedbComSinglestore/metadata/annotations') || {} - const newAnnotations = {} - - const filteredAnnotationKeys = Object.keys(oldAnnotations).filter( - (key) => !taskParamterKeys.includes(key) && !key.startsWith('params.stash.appscode.com/'), - ) - - filteredAnnotationKeys.forEach((key) => { - newAnnotations[key] = oldAnnotations[key] - }) - - Object.keys(taskParameters).forEach((tpk) => { - newAnnotations[`params.stash.appscode.com/${tpk}`] = taskParameters[tpk] - }) - - commit('wizard/model$update', { - path: '/resources/kubedbComSinglestore/metadata/annotations', - value: newAnnotations, - }) -} - -function isValueExistInModel({ model, getValue }, path) { - const modelValue = getValue(model, path) - return !!modelValue -} - -function onNamespaceChange({ commit, model, getValue }) { - const namespace = getValue(model, '/metadata/release/namespace') - const agent = getValue(model, '/resources/kubedbComSinglestore/spec/monitor/agent') - if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', - value: [namespace], + path: `/metadata/release/name`, + value: name, force: true, }) - } -} - -function onLabelChange({ commit, model, getValue }) { - const labels = getValue(model, '/resources/kubedbComSinglestore/spec/metadata/labels') - - const agent = getValue(model, '/resources/kubedbComSinglestore/spec/monitor/agent') - - if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, + path: `/metadata/release/namespace`, + value: namespace, force: true, }) - } -} - -function onNameChange({ commit, model, getValue }) { - const dbName = getValue(model, '/metadata/release/name') - - const agent = getValue(model, '/resources/kubedbComSinglestore/spec/monitor/agent') - - const labels = getValue(model, '/resources/kubedbComSinglestore/spec/metadata/labels') - - if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, + path: `/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/databaseRef/name`, + value: name, force: true, }) - } - - const scheduleBackup = getValue(model, '/resources/stashAppscodeComBackupConfiguration') - - if (scheduleBackup) { commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, + path: `/resources/autoscalingKubedbComSinglestoreAutoscaler/metadata/labels`, + value: dbDetails.metadata.labels, force: true, }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_repo') - if (creatingNewRepo) { + } + + function initMetadata() { + const dbName = + getValue( + model, + '/resources/autoscalingKubedbComSinglestoreAutoscaler/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/stashAppscodeComBackupConfiguration/spec/repository/name', - value: `${dbName}-repo`, + path: '/resources/autoscalingKubedbComSinglestoreAutoscaler/metadata/name', + value: modifiedName, force: true, }) - } - } - const prePopulateDatabase = getValue(model, '/resources/stashAppscodeComRestoreSession_init') + // delete the other type object from model + if (type === 'compute') + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/storage', + ) + if (type === 'storage') + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/compute', + ) + } - if (prePopulateDatabase) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_init_repo') - if (creatingNewRepo) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: `${dbName}-init-repo`, - force: true, + function onNamespaceChange({ model, getValue, commit }) { + const namespace = getValue( + model, + '/resources/autoscalingKubedbComSinglestoreAutoscaler/metadata/namespace', + ) + if (!namespace) { + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/databaseRef/name', + ) + } + } + 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 [] } - // to reset configSecret name field - const hasSecretConfig = getValue(model, '/resources/secret_config') - if (hasSecretConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComSinglestore/spec/configSecret/name', - value: `${dbName}-config`, - force: true, - }) + function isNodeTopologySelected() { + // watchDependency( + // 'model#/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/compute/nodeTopology/name', + // ) + const nodeTopologyName = + getValue( + model, + '/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/compute/nodeTopology/name', + ) || '' + return !!nodeTopologyName.length } - // to reset shard configSecret name field - const hasSecretShardConfig = getValue(model, '/resources/secret_shard_config') - if (hasSecretShardConfig) { + function setControlledResources(type) { + const list = ['cpu', 'memory'] + const path = `/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/compute/${type}/controlledResources` commit('wizard/model$update', { - path: '/resources/kubedbComSinglestore/spec/shardTopology/shard/configSecret/name', - value: `${dbName}-shard-config`, + path: path, + value: list, force: true, }) + return list } - // to reset shard configSecret name field - const hasSecretConfigServerConfig = getValue(model, '/resources/secret_configserver_config') - if (hasSecretConfigServerConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComSinglestore/spec/shardTopology/configServer/configSecret/name', - value: `${dbName}-configserver-config`, - force: true, - }) + function setTrigger(path) { + let value = getValue(model, `/resources/${path}`) + return value === 'On' } - // to reset mongos configSecret name field - const hasSecretMongosConfig = getValue(model, '/resources/secret_mongos_config') - if (hasSecretMongosConfig) { - commit('wizard/model$update', { - path: '/resources/kubedbComSinglestore/spec/shardTopology/mongos/configSecret/name', - value: `${dbName}-mongos-config`, - force: true, - }) + function setValueFromDbDetails(path) { + const value = getValue(model, path) + return value } -} - -function returnFalse() { - return false -} - -function onAgentChange({ commit, model, getValue }) { - const agent = getValue(model, '/resources/kubedbComSinglestore/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', - value: [], - force: true, - }) - onNamespaceChange({ commit, model, getValue }) - onLabelChange({ commit, model, getValue }) - } else { - commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') + function setApplyToIfReady() { + return 'IfReady' } -} - -/************************************* Database Secret Section ********************************************/ - -function getCreateAuthSecret({ model, getValue }) { - const authSecret = getValue(model, '/resources/kubedbComSinglestore/spec/authSecret') - - return !authSecret -} - -function showExistingSecretSection({ getValue, watchDependency, discriminator }) { - watchDependency('discriminator#/createAuthSecret') - - const hasAuthSecretName = getValue(discriminator, '/createAuthSecret') - return !hasAuthSecretName -} - -function showPasswordSection({ getValue, watchDependency, discriminator }) { - return !showExistingSecretSection({ - getValue, - watchDependency, - discriminator, - }) -} - -function setAuthSecretPassword({ model, getValue }) { - const encodedPassword = getValue(model, '/resources/secret_auth/data/password') - return encodedPassword ? decodePassword({}, encodedPassword) : '' -} - -function onAuthSecretPasswordChange({ getValue, discriminator, commit }) { - const stringPassword = getValue(discriminator, '/password') - if (stringPassword) { - commit('wizard/model$update', { - path: '/resources/secret_auth/data/password', - value: encodePassword({}, stringPassword), - force: true, - }) - commit('wizard/model$update', { - path: '/resources/secret_auth/data/username', - value: encodePassword({}, 'root'), - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/secret_auth') + function setMetadata() { + const dbname = storeGet('/route/params/name') || '' + const namespace = storeGet('/route/query/namespace') || '' + if (mode === 'standalone-step') { + commit('wizard/model$update', { + path: '/metadata/release/name', + value: dbname, + force: true, + }) + commit('wizard/model$update', { + path: '/metadata/release/namespace', + value: namespace, + force: true, + }) + } } -} - -// eslint-disable-next-line no-empty-pattern -function encodePassword({}, value) { - return btoa(value) -} - -// eslint-disable-next-line no-empty-pattern -function decodePassword({}, value) { - return atob(value) -} -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/resources/kubedbComSinglestore/spec/authSecret') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/resources/secret_auth') + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found } -} - -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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 } }, - }, - }, + function hasAnnotations() { + const annotations = getValue( + model, + '/resources/autoscalingKubedbComSinglestoreAutoscaler/metadata/annotations', ) + const instance = annotations['kubernetes.io/instance-type'] - 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) - }) + return !!instance + } - 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 [] + function hasNoAnnotations() { + return !hasAnnotations() } -} -//////////////////////////////////////// Service Monitor ////////////////////////////////////////////////////// + function dbTypeEqualsTo(type) { + // watchDependency('discriminator#/dbDetails') -//////////////////// service monitor /////////////////// + const { spec } = dbDetails || {} + const { topology } = spec || {} + let verd = '' + if (topology) verd = 'topology' + else { + verd = 'standalone' + } + clearSpecModel(verd) + return type === verd && spec + } -function isEqualToServiceMonitorType({ rootModel, watchDependency }, value) { - watchDependency('rootModel#/spec/type') - return rootModel && rootModel.spec && rootModel.spec.type === value -} + function clearSpecModel(dbtype) { + if (dbtype === 'standalone') { + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/${autoscaleType}/cluster`, + ) + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/${autoscaleType}/sentinel`, + ) + } else if (dbtype === 'cluster') { + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/${autoscaleType}/standalone`, + ) + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/${autoscaleType}/sentinel`, + ) + } else if (dbtype === 'sentinel') { + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/${autoscaleType}/standalone`, + ) + commit( + 'wizard/model$delete', + `/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/${autoscaleType}/cluster`, + ) + } + } + + function onMachineChange(type) { + const annoPath = '/resources/autoscalingKubedbComSinglestoreAutoscaler/metadata/annotations' + const annotations = getValue(model, annoPath) || {} + const instance = annotations['kubernetes.io/instance-type'] + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = {} + } -//////////////////// custom config ///////////////// -function onConfigurationSourceChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSource') - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_config') - } else { - const value = getValue(model, '/resources/secret_config') - if (!value) { + // Now discriminator values are objects with { machine, cpu, memory } + const minMachineObj = getValue(discriminator, `/allowedMachine-${type}-min`) + const maxMachineObj = getValue(discriminator, `/allowedMachine-${type}-max`) + const minMachine = minMachineObj?.machine || '' + const maxMachine = maxMachineObj?.machine || '' + const minMaxMachine = `${minMachine},${maxMachine}` + + parsedInstance[type] = minMaxMachine + const instanceString = JSON.stringify(parsedInstance) + annotations['kubernetes.io/instance-type'] = instanceString + + // 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/autoscalingKubedbComSinglestoreAutoscaler/spec/compute/${type}` + + if (minMachine && maxMachine && instance !== instanceString) { commit('wizard/model$update', { - path: '/resources/secret_config', - value: {}, + 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, }) } - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComSinglestore/spec/configSecret/name', - value: configSecretName, - force: true, - }) } -} - -function onConfigurationChange({ getValue, commit, discriminator, model }) { - const value = getValue(discriminator, '/configuration') - commit('wizard/model$update', { - path: '/resources/secret_config/stringData/mongod.conf', - value: value, - force: true, - }) - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComSinglestore/spec/configSecret/name', - value: configSecretName, - force: true, - }) -} -function setConfigurationSource({ model, getValue }) { - const modelValue = getValue(model, '/resources/secret_config') - if (modelValue) { - return 'create-new-config' + 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, + }) + } + } } - return 'use-existing-config' -} - -function setSecretConfigNamespace({ getValue, model, watchDependency }) { - watchDependency('model#/metadata/release/namespace') - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} -//////////////////// custom config for sharded topology ///////////////// + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } -function setConfigurationSourceShard({ model, getValue, discriminator }) { - const src = getValue(discriminator, '/configurationSourceShard') - if (src) return src - const value = getValue(model, '/resources/secret_shard_config') - return value ? 'create-new-config' : 'use-existing-config' -} + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function setConfigurationSourceConfigServer({ model, getValue, discriminator }) { - const src = getValue(discriminator, '/configurationSourceConfigServer') - if (src) return src - const value = getValue(model, '/resources/secret_configserver_config') - return value ? 'create-new-config' : 'use-existing-config' -} + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) -function setConfigurationSourceMongos({ model, getValue, discriminator }) { - const src = getValue(discriminator, '/configurationSourceMongos') - if (src) return src - const value = getValue(model, '/resources/secret_mongos_config') - return value ? 'create-new-config' : 'use-existing-config' -} + const resources = (resp && resp.data && resp.data.items) || [] -function isSchemaOf(schema) { - if (schema === 'discriminator#/configurationSourceShard') { - return 'shard' - } else if (schema === 'discriminator#/configurationSourceConfigServer') { - return 'configserver' - } else { - return 'mongos' + 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 disableConfigSourceOption({ - itemCtx, - discriminator, - getValue, - watchDependency, - elementUi, -}) { - watchDependency('discriminator#/configurationSourceShard') - watchDependency('discriminator#/configurationSourceConfigServer') - watchDependency('discriminator#/configurationSourceMongos') - const configSrcShard = getValue(discriminator, '/configurationSourceShard') - const configSrcConfigServer = getValue(discriminator, '/configurationSourceConfigServer') - const configSrcMongos = getValue(discriminator, '/configurationSourceMongos') - if ( - itemCtx.value !== 'use-existing-config' && - itemCtx.value !== 'create-new-config' && - (configSrcShard === `same-as-${isSchemaOf(elementUi.schema.$ref)}-config-secret` || - configSrcConfigServer === `same-as-${isSchemaOf(elementUi.schema.$ref)}-config-secret` || - configSrcMongos === `same-as-${isSchemaOf(elementUi.schema.$ref)}-config-secret`) - ) { - return true - } - if ( - itemCtx.value === 'same-as-shard-config-secret' && - configSrcShard !== 'use-existing-config' && - configSrcShard !== 'create-new-config' - ) { - return true - } - if ( - itemCtx.value === 'same-as-configserver-config-secret' && - configSrcConfigServer !== 'use-existing-config' && - configSrcConfigServer !== 'create-new-config' - ) { - return true - } - if ( - itemCtx.value === 'same-as-mongos-config-secret' && - configSrcMongos !== 'use-existing-config' && - configSrcMongos !== 'create-new-config' + async function getNamespacedResourceList( + axios, + storeGet, + { namespace, group, version, resource }, ) { - return true - } - return false -} + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function onConfigurationSourceMongosChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSourceMongos') - const configSecretName = `${getValue(model, '/metadata/release/name')}-mongos-config` - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_mongos_config') - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'mongos', - configurationSource, - '/configurationMongos', - ) - } else if (configurationSource === 'create-new-config') { - const value = getValue(model, '/resources/secret_mongos_config') - if (!value) { - commit('wizard/model$update', { - path: '/resources/secret_mongos_config', - value: {}, - force: true, - }) - } - commit('wizard/model$update', { - path: '/resources/kubedbComSinglestore/spec/shardTopology/mongos/configSecret/name', - value: configSecretName, - force: true, - }) - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'mongos', - configurationSource, - '/configurationMongos', - ) - } else if (configurationSource === 'same-as-shard-config-secret') { - transferConfigSecret({ commit, model, getValue }, 'shard', 'mongos') - } else if (configurationSource === 'same-as-configserver-config-secret') { - transferConfigSecret({ commit, model, getValue }, 'configserver', 'mongos') - } -} + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` -function onConfigurationSourceShardChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSourceShard') - const configSecretName = `${getValue(model, '/metadata/release/name')}-shard-config` - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_shard_config') - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'shard', - configurationSource, - '/configurationShard', - ) - } else if (configurationSource === 'create-new-config') { - const value = getValue(model, '/resources/secret_shard_config') - if (!value) { - commit('wizard/model$update', { - path: '/resources/secret_shard_config', - value: {}, - force: true, + 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) } - commit('wizard/model$update', { - path: '/resources/kubedbComSinglestore/spec/shardTopology/shard/configSecret/name', - value: configSecretName, - force: true, - }) - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'shard', - configurationSource, - '/configurationShard', - ) - } else if (configurationSource === 'same-as-configserver-config-secret') { - transferConfigSecret({ commit, model, getValue }, 'configserver', 'shard') - } else if (configurationSource === 'same-as-mongos-config-secret') { - transferConfigSecret({ commit, model, getValue }, 'mongos', 'shard') + + return ans } -} -function onConfigurationSourceConfigServerChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSourceConfigServer') - const configSecretName = `${getValue(model, '/metadata/release/name')}-configserver-config` - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_configserver_config') - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'configserver', - configurationSource, - '/configurationConfigServer', - ) - } else if (configurationSource === 'create-new-config') { - const value = getValue(model, '/resources/secret_configserver_config') - if (!value) { + /****** 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/secret_configserver_config', + path: '/resources/kubedbComSinglestore/spec/monitor', value: {}, force: true, }) + } else { + commit('wizard/model$delete', '/resources/kubedbComSinglestore/spec/monitor') } - commit('wizard/model$update', { - path: '/resources/kubedbComSinglestore/spec/shardTopology/configServer/configSecret/name', - value: configSecretName, - force: true, - }) - onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - 'configserver', - configurationSource, - '/configurationConfigServer', - ) - } else if (configurationSource === 'same-as-shard-config-secret') { - const configurationSourceReference = getValue(discriminator, '/configurationSourceShard') - transferConfigSecret( - { commit, model, getValue }, - 'shard', - 'configserver', - configurationSourceReference, - ) - } else if (configurationSource === 'same-as-mongos-config-secret') { - const configurationSourceReference = getValue(discriminator, '/configurationSourceMongos') - transferConfigSecret( - { commit, model, getValue }, - 'mongos', - 'configserver', - configurationSourceReference, - ) - } -} -function transferConfigSecret({ commit, model, getValue }, src, des) { - const isShardedMode = getValue(model, '/resources/kubedbComSinglestore/spec/shardTopology') - if (isShardedMode) { + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: `/resources/kubedbComSinglestore/spec/shardTopology/${ - des === 'configserver' ? 'configServer' : des - }/configSecret/name`, - value: getValue( - model, - `/resources/kubedbComSinglestore/spec/shardTopology/${ - src === 'configserver' ? 'configServer' : src - }/configSecret/name`, - ), + path: '/form/alert/enabled', + value: configureStatus ? 'warning' : 'none', force: true, }) - - commit('wizard/model$delete', `/resources/secret_${des}_config`) } -} -function onConfigSecretModelChange( - { commit, model, getValue, discriminator }, - configType, - configSrc, - discriminatorPath, -) { - if (configSrc === 'create-new-config') { - const value = getValue(discriminator, discriminatorPath) - commit('wizard/model$update', { - path: `/resources/secret_${configType}_config/stringData/mongod.conf`, - value: value, - force: true, - }) + function showCustomizeExporterSection() { + // watchDependency('discriminator#/customizeExporter') + const configureStatus = getValue(discriminator, '/customizeExporter') + return configureStatus } - const configSrcShard = getValue(discriminator, '/configurationSourceShard') - const configSrcConfigServer = getValue(discriminator, '/configurationSourceConfigServer') - const configSrcMongos = getValue(discriminator, '/configurationSourceMongos') - if (configSrcShard === `same-as-${configType}-config-secret`) { - transferConfigSecret({ commit, model, getValue }, configType, 'shard') - } - if (configSrcConfigServer === `same-as-${configType}-config-secret`) { - transferConfigSecret({ commit, model, getValue }, configType, 'configserver') - } - if (configSrcMongos === `same-as-${configType}-config-secret`) { - transferConfigSecret({ commit, model, getValue }, configType, 'mongos') + function onCustomizeExporterChange() { + const configureStatus = getValue(discriminator, '/customizeExporter') + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComSinglestore/spec/monitor/prometheus/exporter', + value: {}, + force: true, + }) + } else { + commit( + 'wizard/model$delete', + '/resources/kubedbComSinglestore/spec/monitor/prometheus/exporter', + ) + } } -} - -function setConfiguration({ model, getValue }) { - return getValue(model, '/resources/secret_config/stringData/mongod.conf') -} - -function setConfigurationShard({ model, getValue }) { - const value = getValue(model, '/resources/secret_shard_config/stringData/mongod.conf') - return value -} -function setConfigurationConfigServer({ model, getValue }) { - const value = getValue(model, '/resources/secret_configserver_config/stringData/mongod.conf') - return value -} + function isValueExistInModel(path) { + const modelValue = getValue(model, path) || null + return !!modelValue + } -function setConfigurationMongos({ model, getValue }) { - const value = getValue(model, '/resources/secret_mongos_config/stringData/mongod.conf') - return value -} + // function onNamespaceChange({ commit, model, getValue }) { + // const namespace = getValue(model, '/metadata/release/namespace') + // const agent = getValue(model, '/resources/kubedbComSinglestore/spec/monitor/agent') + // if (agent === 'prometheus.io') { + // commit('wizard/model$update', { + // path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + // value: [namespace], + // force: true, + // }) + // } + // } -function setConfigurationFiles({ model, getValue }) { - const value = getValue(model, '/resources/secret_config/data/mongod.conf') - return atob(value) -} + function onLabelChange() { + const labels = getValue(model, '/resources/kubedbComSinglestore/spec/metadata/labels') -function setConfigurationFilesShard({ model, getValue }) { - const value = getValue(model, '/resources/secret_shard_config/data/mongod.conf') - return atob(value) -} + const agent = getValue(model, '/resources/kubedbComSinglestore/spec/monitor/agent') -function setConfigurationFilesConfigServer({ model, getValue }) { - const value = getValue(model, '/resources/secret_configserver_config/data/mongod.conf') - return atob(value) -} + if (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', + value: labels, + force: true, + }) + } + } -function setConfigurationFilesMongos({ model, getValue }) { - const value = getValue(model, '/resources/secret_mongos_config/data/mongod.conf') - return atob(value) -} + function onAgentChange() { + const agent = getValue(model, '/resources/kubedbComSinglestore/spec/monitor/agent') + if (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', + value: [], + force: true, + }) -function onSetCustomConfigChange({ discriminator, getValue, commit }) { - const value = getValue(discriminator, '/setCustomConfig') + onNamespaceChange() + onLabelChange() + } else { + commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') + } + } - if (value === 'no') { - commit('wizard/model$delete', '/resources/kubedbComSinglestore/spec/configSecret') - commit( - 'wizard/model$delete', - '/resources/kubedbComSinglestore/spec/shardTopology/shard/configSecret', - ) - commit( - 'wizard/model$delete', - '/resources/kubedbComSinglestore/spec/shardTopology/configServer/configSecret', - ) - commit( - 'wizard/model$delete', - '/resources/kubedbComSinglestore/spec/shardTopology/mongos/configSecret', + function onNamespaceChange() { + const namespace = getValue( + model, + '/resources/autoscalingKubedbComSinglestoreAutoscaler/metadata/namespace', ) - commit('wizard/model$delete', '/resources/secret_config') - commit('wizard/model$delete', '/resources/secret_shard_config') - commit('wizard/model$delete', '/resources/secret_configserver_config') - commit('wizard/model$delete', '/resources/secret_mongos_config') + if (!namespace) { + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/databaseRef/name', + ) + } } -} - -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + 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/singlestoreopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` + } + + function setValueFrom() { + if (isConfigMapTypeValueFrom()) { + return 'configMap' + } else if (isSecretTypeValueFrom()) { + return 'secret' + } else { + return 'input' + } } -} - -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} -function showScheduleBackup({ storeGet }) { - const operationQuery = storeGet('/route/params/actions') || '' - const isBackupOperation = operationQuery === 'edit-self-backupconfiguration' ? true : false - return !isBackupOperation -} + 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, + }) + } + } -///////////////////////// Autoscaler /////////////////// -let autoscaleType = '' -let dbDetails = {} + // function isEqualToValueFromType(value) { + // //watchDependency('discriminator#/valueFromType') + // const valueFrom = getValue(discriminator, '/valueFromType') + // return valueFrom === value + // } -function isConsole({ storeGet, commit }) { - const isKube = isKubedb({ storeGet }) + async function resourceNames(group, version, resource) { + const namespace = getValue(model, '/metadata/release/namespace') + // watchDependency('model#/metadata/release/namespace') - if (isKube) { - const dbName = storeGet('/route/params/name') || '' - commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComSinglestoreAutoscaler/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/autoscalingKubedbComSinglestoreAutoscaler/metadata/name', - value: modifiedName, - force: true, + let resources = await getNamespacedResourceList(axios, storeGet, { + namespace, + group, + version, + resource, }) - const namespace = storeGet('/route/query/namespace') || '' - if (namespace) { - commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComSinglestoreAutoscaler/metadata/namespace', - value: namespace, - force: true, + + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) }) } - } - - return !isKube -} -function isKubedb({ storeGet }) { - return !!storeGet('/route/params/actions') -} + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -function showOpsRequestOptions({ model, getValue, watchDependency, storeGet, discriminator }) { - if (isKubedb({ storeGet }) === true) return true - watchDependency( - 'model#/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/databaseRef/name', - ) - watchDependency('discriminator#/autoscalingType') - return ( - !!getValue( + 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/autoscalingKubedbComSinglestoreAutoscaler/spec/databaseRef/name', - ) && !!getValue(discriminator, '/autoscalingType') - ) -} - -async function getNamespaces({ axios, storeGet }) { - 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 } } } }, - }) + `/resources/kubedbComSinglestore/spec/monitor/prometheus/exporter/env/${index}/valueFrom/configMapKeyRef/name`, + ) - const resources = (resp && resp.data && resp.data.items) || [] + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/configMapKeyRef/name') - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + if (!configMapName) return [] -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - watchDependency('model#/resources/autoscalingKubedbComSinglestoreAutoscaler/metadata/namespace') - const namespace = getValue( - model, - '/resources/autoscalingKubedbComSinglestoreAutoscaler/metadata/namespace', - ) - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/configmaps/${configMapName}`, + ) - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/singlestores`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + const configMaps = (resp && resp.data && resp.data.data) || {} - const resources = (resp && resp.data && resp.data.items) || [] + const configMapKeys = Object.keys(configMaps).map((item) => ({ + text: item, + value: item, + })) - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, + 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') -async function getDbDetails({ commit, setDiscriminatorValue, axios, storeGet, getValue, model }) { - const owner = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - const namespace = - storeGet('/route/query/namespace') || - getValue(model, '/resources/autoscalingKubedbComSinglestoreAutoscaler/metadata/namespace') || - '' - const name = - storeGet('/route/params/name') || - getValue(model, '/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/databaseRef/name') || - '' - - if (namespace && name) { try { const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/singlestores/${name}`, + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }, ) - dbDetails = resp.data || {} - setDiscriminatorValue('/dbDetails', true) - } catch (e) { - console.log(e) - } - } - commit('wizard/model$update', { - path: `/metadata/release/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/metadata/release/namespace`, - value: namespace, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/databaseRef/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComSinglestoreAutoscaler/metadata/labels`, - value: dbDetails.metadata.labels, - force: true, - }) -} + const secrets = (resp && resp.data && resp.data.items) || [] -async function dbTypeEqualsTo({ axios, storeGet, watchDependency, model, getValue, commit }, type) { - watchDependency('discriminator#/dbDetails') + const filteredSecrets = secrets.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) - const { spec } = dbDetails || {} - const { topology } = spec || {} - let verd = '' - if (topology) verd = 'topology' - else { - verd = 'standalone' + 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 [] + } } - clearSpecModel({ commit }, verd) - return type === verd && spec -} -function clearSpecModel({ commit }, dbtype) { - if (dbtype === 'standalone') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/${autoscaleType}/cluster`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/${autoscaleType}/sentinel`, - ) - } else if (dbtype === 'cluster') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/${autoscaleType}/sentinel`, - ) - } else if (dbtype === 'sentinel') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/${autoscaleType}/standalone`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/${autoscaleType}/cluster`, + 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/kubedbComSinglestore/spec/monitor/prometheus/exporter/env/${index}/valueFrom/secretKeyRef/name`, ) - } -} -function initMetadata({ getValue, discriminator, model, commit, storeGet }) { - const dbName = - getValue(model, '/resources/autoscalingKubedbComSinglestoreAutoscaler/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/autoscalingKubedbComSinglestoreAutoscaler/metadata/name', - value: modifiedName, - force: true, - }) + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/secretKeyRef/name') - // delete the other type object from model - if (type === 'compute') - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/storage', - ) - if (type === 'storage') - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/compute', - ) -} + if (!secretName) return [] -function onNamespaceChange({ model, getValue, commit }) { - const namespace = getValue( - model, - '/resources/autoscalingKubedbComSinglestoreAutoscaler/metadata/namespace', - ) - if (!namespace) { - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/databaseRef/name', - ) - } -} + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets/${secretName}`, + ) -function ifScalingTypeEqualsTo( - { storeGet, watchDependency, getValue, discriminator, model }, - type, -) { - watchDependency('discriminator#/autoscalingType') - watchDependency( - 'model#/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/databaseRef/name', - ) + const secret = (resp && resp.data && resp.data.data) || {} - const operation = storeGet('/route/params/actions') || '' - if (operation.length) { - const splitOp = operation.split('-') - if (splitOp.length > 2) autoscaleType = splitOp[2] - } else autoscaleType = getValue(discriminator, '/autoscalingType') || '' - const isDatabaseSelected = !!getValue( - model, - '/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/databaseRef/name', - ) - return autoscaleType === type && isDatabaseSelected -} + const secretKeys = Object.keys(secret).map((item) => ({ + text: item, + value: item, + })) -async function fetchNodeTopology({ axios, storeGet }) { - 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 secretKeys + } catch (e) { + console.log(e) + return [] + } } - return [] -} - -function isNodeTopologySelected({ watchDependency, model, getValue }) { - watchDependency( - 'model#/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/compute/nodeTopology/name', - ) - const nodeTopologyName = - getValue( - model, - '/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/compute/nodeTopology/name', - ) || '' - return !!nodeTopologyName.length -} - -function setControlledResources({ commit }, type) { - const list = ['cpu', 'memory'] - const path = `/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/compute/${type}/controlledResources` - commit('wizard/model$update', { - path: path, - value: list, - force: true, - }) - return list -} -function setTrigger({ model, getValue }, path) { - let value = getValue(model, `/resources/${path}`) - if (value) return value - return 'On' -} + function returnFalse() { + return false + } -function setApplyToIfReady() { - return 'IfReady' -} + function isBindingAlreadyOn() { + const value = getValue(model, '/resources') + const keys = Object.keys(value) + const isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComSinglestoreBinding') + return isExposeBinding + } -function handleUnit({ commit, model, getValue }, 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, - }) + 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/kubedbComSinglestore/metadata/labels') + const bindingValues = { + apiVersion: 'catalog.appscode.com/v1alpha1', + kind: 'SinglestoreBinding', + metadata: { + labels, + name: dbName, + namespace: dbNamespace, + }, + spec: { + sourceRef: { + name: dbName, + namespace: dbNamespace, + }, + }, } - } else { - if (!isNaN(value)) { - value += 'Gi' + + if (value) { commit('wizard/model$update', { - path: `/resources/${path}`, - value: value, + path: '/resources/catalogAppscodeComSinglestoreBinding', + value: bindingValues, force: true, }) + } else { + commit('wizard/model$delete', '/resources/catalogAppscodeComSinglestoreBinding') } } -} - -function objectCopy(obj) { - const temp = JSON.stringify(obj) - return JSON.parse(temp) -} - -function isBindingAlreadyOn({ model, getValue }) { - const value = getValue(model, '/resources') - const keys = Object.keys(value) - isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComSinglestoreBinding') - return isExposeBinding -} -async function addOrRemoveBinding({ commit, model, getValue, discriminator }) { - const value = getValue(discriminator, `/binding`) - const dbName = getValue(model, '/metadata/release/name') - const dbNamespace = getValue(model, '/metadata/release/namespace') - const labels = getValue(model, '/resources/kubedbComSinglestore/metadata/labels') - const bindingValues = { - apiVersion: 'catalog.appscode.com/v1alpha1', - kind: 'SinglestoreBinding', - metadata: { - labels, - name: dbName, - namespace: dbNamespace, - }, - spec: { - sourceRef: { - name: dbName, - namespace: dbNamespace, - }, - }, + function setValueFromDbDetails(path) { + const value = getValue(model, path) + return value } - if (value) { - await commit('wizard/model$update', { - path: '/resources/catalogAppscodeComSinglestoreBinding', - value: bindingValues, - force: true, - }) - } else { - await commit('wizard/model$delete', '/resources/catalogAppscodeComSinglestoreBinding') - } -} + function onTriggerChange(type) { + const trigger = getValue(discriminator, `/${type}/trigger`) + const commitPath = `/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/${type}/trigger` -function setMetadata({ storeGet, mode, commit }) { - const dbname = storeGet('/route/params/name') || '' - const namespace = storeGet('/route/query/namespace') || '' - if (mode === 'standalone-step') { - commit('wizard/model$update', { - path: '/metadata/release/name', - value: dbname, - force: true, - }) commit('wizard/model$update', { - path: '/metadata/release/namespace', - value: namespace, + path: commitPath, + value: trigger ? 'On' : 'Off', force: true, }) } -} -function getOpsRequestUrl({ storeGet, model, getValue, mode }, 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 + `/create-opsrequest-${reqType.toLowerCase()}?namespace=${namespace}` - - if (mode === 'standalone-step') return pathConstructedForKubedb - else - return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/singlestoreopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=VerticalScaling` -} - -async function fetchTopologyMachines({ axios, getValue, storeGet, model, setDiscriminatorValue }) { - const instance = hasAnnotations({ model, getValue }) + async function fetchTopologyMachines() { + const annotations = getValue( + model, + '/resources/autoscalingKubedbComSinglestoreAutoscaler/metadata/annotations', + ) + const 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) + } catch (e) { + console.log(e) + setDiscriminatorValue('/topologyMachines', []) + } + } + } - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - if (instance) { + function setAllowedMachine(type, minmax) { + let parsedInstance = {} 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 + if (instance) parsedInstance = JSON.parse(instance) } catch (e) { console.log(e) - return [] + parsedInstance = {} } - } -} -function setAllowedMachine({ model, getValue }, type, minmax) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComSinglestoreAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - let parsedInstance = {} - try { - if (instance) parsedInstance = JSON.parse(instance) - } catch (e) { - console.log(e) - parsedInstance = {} + const machine = parsedInstance[type] || '' + const mx = machine?.includes(',') ? machine.split(',')[1] : '' + const mn = machine?.includes(',') ? machine.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: '', + } } - const machine = parsedInstance[type] || '' - const mx = machine?.includes(',') ? machine.split(',')[1] : '' - const mn = machine?.includes(',') ? machine.split(',')[0] : '' - - if (minmax === 'min') return mn - else return mx -} + function getMachines(type, minmax) { + const depends = minmax === 'min' ? 'max' : 'min' + const dependantPath = `/allowedMachine-${type}-${depends}` -async function getMachines({ getValue, watchDependency, discriminator }, type, minmax) { - watchDependency('discriminator#/topologyMachines') - const depends = minmax === 'min' ? 'max' : 'min' - const dependantPath = `/allowedMachine-${type}-${depends}` + const dependantMachineObj = getValue(discriminator, dependantPath) + const dependantMachine = dependantMachineObj?.machine || '' - watchDependency(`discriminator#${dependantPath}`) - const dependantMachine = getValue(discriminator, dependantPath) + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] - const nodeGroups = getValue(discriminator, '/topologyMachines') || [] + const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) - 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 machines = nodeGroups?.map((item) => { - const subText = `CPU: ${item.allocatable.cpu}, Memory: ${item.allocatable.memory}` - const text = item.topologyValue - return { text, subText, value: item.topologyValue } - }) + const filteredMachine = machines?.filter((item, ind) => + minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, + ) - const filteredMachine = machines?.filter((item, ind) => - minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, - ) + return dependantIndex === -1 ? machines : filteredMachine + } + + 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 + }) - return dependantIndex === -1 ? machines : filteredMachine -} + if (filteredEnv.length) + commit('wizard/model$update', { + path: '/resources/kubedbComSinglestore/spec/monitor/prometheus/exporter/env', + value: filteredEnv, + force: true, + }) + } -function hasAnnotations({ model, getValue }, type) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComSinglestoreAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] + function initEnvArray() { + const env = getValue( + model, + '/resources/kubedbComSinglestore/spec/monitor/prometheus/exporter/env', + ) - return !!instance -} + return env || [] + } -function hasNoAnnotations({ model, getValue }) { - return !hasAnnotations({ model, getValue }) -} + function isEqualToTemp(value, index) { + //watchDependency('discriminator#/valueFromType') + const valueFrom = getValue(discriminator, `/env/${index}/temp/valueFromType`) + return valueFrom === value + } -function onMachineChange({ model, getValue, discriminator, commit }, type) { - const annoPath = '/resources/autoscalingKubedbComSinglestoreAutoscaler/metadata/annotations' - const annotations = getValue(model, annoPath) - const instance = annotations['kubernetes.io/instance-type'] - let parsedInstance = {} - try { - if (instance) parsedInstance = JSON.parse(instance) - } catch (e) { - console.log(e) - parsedInstance = {} - } - - const minMachine = getValue(discriminator, `/allowedMachine-${type}-min`) - const maxMachine = getValue(discriminator, `/allowedMachine-${type}-max`) - const minMaxMachine = `${minMachine},${maxMachine}` - - parsedInstance[type] = minMaxMachine - const instanceString = JSON.stringify(parsedInstance) - annotations['kubernetes.io/instance-type'] = instanceString - - const machines = getValue(discriminator, `/topologyMachines`) || [] - const minMachineObj = machines.find((item) => item.topologyValue === minMachine) - const maxMachineObj = machines.find((item) => item.topologyValue === maxMachine) - const minMachineAllocatable = minMachineObj?.allocatable - const maxMachineAllocatable = maxMachineObj?.allocatable - const allowedPath = `/resources/autoscalingKubedbComSinglestoreAutoscaler/spec/compute/${type}` - - if (minMachine && maxMachine && instance !== instanceString) { - 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 initMonitoring() { + const env = + getValue(model, '/resources/kubedbComSinglestore/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 { - getOpsRequestUrl, - setMetadata, - handleUnit, - isConsole, - getNamespaces, - getDbs, - isKubedb, - getDbDetails, - dbTypeEqualsTo, - clearSpecModel, - initMetadata, - onNamespaceChange, - ifScalingTypeEqualsTo, - fetchNodeTopology, - isNodeTopologySelected, - setControlledResources, - setTrigger, - setApplyToIfReady, - showOpsRequestOptions, - setInitSchedule, - fetchNames, - fetchNamespaces, - isRancherManaged, - onInputChangeSchedule, - getDefaultSchedule, - getBlueprints, - ifUsagePolicy, - isBlueprintOption, - getDefault, - onInputChange, - showBackupOptions, - showScheduleBackup, - isVariantAvailable, - fetchJsons, - disableLableChecker, - isEqualToModelPathValue, - getResources, - isEqualToDiscriminatorPath, - setValueFromModel, - isNotShardModeSelected, - isShardModeSelected, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - returnTrue, - returnStringYes, - getMongoDbVersions, - showAuthPasswordField, - showAuthSecretField, - showNewSecretCreateField, - isNotStandaloneMode, - showCommonStorageClassAndSizeField, - setDatabaseMode, - getStorageClassNames, - setStorageClass, - deleteDatabaseModePath, - isEqualToDatabaseMode, - setApiGroup, - getIssuerRefsName, - hasIssuerRefName, - hasNoIssuerRefName, - setClusterAuthMode, - setSSLMode, - showTlsConfigureSection, - onTlsConfigureChange, - getAliasOptions, - showMonitoringSection, - onEnableMonitoringChange, - showCustomizeExporterSection, - onCustomizeExporterChange, - disableInitializationSection, - valueExists, - initPrePopulateDatabase, - onPrePopulateDatabaseChange, - initDataSource, - onDataSourceChange, - initVolumeType, - onVolumeTypeChange, - showInitializationForm, - showScriptOrStashForm, - showConfigMapOrSecretName, - initializeNamespace, - showRepositorySelectOrCreate, - onInitRepositoryChoiseChange, - initCustomizeRestoreJobRuntimeSettings, - initCustomizeRestoreJobRuntimeSettingsForBackup, - onCustomizeRestoreJobRuntimeSettingsChange, - onCustomizeRestoreJobRuntimeSettingsChangeForBackup, - showRuntimeForm, - getImagePullSecrets, - getBackupConfigsAndAnnotations, - deleteKubeDbComMongDbAnnotation, - addKubeDbComMongDbAnnotation, - initScheduleBackup, - initScheduleBackupForEdit, - onScheduleBackupChange, - showBackupForm, - initalizeTargetReferenceName, - setInitialRestoreSessionRepo, - initRepositoryChoise, - initRepositoryChoiseForEdit, - onRepositoryChoiseChange, - onRepositoryNameChange, - getMongoAnnotations, - initFromAnnotationValue, - onBackupBlueprintNameChange, - onBackupBlueprintScheduleChange, - initFromAnnotationKeyValue, - onTaskParametersChange, - isValueExistInModel, - onNamespaceChange, - onLabelChange, - onNameChange, - returnFalse, - onAgentChange, - getCreateAuthSecret, - showExistingSecretSection, - showPasswordSection, - setAuthSecretPassword, - onAuthSecretPasswordChange, - encodePassword, - decodePassword, - onCreateAuthSecretChange, - getSecrets, - isEqualToServiceMonitorType, - onConfigurationSourceChange, - onConfigurationChange, - setConfigurationSource, - setSecretConfigNamespace, - setConfigurationSourceShard, - setConfigurationSourceConfigServer, - setConfigurationSourceMongos, - isSchemaOf, - disableConfigSourceOption, - onConfigurationSourceMongosChange, - onConfigurationSourceShardChange, - onConfigurationSourceConfigServerChange, - transferConfigSecret, - onConfigSecretModelChange, - setConfiguration, - setConfigurationShard, - setConfigurationConfigServer, - setConfigurationMongos, - setConfigurationFiles, - setConfigurationFilesShard, - setConfigurationFilesConfigServer, - setConfigurationFilesMongos, - onSetCustomConfigChange, - getCreateNameSpaceUrl, - updateConfigServerStorageClass, - - initBackupData, - isBackupDataLoadedTrue, - setBackupType, - getTypes, - getNamespaceArray, - isBackupType, - getContext, - onContextChange, - getConfigList, - onConfigChange, - showPause, - showSchedule, - showConfigList, - setBlueprintSwitch, - onBlueprintChange, - setArchiverSwitch, - onArchiverChange, - onBackupTypeChange, - isBindingAlreadyOn, - addOrRemoveBinding, - getMachines, - setAllowedMachine, - hasAnnotations, - hasNoAnnotations, - fetchTopologyMachines, - onMachineChange, + 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, + + isConsole, + isKubedb, + showOpsRequestOptions, + getNamespaces, + getDbs, + getDbDetails, + initMetadata, + onNamespaceChange, + fetchNodeTopology, + isNodeTopologySelected, + setControlledResources, + setTrigger, + onTriggerChange, + setApplyToIfReady, + setMetadata, + isRancherManaged, + dbTypeEqualsTo, + onMachineChange, + handleUnit, + setValueFromDbDetails, + + getOpsRequestUrl, + isValueExistInModel, + onEnableMonitoringChange, + showMonitoringSection, + onAgentChange, + getResources, + isEqualToModelPathValue, + onCustomizeExporterChange, + showCustomizeExporterSection, + onLabelChange, + setValueFrom, + onValueFromChange, + resourceNames, + getConfigMapKeys, + getSecrets, + getSecretKeys, + isConfigMapTypeValueFrom, + isSecretTypeValueFrom, + getNamespacedResourceList, + returnFalse, + initMonitoring, + onEnvArrayChange, + initEnvArray, + isEqualToTemp, + + isBindingAlreadyOn, + addOrRemoveBinding, + setValueFromDbDetails, + hasAnnotations, + hasNoAnnotations, + fetchTopologyMachines, + setAllowedMachine, + getMachines, + } } diff --git a/charts/kubedbcom-solr-editor-options/ui/create-ui.yaml b/charts/kubedbcom-solr-editor-options/ui/create-ui.yaml index dfdbf7a545..0d7e59a860 100644 --- a/charts/kubedbcom-solr-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-solr-editor-options/ui/create-ui.yaml @@ -1,434 +1,498 @@ -steps: -- form: - discriminator: - bundleApiLoaded: - default: false - type: boolean - elements: - - computed: initBundle - if: returnFalse - type: label-element - - disableUnselect: true - fetch: getAdminOptions|databases/Solr/versions - if: isToggleOn|databases/Solr/versions - label: - text: labels.database.version - schema: - $ref: schema#/properties/spec/properties/admin/properties/databases/properties/Solr/properties/versions/properties/default - type: select - - computed: getDefault|databases/Solr/mode - fetch: getAdminOptions|databases/Solr/mode - hasDescription: true - if: isToggleOn|databases/Solr/mode - label: - text: labels.database.mode - schema: - $ref: schema#/properties/spec/properties/mode - type: radio - - elements: - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/replicas - type: input - if: isEqualToModelPathValue|[Replicaset]|/spec/mode - type: single-step-form - - elements: - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/topology/properties/overseer/properties/replicas - type: input - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/topology/properties/overseer/properties/persistence/properties/size - type: input - - elements: - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/topology/properties/overseer/properties/podResources/properties/machine +step: +- type: single-step-form + loader: initBundle + elements: + - if: + type: function + name: returnFalse + init: + type: func + value: initBundle + label: '' + type: label-element + - type: label-element + label: '' + subtitle: Select the Solr version you want to deploy on Kubernetes. The chosen version determines the Solr engine features, compatibility, and runtime behavior of your database. + - disableUnselect: true + loader: getAdminOptions|databases/Solr/versions + if: + type: function + name: isToggleOn|databases/Solr/versions + label: Database Version + schema: schema/properties/spec/properties/admin/properties/databases/properties/Solr/properties/versions/properties/default + type: select + - init: + type: func + value: getDefault|databases/Solr/mode + loader: getAdminOptions|databases/Solr/mode + isHorizontal: true + if: + type: function + name: isToggleOn|databases/Solr/mode + label: Database Mode + schema: schema/properties/spec/properties/mode + type: radio + - elements: + - label: Replica number + schema: schema/properties/spec/properties/replicas + type: input + if: + type: function + name: isEqualToModelPathValue|Replicaset|/spec/mode + type: block-layout + - elements: + - type: label-element + label: '' + subtitle: Overseer nodes coordinate cluster operations and manage shard assignments. Configure replicas, storage, and resource allocation for reliable cluster coordination. + - type: horizontal-layout + showLabels: true + elements: + - label: Replica number + schema: schema/properties/spec/properties/topology/properties/overseer/properties/replicas + type: input + - label: Storage Size + schema: schema/properties/spec/properties/topology/properties/overseer/properties/persistence/properties/size + type: input + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/topology/properties/overseer/properties/podResources/properties/machine type: select - - computed: setLimits|cpu|topology/overseer - disabled: isMachineNotCustom|topology/overseer - if: isMachineCustom|topology/overseer - label: - text: labels.cpu - onChange: setRequests|cpu|topology/overseer - schema: - $ref: schema#/properties/spec/properties/topology/properties/overseer/properties/podResources/properties/resources/properties/requests/properties/cpu + - init: + type: func + value: setLimits|cpu|topology/overseer + disable: isMachineNotCustom|topology/overseer + if: + type: function + name: isMachineCustom|topology/overseer + label: CPU + loader: setLimits|cpu|topology/overseer + watcher: + func: setRequests|cpu|topology/overseer + paths: + - schema/properties/spec/properties/topology/properties/overseer/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/topology/properties/overseer/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/overseer/properties/podResources/properties/resources/properties/requests/properties/cpu type: input - - computed: setLimits|memory|topology/overseer - disabled: isMachineNotCustom|topology/overseer - if: isMachineCustom|topology/overseer - label: - text: labels.memory - onChange: setRequests|memory|topology/overseer - schema: - $ref: schema#/properties/spec/properties/topology/properties/overseer/properties/podResources/properties/resources/properties/requests/properties/memory + - init: + type: func + value: setLimits|memory|topology/overseer + disable: isMachineNotCustom|topology/overseer + if: + type: function + name: isMachineCustom|topology/overseer + label: Memory + loader: setLimits|memory|topology/overseer + watcher: + func: setRequests|memory|topology/overseer + paths: + - schema/properties/spec/properties/topology/properties/overseer/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/topology/properties/overseer/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/overseer/properties/podResources/properties/resources/properties/requests/properties/memory type: input - type: single-step-form - if: isEqualToModelPathValue|[Topology]|/spec/mode - label: - text: Overseer - show_label: true - type: single-step-form - - elements: - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/topology/properties/data/properties/replicas - type: input - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/topology/properties/data/properties/persistence/properties/size - type: input - - elements: - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/topology/properties/data/properties/podResources/properties/machine + if: + type: function + name: isEqualToModelPathValue|Topology|/spec/mode + label: Overseer + showLabels: true + type: block-layout + - elements: + - type: label-element + label: '' + subtitle: Data nodes store and serve search documents. Configure replicas, storage, and resource allocation for optimal search performance and data persistence. + - type: horizontal-layout + showLabels: true + elements: + - label: Replica number + schema: schema/properties/spec/properties/topology/properties/data/properties/replicas + type: input + - label: Storage Size + schema: schema/properties/spec/properties/topology/properties/data/properties/persistence/properties/size + type: input + + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/topology/properties/data/properties/podResources/properties/machine type: select - - computed: setLimits|cpu|topology/data - disabled: isMachineNotCustom|topology/data - if: isMachineCustom|topology/data - label: - text: labels.cpu - onChange: setRequests|cpu|topology/data - schema: - $ref: schema#/properties/spec/properties/topology/properties/data/properties/podResources/properties/resources/properties/requests/properties/cpu + - init: + type: func + value: setLimits|cpu|topology/data + disable: isMachineNotCustom|topology/data + if: + type: function + name: isMachineCustom|topology/data + label: CPU + loader: setLimits|cpu|topology/data + watcher: + func: setRequests|cpu|topology/data + paths: + - schema/properties/spec/properties/topology/properties/data/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/topology/properties/data/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/data/properties/podResources/properties/resources/properties/requests/properties/cpu type: input - - computed: setLimits|memory|topology/data - disabled: isMachineNotCustom|topology/data - if: isMachineCustom|topology/data - label: - text: labels.memory - onChange: setRequests|memory|topology/data - schema: - $ref: schema#/properties/spec/properties/topology/properties/data/properties/podResources/properties/resources/properties/requests/properties/memory + - init: + type: func + value: setLimits|memory|topology/data + disable: isMachineNotCustom|topology/data + if: + type: function + name: isMachineCustom|topology/data + label: Memory + loader: setLimits|memory|topology/data + watcher: + func: setRequests|memory|topology/data + paths: + - schema/properties/spec/properties/topology/properties/data/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/topology/properties/data/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/data/properties/podResources/properties/resources/properties/requests/properties/memory type: input - type: single-step-form - if: isEqualToModelPathValue|[Topology]|/spec/mode - label: - text: Data - show_label: true - type: single-step-form - - elements: - - label: - text: labels.replicaset.number - schema: - $ref: schema#/properties/spec/properties/topology/properties/coordinator/properties/replicas - type: input - - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/topology/properties/coordinator/properties/persistence/properties/size - type: input - - elements: - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/topology/properties/coordinator/properties/podResources/properties/machine + if: + type: function + name: isEqualToModelPathValue|Topology|/spec/mode + label: Data + showLabels: true + type: block-layout + - elements: + - type: label-element + label: '' + subtitle: Coordinator nodes handle query routing and aggregation. Configure replicas, storage, and resource allocation for efficient query distribution and response coordination. + - type: horizontal-layout + showLabels: true + elements: + - label: Replica number + schema: schema/properties/spec/properties/topology/properties/coordinator/properties/replicas + type: input + customClass: mb-20 + - label: Storage Size + schema: schema/properties/spec/properties/topology/properties/coordinator/properties/persistence/properties/size + type: input + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/topology/properties/coordinator/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu|topology/coordinator + disable: isMachineNotCustom|topology/coordinator + if: + type: function + name: isMachineCustom|topology/coordinator + label: CPU + loader: setLimits|cpu|topology/coordinator + watcher: + func: setRequests|cpu|topology/coordinator + paths: + - schema/properties/spec/properties/topology/properties/coordinator/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/topology/properties/coordinator/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/coordinator/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory|topology/coordinator + disable: isMachineNotCustom|topology/coordinator + if: + type: function + name: isMachineCustom|topology/coordinator + label: Memory + loader: setLimits|memory|topology/coordinator + watcher: + func: setRequests|memory|topology/coordinator + paths: + - schema/properties/spec/properties/topology/properties/coordinator/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/topology/properties/coordinator/properties/podResources/properties/machine + schema: schema/properties/spec/properties/topology/properties/coordinator/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + if: + type: function + name: isEqualToModelPathValue|Topology|/spec/mode + label: Coordinator + showLabels: true + type: block-layout + - elements: + - type: label-element + label: '' + subtitle: Select a machine profile to allocate CPU and memory resources for your database. Choose 'custom' to manually specify resource requirements or select a predefined profile. + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/podResources/properties/machine type: select - - computed: setLimits|cpu|topology/coordinator - disabled: isMachineNotCustom|topology/coordinator - if: isMachineCustom|topology/coordinator - label: - text: labels.cpu - onChange: setRequests|cpu|topology/coordinator - schema: - $ref: schema#/properties/spec/properties/topology/properties/coordinator/properties/podResources/properties/resources/properties/requests/properties/cpu + - init: + type: func + value: setLimits|cpu + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: CPU + loader: setLimits|cpu + watcher: + func: setRequests|cpu + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: Memory + loader: setLimits|memory + watcher: + func: setRequests|memory + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory type: input - - computed: setLimits|memory|topology/coordinator - disabled: isMachineNotCustom|topology/coordinator - if: isMachineCustom|topology/coordinator - label: - text: labels.memory - onChange: setRequests|memory|topology/coordinator - schema: - $ref: schema#/properties/spec/properties/topology/properties/coordinator/properties/podResources/properties/resources/properties/requests/properties/memory + if: + type: function + name: isEqualToModelPathValue|Replicaset,Standalone|/spec/mode + label: Machine Profile + showLabels: true + type: block-layout + - elements: + - type: horizontal-layout + showLabels: true + elements: + - loader: getAdminOptions|storageClasses + if: + type: function + name: isToggleOn|storageClasses + label: Storage Class + schema: schema/properties/spec/properties/admin/properties/storageClasses/properties/default + type: select + - if: + type: function + name: showStorageSizeField + label: Storage Size + schema: schema/properties/spec/properties/persistence/properties/size type: input - type: single-step-form - if: isEqualToModelPathValue|[Topology]|/spec/mode - label: - text: Coordinator - show_label: true - type: single-step-form + if: + type: function + name: isEqualToModelPathValue|Replicaset,Standalone|/spec/mode + type: block-layout + - elements: + - loader: getAppBindings + label: Name + schema: schema/properties/spec/properties/zookeeperRef/properties/name + type: select + label: ZookeeperRef + showLabels: true + type: block-layout + - description: Configure Credentials, Deployment Mode etc. + elements: - elements: - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.cpu - onChange: setRequests|cpu - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.memory - onChange: setRequests|memory - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - if: isEqualToModelPathValue|[Replicaset, Standalone]|/spec/mode - label: - text: labels.machine_profile - show_label: true - type: single-step-form - - fetch: getAdminOptions|storageClasses - label: - text: labels.storage.class - schema: - $ref: schema#/properties/spec/properties/admin/properties/storageClasses/properties/default + - type: label-element + label: '' + subtitle: Add custom labels and annotations to your database resources for organization, monitoring, and integration with other Kubernetes tools and services. + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/annotations + hideBlock: true + label: Labels & Annotations + showLabels: true + type: block-layout + - init: + type: func + value: getDefault|deletionPolicy + customClass: mt-20 + if: + type: function + name: isToggleOn|deletionPolicy + label: Deletion Policy + watcher: + func: setStorageClass + paths: + - schema/properties/spec/properties/deletionPolicy + options: + - description: options.deletionPolicy.delete.description + text: Delete + value: Delete + - description: options.deletionPolicy.halt.description + text: Halt + value: Halt + - description: options.deletionPolicy.wipeOut.description + text: WipeOut + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: DoNotTerminate + value: DoNotTerminate + schema: schema/properties/spec/properties/deletionPolicy + type: select + - if: + type: function + name: getDefaultValue|spec/admin/authCredential/customize + label: Provide Authentication Credentials? + watcher: + func: onAuthChange + paths: + - temp/createAuthSecret + schema: temp/createAuthSecret + type: switch + - if: + type: function + name: showReferSecretSwitch + label: Refer existing Secret? + watcher: + func: onReferSecretChange + paths: + - temp/referSecret + schema: temp/referSecret + type: switch + - loader: getReferSecrets + if: + type: function + name: showSecretDropdown + label: Secret + schema: schema/properties/spec/properties/authSecret/properties/name type: select - - if: showStorageSizeField - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/persistence/properties/size + - if: + type: function + name: showReferSecret + label: Password + schema: schema/properties/spec/properties/authSecret/properties/password type: input + - if: + type: function + name: getDefaultValue|spec/admin/customConfiguration + label: Configure Database? + watcher: + func: clearConfiguration + paths: + - temp/configDatabase + schema: temp/configDatabase + type: switch + - if: + type: function + name: isConfigDatabaseOn + label: Configuration + schema: schema/properties/spec/properties/configuration + type: textarea + - if: + type: function + name: isToggleOn|deployment + label: Deployment Mode + options: + - description: For exploring databases when high-performance is not required. + text: Shared + value: Shared + - description: For production applications with sophisticated workload + text: Dedicated + value: Dedicated + schema: schema/properties/spec/properties/admin/properties/deployment/properties/default + type: radio + - if: + type: function + name: isToggleOn|clusterTier + isHorizontal: true + label: Cluster Tier + options: + - text: General Purpose + value: GeneralPurpose + - text: Memory Optimized + value: MemoryOptimized + - text: CPU Optimized + value: CPUOptimized + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/default + type: radio + - disableUnselect: true + loader: getAdminOptions|clusterTier/placement + if: + type: function + name: isToggleOn|clusterTier/placement + label: Placement Policy + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + type: select + - disableUnselect: true + loader: getNodeTopology + if: + type: function + name: isToggleOn|clusterTier/nodeTopology + label: Node Topology + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + type: select + hideBlock: true + label: Advanced Configuration + showLabels: true + type: block-layout + - description: Enable Backup, Monitoring, TLS etc. + elements: - elements: - - fetch: getAppBindings - label: - text: labels.zookeeperRef.name - schema: - $ref: schema#/properties/spec/properties/zookeeperRef/properties/name - type: select - label: - text: labels.zookeeperRef.label - schema: - $ref: schema#/properties/spec/properties/zookeeperRef - show_label: true - type: single-step-form - - accordion: true - description: - text: Configure Credentials, Deployment Mode etc. - discriminator: - configDatabase: - default: false - type: boolean - createAuthSecret: - default: false - type: boolean - referSecret: - default: false - type: boolean - elements: - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties - type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties - type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - computed: getDefault|deletionPolicy - customClass: mt-20 - if: isToggleOn|deletionPolicy - 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/spec/properties/deletionPolicy - type: select - - if: getDefaultValue|spec/admin/authCredential/customize - label: - text: Provide Authentication Credentials? - onChange: onAuthChange - schema: - $ref: discriminator#/createAuthSecret - type: switch - - if: showReferSecretSwitch - label: - text: Refer existing Secret? - onChange: onReferSecretChange - schema: - $ref: discriminator#/referSecret - type: switch - - fetch: getReferSecrets - if: showSecretDropdown - label: - text: Secret - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/name - type: select - - if: showReferSecret - label: - text: labels.password - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/password - type: input - - computed: isConfigAvailable - if: getDefaultValue|spec/admin/customConfiguration - label: - text: Configure Database? - onChange: clearConfiguration - schema: - $ref: discriminator#/configDatabase + - init: + type: func + value: setMonitoring + label: Enable Monitoring + watcher: + func: updateAlertValue + paths: + - temp/monitoring + schema: temp/monitoring type: switch - - if: isConfigDatabaseOn - label: - text: Configuration - schema: - $ref: schema#/properties/spec/properties/configuration - type: editor - - hasDescription: true - if: isToggleOn|deployment - label: - text: labels.deployment.name + - customClass: mt-10 + if: + type: function + name: showAlerts + label: Alert Options options: - - description: labels.deployment.shared - text: Shared - value: Shared - - description: labels.deployment.dedicated - text: Dedicated - value: Dedicated - schema: - $ref: schema#/properties/spec/properties/admin/properties/deployment/properties/default - type: radio - - if: isToggleOn|clusterTier - isHorizontal: true - label: - text: labels.clusterTier - options: - - text: General Purpose - value: GeneralPurpose - - text: Memory Optimized - value: MemoryOptimized - - text: CPU Optimized - value: CPUOptimized - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/default - type: radio - - disableUnselect: true - fetch: getAdminOptions|clusterTier/placement - if: isToggleOn|clusterTier/placement - label: - text: labels.placement - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default - type: select - - disableUnselect: true - fetch: getNodeTopology - if: isToggleOn|clusterTier/nodeTopology - label: - text: labels.nodeTopology - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + - text: None + value: none + - text: Critical + value: critical + - text: Warning + value: warning + - text: Info + value: info + schema: schema/properties/form/properties/alert/properties/enabled type: select - hideForm: true - label: - text: Advanced Configuration - show_label: true - type: single-step-form - - accordion: true - description: - text: Enable Backup, Monitoring, TLS etc. - elements: - - discriminator: - monitoring: - default: false - type: boolean - elements: - - computed: setMonitoring - label: - text: labels.enable_monitoring - onChange: updateAlertValue - schema: - $ref: discriminator#/monitoring - type: switch - - customClass: mt-10 - if: showAlerts - label: - text: labels.alert.options - options: - - text: None - value: none - - text: Critical - value: critical - - text: Warning - value: warning - - text: Info - value: info - schema: - $ref: schema#/properties/form/properties/alert/properties/enabled - sortable: true - type: select - if: isToggleOn|monitoring - type: single-step-form - - elements: - - label: - text: Expose via Gateway? - schema: - $ref: schema#/properties/spec/properties/admin/properties/expose/properties/default - type: switch - if: isToggleOn|expose - type: single-step-form - if: showAdditionalSettings - label: - text: Additional Options - show_label: true - type: single-step-form - type: single-step-form + if: + type: function + name: isToggleOn|monitoring + type: block-layout + - elements: + - label: Expose via Gateway? + schema: schema/properties/spec/properties/admin/properties/expose/properties/default + type: switch + if: + type: function + name: isToggleOn|expose + type: block-layout + if: + type: function + name: showAdditionalSettings + label: Additional Options + showLabels: true + type: block-layout id: options - title: steps.0.label type: multi-step-form diff --git a/charts/kubedbcom-solr-editor-options/ui/functions.js b/charts/kubedbcom-solr-editor-options/ui/functions.js index 88c295f076..8a634d91ab 100644 --- a/charts/kubedbcom-solr-editor-options/ui/functions.js +++ b/charts/kubedbcom-solr-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -319,1033 +321,873 @@ const modeDetails = { }, } -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return value.includes(modelPathValue) -} - -function showAuthSecretField({ discriminator, getValue, watchDependency }) { - return !showAuthPasswordField({ - discriminator, - getValue, - watchDependency, - }) -} - -function showStorageSizeField({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - const validType = ['Standalone', 'Replicaset'] - return validType.includes(modelPathValue) -} - -async function getResources({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, ) - const resources = (resp && resp.data && resp.data.items) || [] + setDiscriminatorValue('bundleApiLoaded', false) + setDiscriminatorValue('createAuthSecret', false) + setDiscriminatorValue('referSecret', false) + setDiscriminatorValue('configDatabase', false) + setDiscriminatorValue('monitoring', false) - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return resources -} - -async function getMongoDbVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function clearConfiguration() { + const configOn = getValue(discriminator, '/configDatabase') - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, - }, - }, + if (!configOn) { + commit('wizard/model$delete', '/spec/configuration') + } } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) + async function fetchJsons() { + let ui = {} + let language = {} + let functions = {} + const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart - const resources = (resp && resp.data && resp.data.items) || [] + 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) + } - // keep only non deprecated versions - const filteredMongoDbVersions = resources.filter((item) => item.spec && !item.spec.deprecated) + return { + ui: ui.data || {}, + language: language.data || {}, + functions, + } + } - filteredMongoDbVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredMongoDbVersions -} + function filterNodeTopology(list, tier, provider) { + // first filter the list from value that exists from the filtered list got from API + const filteredlist = list -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/spec/authSecret/name') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/spec/authSecret/password') + // filter the list based on clusterTier + if (provider === 'EKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('c') + else if (tier === 'MemoryOptimized') return item.startsWith('r') + else return !item.startsWith('c') && !item.startsWith('r') + }) + } else if (provider === 'AKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') + else if (tier === 'MemoryOptimized') + return ( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + else + return ( + !(item.startsWith('f') || item.startsWith('fx')) && + !( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + ) + }) + } else if (provider === 'GKE') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') + return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') + else if (tier === 'MemoryOptimized') + return ( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + else + return ( + !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && + !( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + ) + }) + } else return filteredlist } -} -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + function getCreateNameSpaceUrl() { + const user = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - const secrets = (resp && resp.data && resp.data.items) || [] + const domain = storeGet('/domain') || '' + if (domain.includes('bb.test')) { + return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } + } - const filteredSecrets = secrets.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) + function getDefault(type) { + const val = getValue(model, `/spec/admin/${type}/default`) || '' + return val + } - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return filteredSecrets -} + function getDefaultValue(path) { + const val = getValue(model, `/${path}`) || '' + return val + } -function getMachineListForOptions({ model, getValue }) { - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') let array = [] + function getMachineListForOptions() { + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') - if (available.length) { - array = available.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - else { - let subText = '', - text = '' - const machineData = machinesFromPreset.find((val) => val.id === machine) - if (machineData) { - subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` - text = machineData.name ? machineData.name : machineData.id - } - return { text, subText, value: machine } - } - }) - } else { - array = machineList - .map((machine) => { + if (available.length) { + array = available.map((machine) => { if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + else { + let subText = '', + text = '' + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + text = machineData.name ? machineData.name : machineData.id + } + return { text, subText, value: machine } + } }) - .filter((val) => !!val) - } - return array -} - -function setLimits({ model, getValue, commit, watchDependency }, resource, type) { - const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' - watchDependency(`model#${path}`) - const selectedMachine = getValue(model, path) || 'custom' - const reqCommitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - const comparePath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - - const resourceValue = getValue(model, comparePath) - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - - let cpu = '', - memory = '' - if (available.length && selectedMachine !== 'custom') { - const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) - if (machineData) { - cpu = machineData.limits.cpu - memory = machineData.limits.memory - } - } else { - if (selectedMachine === 'custom') { - cpu = resourceValue - memory = resourceValue } else { - cpu = machines[selectedMachine].resources.limits.cpu - memory = machines[selectedMachine].resources.limits.memory + array = machineList + .map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { text, subText, value: machine } + }) + .filter((val) => !!val) } + return array } - if (resource === 'memory') { - commit('wizard/model$update', { - path: reqCommitPath, - value: memory, - force: true, - }) - commit('wizard/model$update', { - path: comparePath, - value: memory, - force: true, - }) - return memory - } else { - commit('wizard/model$update', { - path: reqCommitPath, - value: cpu, - force: true, - }) - commit('wizard/model$update', { - path: comparePath, - value: cpu, - force: true, - }) - return cpu + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, + }, + ) + if (resp.data?.status?.projects) { + const projects = resp.data?.status?.projects + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } + } catch (e) { + console.log(e) + } + return [] } -} - -function setRequests({ getValue, model, commit }, resource, type) { - const modelPath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - const val = getValue(model, modelPath) - commitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - commit('wizard/model$update', { - path: commitPath, - value: val, - force: true, - }) -} -function setMachineToCustom({ getValue, model }) { - const machine = getValue(model, '/spec/admin/machineProfiles/default') - return machine || 'custom' -} + async function getReferSecrets() { + const referSecret = getValue(discriminator, '/referSecret') + if (!referSecret) { + return [] + } -async function fetchJsons({ axios, itemCtx }) { - let ui = {} - let language = {} - let functions = {} - const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/metadata/release/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - 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) + const options = [] + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + return options } - return { - ui: ui.data || {}, - language: language.data || {}, - functions, - } -} + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function updateAgentValue({ commit }, val) { - commit('wizard/model$update', { - path: '/spec/monitoring/agent', - value: val ? 'prometheus.io/operator' : '', - force: true, - }) - - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: val ? 'warning' : 'none', - force: true, - }) -} + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + const resources = (resp && resp.data && resp.data.items) || [] - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true + }) + return resources } -} - -const ifCapiProviderIsNotEmpty = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/provider') - const val = getValue(model, '/form/capi/provider') - if (val) return true -} - -const showMultiselectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') - - if (val === 'capz' && ifDedicated({ model, getValue })) return true -} -const showSelectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') - if (val !== 'capz' && ifDedicated({ model, getValue })) return true -} - -const ifDedicated = ({ model, getValue }) => { - const val = getValue(model, 'form/capi/dedicated') - if (val) return true -} - -const dedicatedOnChange = ({ model, getValue, commit }) => { - const val = getValue(model, 'form/capi/dedicated') - if (!val) { - commit('wizard/model$delete', 'form/capi/zones') - commit('wizard/model$delete', 'form/capi/sku') - } -} + 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') + + if (owner && cluster && namespace) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { + items: { + data: { username: null, password: null }, + metadata: { name: null }, + type: null, + }, + }, + }, + }, + ) -const ifZones = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/zones') - watchDependency('model#/form/capi/dedicated') - const zones = getValue(model, 'form/capi/zones') || [] - const isDedicated = getValue(model, 'form/capi/dedicated') - if (zones.length && isDedicated) return true -} + const secrets = (resp && resp.data && resp.data.items) || [] -const zonesOnChange = ({ model, getValue, commit }) => { - const zones = getValue(model, 'form/capi/zones') || [] - if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') -} + const filteredSecrets = secrets.filter((item) => { + const validType = [ + 'kubernetes.io/service-account-token', + 'Opaque', + 'kubernetes.io/basic-auth', + ] + return validType.includes(item.type) + }) -async function getZones({ storeGet, axios, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const isDedicated = getValue(model, 'form/capi/dedicated') - if (isDedicated) { - try { - const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) - const val = resp.data.map((item) => { - return { value: item, text: item } - }) - return val - } catch (e) { - console.log(e) - return [] + 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 getSKU({ storeGet, axios, model, getValue, watchDependency }) { - watchDependency('model#/form/capi/zones') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const zones = getValue(model, 'form/capi/zones') || [] - if (zones.length) { + let placement = [] + let versions = [] + let storageClass = [] + let clusterIssuers = [] + let nodetopologiesShared = [] + let nodetopologiesDedicated = [] + let features = [] + async function initBundle() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') + + let db = getValue(model, '/metadata/resource/kind') + db = db.toLowerCase() + let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` + const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` + try { - let url = `clustersv2/${owner}/${cluster}/vms?` - if (typeof zones === 'string') { - url += `zones=${encodeURIComponent(zones)}` - } else { - zones.forEach((item) => { - url += `zones=${encodeURIComponent(item)}&` + const resp = await axios.get(url) + features = resp.data.features || [] + placement = resp.data.placementpolicies || [] + versions = resp.data.versions || [] + storageClass = resp.data.storageclasses || [] + clusterIssuers = resp.data.clusterissuers || [] + nodetopologiesDedicated = resp.data.dedicated || [] + nodetopologiesShared = resp.data.shared || [] + + const response = await axios.get(annotationUrl) + const annotations = response.data?.metadata?.annotations || {} + const uidRange = annotations['openshift.io/sa.scc.uid-range'] + if (uidRange) { + const val = uidRange.split('/')[0] + commit('wizard/model$update', { + path: '/spec/openshift/securityContext/runAsUser', + value: val, + force: true, }) - url = url.slice(0, -1) } - const resp = await axios.get(url) - const val = resp.data.map((item) => { - return { - value: item.name, - text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, - } - }) - return val } catch (e) { console.log(e) - return [] } - } -} - -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} -function setStorageClass({ model, getValue, commit, watchDependency, discriminator }) { - const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' - let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' - const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] - const suffix = '-retain' - - const simpleClassList = storageClassList.filter((item) => { - return !item.endsWith(suffix) - }) - const retainClassList = storageClassList.filter((item) => { - return item.endsWith(suffix) - }) - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] - } else { - storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] - } - - const isChangeable = isToggleOn( - { getValue, model, watchDependency, discriminator }, - 'storageClasses', - ) - if (isChangeable && storageClass) { commit('wizard/model$update', { - path: '/spec/admin/storageClasses/default', - value: storageClass, + path: '/spec/deletionPolicy', + value: getDefault('deletionPolicy'), force: true, }) - } -} -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], - }, - }, - ) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] + if (!getValue(model, `/spec/admin/databases/Solr/mode/toggle`)) { + let defMode = getDefault('databases/Solr/mode') || '' + if (defMode === '') { + const arr = getValue(model, '/spec/databases/Solr/mode/available') || [] + if (arr.length) defMode = arr[0] + } + commit('wizard/model$update', { + path: '/spec/mode', + value: defMode, + force: true, + }) } - } catch (e) { - console.log(e) - } - return [] -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} - -let placement = [] -let versions = [] -let storageClass = [] -let clusterIssuers = [] -let nodetopologiesShared = [] -let nodetopologiesDedicated = [] -let features = [] -async function initBundle({ commit, model, getValue, axios, storeGet, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - - let db = getValue(model, '/metadata/resource/kind') - db = db.toLowerCase() - let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` - const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - - try { - const resp = await axios.get(url) - features = resp.data.features || [] - placement = resp.data.placementpolicies || [] - versions = resp.data.versions || [] - storageClass = resp.data.storageclasses || [] - clusterIssuers = resp.data.clusterissuers || [] - nodetopologiesDedicated = resp.data.dedicated || [] - nodetopologiesShared = resp.data.shared || [] - - const response = await axios.get(annotationUrl) - const annotations = response.data?.metadata?.annotations || {} - const uidRange = annotations['openshift.io/sa.scc.uid-range'] - if (uidRange) { - const val = uidRange.split('/')[0] + if (!features.includes('tls')) { commit('wizard/model$update', { - path: '/spec/openshift/securityContext/runAsUser', - value: val, + path: '/spec/admin/tls/default', + value: false, force: true, }) } - } catch (e) { - console.log(e) + if (!features.includes('binding')) { + commit('wizard/model$update', { + path: '/spec/admin/expose/default', + value: false, + force: true, + }) + } + if (!features.includes('monitoring')) { + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: 'none', + force: true, + }) + } + if (!features.includes('backup')) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: '', + force: true, + }) + } + + setDiscriminatorValue('/bundleApiLoaded', true) } - commit('wizard/model$update', { - path: '/spec/deletionPolicy', - value: getDefault({ getValue, model }, 'deletionPolicy'), - force: true, - }) - - if (!getValue(model, `/spec/admin/databases/Solr/mode/toggle`)) { - let defMode = getDefault({ getValue, model }, 'databases/Solr/mode') || '' - if (defMode === '') { - const arr = getValue(model, '/spec/databases/Solr/mode/available') || [] - if (arr.length) defMode = arr[0] - } - commit('wizard/model$update', { - path: '/spec/mode', - value: defMode, - force: true, - }) + function isConfigDatabaseOn() { + // watchDependency('discriminator#/configDatabase') + return getValue(discriminator, '/configDatabase') } - if (!features.includes('tls')) { - commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: false, - force: true, - }) + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return value.split(',').includes(modelPathValue) } - if (!features.includes('binding')) { - commit('wizard/model$update', { - path: '/spec/admin/expose/default', - value: false, - force: true, - }) + + function isMachineCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue === 'custom' } - if (!features.includes('monitoring')) { - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: 'none', - force: true, - }) + + function isMachineNotCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue !== 'custom' && !!modelPathValue } - if (!features.includes('backup')) { + + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } + + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false + } + + function onAuthChange() { commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, + path: '/spec/authSecret/name', + value: '', force: true, }) commit('wizard/model$update', { - path: '/spec/backup/tool', + path: '/spec/authSecret/password', value: '', force: true, }) } - setDiscriminatorValue('/bundleApiLoaded', true) -} - -function fetchOptions({ model, getValue, commit }, type) { - let kind = getValue(model, '/metadata/resource/kind') - - let returnArray = [] - if (type === 'clusterTier/placement') { - returnArray = placement - } else if (type === `databases/${kind}/versions`) { - returnArray = versions - } else if (type === 'storageClasses') { - returnArray = storageClass - } else if (type === 'clusterIssuers') { - returnArray = clusterIssuers - } - - if (returnArray.length === 1) { - const path = `/spec/admin/${type}/default` + function onReferSecretChange() { commit('wizard/model$update', { - path: path, - value: returnArray[0], + path: '/spec/authSecret/name', + value: '', force: true, }) } - return returnArray -} - -function getAdminOptions({ getValue, model, watchDependency, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') - - const options = getValue(model, `/spec/admin/${type}/available`) || [] - - if (options.length === 0) { - return fetchOptions({ model, getValue, commit }, type) + function returnFalse() { + return false } - if (type.endsWith('/mode')) { - return ( - options?.map((item) => ({ - description: modeDetails[item]?.description || '', - text: modeDetails[item]?.text || '', - value: item, - })) || [] - ) - } - return options -} -function checkIfFeatureOn({ getValue, model }, type) { - let val = getValue(model, `/spec/admin/${type}/toggle`) - if (type === 'backup' || type === 'archiver') { - val = getValue(model, `/spec/admin/${type}/enable/toggle`) - } - const backupVal = getValue(model, '/spec/backup/tool') - - if (type === 'backup') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } else if (type === 'tls') { - return features.includes('tls') && val - } else if (type === 'expose') { - return features.includes('binding') && val - } else if (type === 'monitoring') { - return features.includes('monitoring') && val - } else if (type === 'archiver') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } -} + function setLimits(resource, type) { + const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' + // watchDependency(`model#${path}`) + const selectedMachine = getValue(model, path) || 'custom' + const reqCommitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + const comparePath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + + const resourceValue = getValue(model, comparePath) + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + let cpu = '', + memory = '' + if (available.length && selectedMachine !== 'custom') { + const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) + if (machineData) { + cpu = machineData.limits.cpu + memory = machineData.limits.memory + } + } else { + if (selectedMachine === 'custom') { + cpu = resourceValue + memory = resourceValue + } else { + cpu = machines[selectedMachine].resources.limits.cpu + memory = machines[selectedMachine].resources.limits.memory + } + } -function isToggleOn({ getValue, model, discriminator, watchDependency }, type) { - watchDependency('discriminator#/bundleApiLoaded') - watchDependency('model#/spec/admin/deployment/default') - const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') - let deploymentType = getValue(model, `/spec/admin/deployment/default`) - if ( - type === 'tls' || - type === 'backup' || - type === 'expose' || - type === 'monitoring' || - type === 'archiver' - ) { - return checkIfFeatureOn({ getValue, model }, type) - } else if ( - type === 'clusterTier' || - type === 'clusterTier/placement' || - type === 'clusterTier/nodeTopology' - ) { - if (deploymentType === 'Dedicated' && bundleApiLoaded) return true - else return false - } else if (type === 'deployment') { - const deploymentType = getValue(model, '/spec/admin/deployment/default') - if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + if (resource === 'memory') { + commit('wizard/model$update', { + path: reqCommitPath, + value: memory, + force: true, + }) commit('wizard/model$update', { - path: '/spec/admin/deployment/default', - value: 'Shared', + path: comparePath, + value: memory, force: true, }) + return memory + } else { + commit('wizard/model$update', { + path: reqCommitPath, + value: cpu, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: cpu, + force: true, + }) + return cpu } - return ( - getValue(model, `/spec/admin/${type}/toggle`) && - nodetopologiesDedicated.length && - bundleApiLoaded - ) - } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded -} - -async function getNodeTopology({ model, getValue, axios, storeGet, watchDependency }) { - watchDependency('model#/spec/admin/deployment/default') - watchDependency('model#/spec/admin/clusterTier/default') - const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' - const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' - let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + } - const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + function setMachineToCustom() { + const machine = getValue(model, '/spec/admin/machineProfiles/default') + return machine || 'custom' + } - if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared - else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + function setMonitoring() { + const agent = getValue(model, '/spec/admin/monitoring/agent') || '' + return !!agent + } - const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) - return filteredList -} + function setRequests(resource, type) { + const modelPath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` -function filterNodeTopology(list, tier, provider) { - // first filter the list from value that exists from the filtered list got from API - const filteredlist = list + const fullpath = `/spec/podResources/machine` + const modelPathValue = getValue(model, fullpath) - // filter the list based on clusterTier - if (provider === 'EKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('c') - else if (tier === 'MemoryOptimized') return item.startsWith('r') - else return !item.startsWith('c') && !item.startsWith('r') + commit('wizard/model$update', { + path: commitPath, + value: val, + force: true, }) - } else if (provider === 'AKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - else - return ( - !(item.startsWith('f') || item.startsWith('fx')) && - !( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - ) + + if (modelPathValue === 'custom') { + return + } + let commitCpuMemory, ModelPathValue + if (resource && type) { + const fullPath = `/spec/${type}/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/${type}/podResources/resources/requests/${resource}` + } else { + const fullPath = `/spec/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/podResources/resources/requests/${resource}` + } + let cpuMemoryValue + array.forEach((item) => { + if (item.value === ModelPathValue) { + // Parse subText like "CPU: 2, Memory: 2Gi" + const subText = item.subText || '' + if (resource === 'cpu') { + // Extract CPU value + const cpuMatch = subText.match(/CPU:\s*([^,]+)/) + cpuMemoryValue = cpuMatch ? cpuMatch[1].trim() : '' + } else if (resource === 'memory') { + // Extract Memory value + const memoryMatch = subText.match(/Memory:\s*(.+)/) + cpuMemoryValue = memoryMatch ? memoryMatch[1].trim() : '' + } + } }) - } else if (provider === 'GKE') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') - return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - else - return ( - !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && - !( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - ) + commit('wizard/model$update', { + path: commitCpuMemory, + value: cpuMemoryValue, + force: true, }) - } else return filteredlist -} + return cpuMemoryValue + } -function returnFalse() { - return false -} + function setStorageClass() { + const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' + let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' + const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] + const suffix = '-retain' -function isMachineCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue === 'custom' -} - -function isMachineNotCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue !== 'custom' && !!modelPathValue -} - -function onAuthChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/authSecret/password', - value: '', - force: true, - }) -} + const simpleClassList = storageClassList.filter((item) => { + return !item.endsWith(suffix) + }) + const retainClassList = storageClassList.filter((item) => { + return item.endsWith(suffix) + }) + if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { + storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] + } else { + storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + } -function clearConfiguration({ discriminator, getValue, commit }) { - const configOn = getValue(discriminator, '/configDatabase') + const isChangeable = isToggleOn('storageClasses') + if (isChangeable && storageClass) { + commit('wizard/model$update', { + path: '/spec/admin/storageClasses/default', + value: storageClass, + force: true, + }) + } + } - if (!configOn) { - commit('wizard/model$delete', '/spec/configuration') + function showAdditionalSettings() { + // watchDependency('discriminator#/bundleApiLoaded') + return features.length } -} -function isConfigDatabaseOn({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configDatabase') - return getValue(discriminator, '/configDatabase') -} + function showAlerts() { + // watchDependency('discriminator#/monitoring') + const isMonitorEnabled = getValue(discriminator, '/monitoring') + return isMonitorEnabled && isToggleOn('alert') + } -function showIssuer({ model, getValue, watchDependency, discriminator }) { - watchDependency('model#/spec/admin/tls/default') - const isTlsEnabled = getValue(model, '/spec/admin/tls/default') - const isIssuerToggleEnabled = isToggleOn( - { getValue, model, watchDependency, discriminator }, - 'clusterIssuers', - ) - return isTlsEnabled && isIssuerToggleEnabled -} + function showReferSecret() { + const modelPathValue = getValue(discriminator, '/createAuthSecret') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue + } -function setMonitoring({ getValue, model }) { - const agent = getValue(model, '/spec/admin/monitoring/agent') || '' - return !!agent -} + function showReferSecretSwitch() { + const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue && showReferSecret() + } -function updateAlertValue({ commit, model, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const alert = isMonitorEnabled ? 'warning' : 'none' - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: alert, - force: true, - }) - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} + function showSecretDropdown() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !!modelPathValue && showReferSecret() + } -function showAlerts({ watchDependency, model, getValue, discriminator }) { - watchDependency('discriminator#/monitoring') - const isMonitorEnabled = getValue(discriminator, '/monitoring') - return ( - isMonitorEnabled && isToggleOn({ getValue, model, watchDependency, discriminator }, 'alert') - ) -} + function showStorageSizeField() { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + const validType = ['Standalone', 'Replicaset'] + return validType.includes(modelPathValue) + } -function onBackupSwitch({ discriminator, getValue, commit }) { - const isBackupOn = getValue(discriminator, '/backup') - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: isBackupOn ? 'KubeStash' : '', - force: true, - }) -} + function updateAlertValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const alert = isMonitorEnabled ? 'warning' : 'none' + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: alert, + force: true, + }) + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: agent, + force: true, + }) + } -function setBackup({ model, getValue }) { - const backup = getValue(model, '/spec/backup/tool') - const val = getValue(model, '/spec/admin/backup/enable/default') - return backup === 'KubeStash' && features.includes('backup') && val -} + function fetchOptions(type) { + let kind = getValue(model, '/metadata/resource/kind') + + let returnArray = [] + if (type === 'clusterTier/placement') { + returnArray = placement + } else if (type === `databases/${kind}/versions`) { + returnArray = versions + } else if (type === 'storageClasses') { + returnArray = storageClass + } else if (type === 'clusterIssuers') { + returnArray = clusterIssuers + } -async function getAppBindings({ commit, axios, storeGet, model, getValue }) { - const namespace = getValue(model, '/metadata/release/namespace') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + if (returnArray.length === 1) { + const path = `/spec/admin/${type}/default` + commit('wizard/model$update', { + path: path, + value: returnArray[0], + force: true, + }) + } - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { type: null }, - }, - }, + return returnArray } - setNamespace({ commit, model, getValue }) - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/appcatalog.appscode.com/v1alpha1/appbindings`, - { - params: queryParams, - }, - ) - const resources = (resp && resp.data && resp.data.items) || [] + function getAdminOptions(type) { + // watchDependency('discriminator#/bundleApiLoaded') - const fileredResources = resources - .filter((item) => item.spec?.type === 'kubedb.com/zookeeper') - .map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: `${namespace}/${name}`, - value: name, - } - }) - return fileredResources - } catch (e) { - console.log(e) - return [] - } -} + const options = getValue(model, `/spec/admin/${type}/available`) || [] -function setNamespace({ commit, model, getValue }) { - let modelPathValue = getValue(model, '/metadata/release/namespace') - if (modelPathValue) { - commit('wizard/model$update', { - path: '/spec/zookeeperRef/namespace', - value: modelPathValue, - force: true, - }) + if (options.length === 0) { + return fetchOptions(type) + } + if (type.endsWith('/mode')) { + return ( + options?.map((item) => ({ + description: modeDetails[item]?.description || '', + text: modeDetails[item]?.text || '', + value: item, + })) || [] + ) + } + return options } -} -function showAdditionalSettings({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return features.length -} + async function getNodeTopology() { + // watchDependency('model#/spec/admin/deployment/default') + // watchDependency('model#/spec/admin/clusterTier/default') + const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' + const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' + let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] -function getDefault({ getValue, model }, type) { - const val = getValue(model, `/spec/admin/${type}/default`) || '' - return val -} + const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' -function isConfigAvailable({ getValue, model }) { - const val = getValue(model, '/spec/configuration') - return val !== '' -} + if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared + else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated -async function getReferSecrets({ getValue, model, storeGet, axios, discriminator }) { - const referSecret = getValue(discriminator, '/referSecret') - if (!referSecret) { - return [] + const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) + return filteredList } - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/metadata/release/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - - const options = [] - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) - } catch (e) { - console.log(e) + function checkIfFeatureOn(type) { + let val = getValue(model, `/spec/admin/${type}/toggle`) + if (type === 'backup' || type === 'archiver') { + val = getValue(model, `/spec/admin/${type}/enable/toggle`) + } + const backupVal = getValue(model, '/spec/backup/tool') + + if (type === 'backup') { + return features.includes('backup') && backupVal === 'KubeStash' && val + } else if (type === 'tls') { + return features.includes('tls') && val + } else if (type === 'expose') { + return features.includes('binding') && val + } else if (type === 'monitoring') { + return features.includes('monitoring') && val + } else if (type === 'archiver') { + return features.includes('backup') && val + } } - return options -} - -function showAuthPasswordField({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} -function showSecretDropdown({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function isToggleOn(type) { + // watchDependency('discriminator#/bundleApiLoaded') + // watchDependency('model#/spec/admin/deployment/default') + const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') + let deploymentType = getValue(model, `/spec/admin/deployment/default`) + if ( + type === 'tls' || + type === 'backup' || + type === 'expose' || + type === 'monitoring' || + type === 'archiver' + ) { + return checkIfFeatureOn(type) + } else if ( + type === 'clusterTier' || + type === 'clusterTier/placement' || + type === 'clusterTier/nodeTopology' + ) { + if (deploymentType === 'Dedicated' && bundleApiLoaded) return true + else return false + } else if (type === 'deployment') { + const deploymentType = getValue(model, '/spec/admin/deployment/default') + if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + commit('wizard/model$update', { + path: '/spec/admin/deployment/default', + value: 'Shared', + force: true, + }) + } + return ( + getValue(model, `/spec/admin/${type}/toggle`) && + nodetopologiesDedicated.length && + bundleApiLoaded + ) + } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded + } -function showReferSecret({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/createAuthSecret') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue -} + async function getAppBindings() { + const namespace = getValue(model, '/metadata/release/namespace') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function getDefaultValue({ getValue, model }, path) { - const val = getValue(model, `/${path}`) || '' - return val -} - -function showReferSecretSwitch({ model, getValue, watchDependency, discriminator }) { - const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + const queryParams = { + filter: { + items: { + metadata: { name: null }, + spec: { type: null }, + }, + }, + } -function onReferSecretChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) -} + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/appcatalog.appscode.com/v1alpha1/appbindings`, + { + params: queryParams, + }, + ) + + const resources = (resp && resp.data && resp.data.items) || [] + + const filteredResources = resources + .filter((item) => item.spec?.type === 'kubedb.com/zookeeper') + .map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: `${namespace}/${name}`, + value: name, + } + }) + return filteredResources + } catch (e) { + console.log(e) + return [] + } + } -return { - showReferSecretSwitch, - onReferSecretChange, - getDefaultValue, - isRancherManaged, - showSecretDropdown, - showReferSecret, - getReferSecrets, - isConfigAvailable, - initBundle, - returnFalse, - setLimits, - setRequests, - setNamespace, - getAppBindings, - isVariantAvailable, - fetchJsons, - showAuthPasswordField, - isEqualToModelPathValue, - showAuthSecretField, - showStorageSizeField, - getResources, - getMongoDbVersions, - onCreateAuthSecretChange, - getSecrets, - getMachineListForOptions, - setMachineToCustom, - updateAgentValue, - getCreateNameSpaceUrl, - ifCapiProviderIsNotEmpty, - ifDedicated, - dedicatedOnChange, - ifZones, - zonesOnChange, - getZones, - getSKU, - showMultiselectZone, - showSelectZone, - setStorageClass, - getNamespaces, - isToggleOn, - getAdminOptions, - getNodeTopology, - filterNodeTopology, - isMachineNotCustom, - isMachineCustom, - onAuthChange, - clearConfiguration, - isConfigDatabaseOn, - showIssuer, - setMonitoring, - updateAlertValue, - showAlerts, - onBackupSwitch, - setBackup, - getDefault, - showAdditionalSettings, + return { + clearConfiguration, + fetchJsons, + filterNodeTopology, + getCreateNameSpaceUrl, + getDefault, + getDefaultValue, + getMachineListForOptions, + getNamespaces, + getReferSecrets, + getResources, + getSecrets, + initBundle, + isConfigDatabaseOn, + isEqualToModelPathValue, + isMachineCustom, + isMachineNotCustom, + isRancherManaged, + isVariantAvailable, + onAuthChange, + onReferSecretChange, + returnFalse, + setLimits, + setMachineToCustom, + setMonitoring, + setRequests, + setStorageClass, + showAdditionalSettings, + showAlerts, + showReferSecret, + showReferSecretSwitch, + showSecretDropdown, + showStorageSizeField, + updateAlertValue, + fetchOptions, + getAdminOptions, + getNodeTopology, + checkIfFeatureOn, + isToggleOn, + getAppBindings, + } } diff --git a/charts/kubedbcom-solr-editor/ui/edit-ui.yaml b/charts/kubedbcom-solr-editor/ui/edit-ui.yaml index 55748cbdca..424799e954 100644 --- a/charts/kubedbcom-solr-editor/ui/edit-ui.yaml +++ b/charts/kubedbcom-solr-editor/ui/edit-ui.yaml @@ -1,1160 +1,974 @@ -steps: -- form: - discriminator: - dbDetails: - default: false - type: boolean +type: multi-step-form +step: + - type: single-step-form + id: storage-autoscaler + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: SelectDb - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: SelectType - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - elements: - - discriminator: - topologyMachines: - default: [] - type: array + - type: block-layout + if: + type: function + name: isConsole elements: - - fetch: fetchTopologyMachines - if: returnFalse - schema: - $ref: discriminator#/topologyMachines - type: input - - elements: - - computed: setTrigger|autoscalingKubedbComSolrAutoscaler/spec/compute/coordinator/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/coordinator/properties/trigger - type: select - - label: - text: PodLifeTimeThreshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/coordinator/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/coordinator/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-coordinator-max: - type: string - allowedMachine-coordinator-min: - type: string - elements: - - computed: setAllowedMachine|coordinator|min - disableUnselect: true - fetch: getMachines|coordinator|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|coordinator - schema: - $ref: discriminator#/properties/allowedMachine-coordinator-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/coordinator/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/coordinator/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/coordinator/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|coordinator|max - disableUnselect: true - fetch: getMachines|coordinator|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|coordinator - schema: - $ref: discriminator#/properties/allowedMachine-coordinator-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/coordinator/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/coordinator/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/coordinator/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|coordinator - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/coordinator/properties/controlledResources - type: multiselect - if: isTopology - label: - text: Coordinator - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/coordinator - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComSolrAutoscaler/spec/compute/data/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/data/properties/trigger - type: select - - label: - text: PodLifeTimeThreshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/data/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/data/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-data-max: - type: string - allowedMachine-data-min: - type: string + - type: input + label: Name + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/metadata/properties/name + - type: select + label: Select Namespace + loader: getNamespaces + if: + type: function + name: isRancherManaged + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/metadata/properties/namespace + - type: select + label: Select Db + loader: getDbs + validation: + type: required + refresh: true + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/databaseRef/properties/name + watcher: + func: initMetadata + paths: + - schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/databaseRef/properties/name + + - type: radio + if: + type: function + name: isConsole + label: Select Type + validation: + type: required + schema: temp/properties/autoscalingType + watcher: + func: initMetadata + paths: + - temp/properties/autoscalingType + options: + - text: Compute + value: compute + description: Scale your CPU Memory based on resource usage + - text: Storage + value: storage + description: Expand your database size based on volume usage + + - type: block-layout + showLabels: false + elements: + # Storage sections for different node types + - type: block-layout + showLabels: false elements: - - computed: setAllowedMachine|data|min - disableUnselect: true - fetch: getMachines|data|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|data - schema: - $ref: discriminator#/properties/allowedMachine-data-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/data/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/data/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/data/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|data|max - disableUnselect: true - fetch: getMachines|data|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|data - schema: - $ref: discriminator#/properties/allowedMachine-data-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/data/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/data/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/data/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|data - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/data/properties/controlledResources - type: multiselect - if: isTopology - label: - text: Data - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/data - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComSolrAutoscaler/spec/compute/node/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/node/properties/trigger - type: select - - label: - text: PodLifeTimeThreshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/node/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/node/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-node-max: - type: string - allowedMachine-node-min: - type: string + # Coordinator - Topology Mode + - type: switch + label: Trigger + fullwidth: true + if: + type: function + name: isTopology + init: + type: func + value: setTrigger|autoscalingKubedbComSolrAutoscaler/spec/storage/coordinator/trigger + schema: temp/properties/storage/properties/coordinator/properties/trigger + watcher: + func: onTriggerChange|storage/coordinator + paths: + - temp/properties/storage/properties/coordinator/properties/trigger + - type: label-element + 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. + if: + type: function + name: isTopology + - type: select + label: Mode + description: Select how the storage expansion should be handled. + if: + type: function + name: isTopology + options: + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/coordinator/properties/expansionMode + - type: block-layout + label: Coordinator + showLabels: true + if: + type: function + name: isTopology + # schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/coordinator + elements: + - type: threshold-input + label: Usage Threshold (%) + subtitle: Set the threshold percentage of storage usage to trigger scaling. + customClass: width-300 + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/coordinator/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/coordinator/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComSolr/spec/topology/coordinator/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComSolrAutoscaler/spec/storage/coordinator/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/coordinator/properties/scalingRules + - type: input + label: Upper Bound + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/coordinator/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComSolrAutoscaler/spec/storage/coordinator/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/coordinator/properties/upperBound + + # Data - Topology Mode + - type: switch + label: Trigger + fullwidth: true + if: + type: function + name: isTopology + init: + type: func + value: setTrigger|autoscalingKubedbComSolrAutoscaler/spec/storage/data/trigger + schema: temp/properties/storage/properties/data/properties/trigger + watcher: + func: onTriggerChange|storage/data + paths: + - temp/properties/storage/properties/data/properties/trigger + - type: label-element + 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. + if: + type: function + name: isTopology + - type: select + label: Mode + description: Select how the storage expansion should be handled. + if: + type: function + name: isTopology + options: + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/data/properties/expansionMode + - type: block-layout + label: Data + showLabels: true + if: + type: function + name: isTopology + # schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/data + elements: + - type: threshold-input + label: Usage Threshold (%) + subtitle: Set the threshold percentage of storage usage to trigger scaling. + customClass: width-300 + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/data/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/data/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComSolr/spec/topology/data/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComSolrAutoscaler/spec/storage/data/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/data/properties/scalingRules + - type: input + label: Upper Bound + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/data/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComSolrAutoscaler/spec/storage/data/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/data/properties/upperBound + + # Overseer - Topology Mode + - type: switch + label: Trigger + fullwidth: true + if: + type: function + name: isTopology + init: + type: func + value: setTrigger|autoscalingKubedbComSolrAutoscaler/spec/storage/overseer/trigger + schema: temp/properties/storage/properties/overseer/properties/trigger + watcher: + func: onTriggerChange|storage/overseer + paths: + - temp/properties/storage/properties/overseer/properties/trigger + - type: label-element + 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. + if: + type: function + name: isTopology + - type: select + label: Mode + description: Select how the storage expansion should be handled. + if: + type: function + name: isTopology + options: + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/overseer/properties/expansionMode + - type: block-layout + label: Overseer + showLabels: true + if: + type: function + name: isTopology + # schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/overseer + elements: + - type: threshold-input + label: Usage Threshold (%) + subtitle: Set the threshold percentage of storage usage to trigger scaling. + customClass: width-300 + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/overseer/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/overseer/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComSolr/spec/topology/overseer/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComSolrAutoscaler/spec/storage/overseer/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/overseer/properties/scalingRules + - type: input + label: Upper Bound + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/overseer/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComSolrAutoscaler/spec/storage/overseer/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/overseer/properties/upperBound + + # Node - Combined/Standalone Mode + - type: switch + label: Trigger + fullwidth: true + if: + type: function + name: isNotTopology + init: + type: func + value: setTrigger|autoscalingKubedbComSolrAutoscaler/spec/storage/node/trigger + schema: temp/properties/storage/properties/node/properties/trigger + watcher: + func: onTriggerChange|storage/node + paths: + - temp/properties/storage/properties/node/properties/trigger + - type: label-element + 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. + if: + type: function + name: isNotTopology + - type: select + label: Mode + description: Select how the storage expansion should be handled. + if: + type: function + name: isNotTopology + options: + - text: Online + value: Online + - text: Offline + value: Offline + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/node/properties/expansionMode + - type: block-layout + label: Node + showLabels: true + if: + type: function + name: isNotTopology + # schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/node + elements: + - type: threshold-input + label: Usage Threshold (%) + subtitle: Set the threshold percentage of storage usage to trigger scaling. + customClass: width-300 + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/node/properties/usageThreshold + - type: scaling-rules + label: Scaling Rules + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/node/properties/scalingRules + loader: setValueFromDbDetails|resources/kubedbComSolr/spec/storage/resources/requests/storage + watcher: + func: handleUnit|autoscalingKubedbComSolrAutoscaler/spec/storage/node/scalingRules|scalingRules + paths: + - schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/node/properties/scalingRules + - type: input + label: Upper Bound + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/node/properties/upperBound + watcher: + func: handleUnit|autoscalingKubedbComSolrAutoscaler/spec/storage/node/upperBound + paths: + - schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/node/properties/upperBound + + # Node Topology + - type: block-layout + label: Node Topology + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/nodeTopology elements: - - computed: setAllowedMachine|node|min - disableUnselect: true - fetch: getMachines|node|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|node - schema: - $ref: discriminator#/properties/allowedMachine-node-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/node/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/node/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/node/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|node|max - disableUnselect: true - fetch: getMachines|node|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|node - schema: - $ref: discriminator#/properties/allowedMachine-node-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/node/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/node/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/node/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|node - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/node/properties/controlledResources - type: multiselect - if: isNotTopology - label: - text: Node - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/node - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComSolrAutoscaler/spec/compute/overseer/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/overseer/properties/trigger - type: select - - label: - text: PodLifeTimeThreshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/overseer/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/overseer/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-overseer-max: - type: string - allowedMachine-overseer-min: - type: string + - type: select + label: Select NodeTopology + loader: fetchNodeTopology + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/nodeTopology/properties/name + - type: threshold-input + label: ScaleUp Diff Percentage + if: + type: function + name: isNodeTopologySelected|storage + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/nodeTopology/properties/scaleUpDiffPercentage + - type: threshold-input + label: ScaleDown Diff Percentage + if: + type: function + name: isNodeTopologySelected|storage + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/nodeTopology/properties/scaleDownDiffPercentage + + # Ops Request Options + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + # schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/opsRequestOptions elements: - - computed: setAllowedMachine|overseer|min - disableUnselect: true - fetch: getMachines|overseer|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|overseer - schema: - $ref: discriminator#/properties/allowedMachine-overseer-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/overseer/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/overseer/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/overseer/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|overseer|max - disableUnselect: true - fetch: getMachines|overseer|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|overseer - schema: - $ref: discriminator#/properties/allowedMachine-overseer-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/overseer/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/overseer/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/overseer/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|overseer - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/overseer/properties/controlledResources - type: multiselect - if: isTopology - label: - text: Overseer - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/overseer - show_label: true - type: single-step-form - type: single-step-form - - elements: - - fetch: fetchNodeTopology - label: - text: Select NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name - type: select - - if: isNodeTopologySelected|compute - label: - text: ScaleUp Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage - type: input - - if: isNodeTopologySelected|compute - label: - text: ScaleDown Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage - type: input - if: hasNoAnnotations - label: - text: NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/nodeTopology - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: compute-autoscaler - title: steps.0.label -- form: - discriminator: - dbDetails: - default: false - type: boolean + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + + - type: single-step-form + id: compute-autoscaler + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: SelectDb - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: SelectType - onChange: initMetadata - 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - elements: - - elements: - - elements: - - computed: setTrigger|autoscalingKubedbComSolrAutoscaler/spec/storage/coordinator/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/coordinator/properties/trigger - type: select - - label: - text: Expansion Mode - options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/coordinator/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/coordinator/properties/usageThreshold - type: input - - addFormLabel: ScalingRules - element: - elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/coordinator/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/coordinator/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComSolrAutoscaler/spec/storage/coordinator/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/coordinator/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComSolrAutoscaler/spec/storage/coordinator/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/coordinator/properties/upperBound - type: input - label: - text: Coordinator - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/coordinator - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComSolrAutoscaler/spec/storage/data/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/data/properties/trigger - type: select - - label: - text: Expansion Mode - options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/data/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/data/properties/usageThreshold - type: input - - addFormLabel: ScalingRules - element: - elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/data/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/data/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComSolrAutoscaler/spec/storage/data/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/data/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComSolrAutoscaler/spec/storage/data/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/data/properties/upperBound - type: input - label: - text: Data - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/data - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComSolrAutoscaler/spec/storage/node/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/node/properties/trigger - type: select - - label: - text: Expansion Mode - options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/node/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/node/properties/usageThreshold - type: input - - addFormLabel: ScalingRules - element: - elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/node/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/node/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComSolrAutoscaler/spec/storage/node/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/node/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComSolrAutoscaler/spec/storage/node/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/node/properties/upperBound - type: input - label: - text: Node - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/node - show_label: true - type: single-step-form - - elements: - - computed: setTrigger|autoscalingKubedbComSolrAutoscaler/spec/storage/overseer/trigger - label: - text: Trigger - options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/overseer/properties/trigger - type: select - - label: - text: Expansion Mode - options: - - Online - - Offline - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/overseer/properties/expansionMode - type: select - - label: - text: UsageThreshold (%) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/overseer/properties/usageThreshold - type: input - - addFormLabel: ScalingRules - element: - elements: - - label: - text: AppliesUpto (In Storage units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/overseer/properties/scalingRules/items/properties/appliesUpto - type: input - - label: - text: Threshold (In %, Or In Storage Units) - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/overseer/properties/scalingRules/items/properties/threshold - type: input - type: single-step-form - label: - text: ScalingRules - onChange: handleUnit|autoscalingKubedbComSolrAutoscaler/spec/storage/overseer/scalingRules|scalingRules - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/overseer/properties/scalingRules - tableContents: - - inTableColumn: true - label: - text: AppliesUpto (In Storage units) - path: appliesUpto - type: value - typeOfValue: string - - inTableColumn: true - label: - text: Threshold (In %, Or In Storage Units) - path: threshold - type: value - typeOfValue: string - type: single-step-form-array - - label: - text: UpperBound - onChange: handleUnit|autoscalingKubedbComSolrAutoscaler/spec/storage/overseer/upperBound - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/overseer/properties/upperBound - type: input - label: - text: Overseer - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/overseer - show_label: true - type: single-step-form - type: single-step-form - - elements: - - fetch: fetchNodeTopology - label: - text: Select NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/nodeTopology/properties/name - type: select - - if: isNodeTopologySelected|storage - label: - text: ScaleUp Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/nodeTopology/properties/scaleUpDiffPercentage - type: input - - if: isNodeTopologySelected|storage - label: - text: ScaleDown Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/nodeTopology/properties/scaleDownDiffPercentage - type: input - label: - text: NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/storage/properties/nodeTopology - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: OpsRequest Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: storage-autoscaler - title: steps.1.label -- form: - discriminator: - binding: - default: false - type: boolean - elements: - - computed: isBindingAlreadyOn - label: - text: Expose Database - onChange: addOrRemoveBinding - schema: - $ref: discriminator#/properties/binding - type: switch - type: single-step-form - id: binding - title: Gateway Binding -- form: - discriminator: - enableMonitoring: - default: true - type: boolean - elements: - - label: - text: labels.to_update_exporter_resources - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - function: getOpsRequestUrl|VerticalScaling - - computed: isValueExistInModel|/resources/kubedbComSolr/spec/monitor - 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 + - type: block-layout + if: + type: function + name: isConsole + elements: + - type: input + label: Name + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/metadata/properties/name + - type: select + label: Select Namespace + loader: getNamespaces + if: + type: function + name: isRancherManaged + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/metadata/properties/namespace + - type: select + label: Select Db + loader: getDbs + validation: + type: required + refresh: true + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/databaseRef/properties/name + watcher: + func: initMetadata + paths: + - schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/databaseRef/properties/name + + - type: radio + if: + type: function + name: isConsole + label: Select Type + validation: + type: required + schema: temp/properties/autoscalingType + watcher: + func: initMetadata + paths: + - temp/properties/autoscalingType 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/kubedbComSolr/properties/spec/properties/monitor/properties/agent - type: radio - - elements: - - label: - text: labels.scrapping_interval - schema: - $ref: schema#/properties/resources/properties/kubedbComSolr/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval - type: input - if: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComSolr/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/kubedbComSolr/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/kubedbComSolr/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: - - if: returnFalse - label: - text: labels.resources - schema: - $ref: schema#/properties/resources/properties/kubedbComSolr/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/kubedbComSolr/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/kubedbComSolr/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup - type: input - - label: - text: labels.port - schema: - $ref: schema#/properties/resources/properties/kubedbComSolr/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/kubedbComSolr/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args/items - type: input - label: - text: labels.args - schema: - $ref: schema#/properties/resources/properties/kubedbComSolr/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args - type: list-input-form - - alias: reusable_env - chart: - name: uibytebuildersdev-component-env - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComSolr/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 -type: multi-step-form + - text: Compute + value: compute + description: Scale your CPU Memory based on resource usage + - text: Storage + value: storage + description: Expand your database size based on volume usage + + - type: block-layout + showLabels: false + elements: + - type: block-layout + showLabels: false + loader: fetchTopologyMachines + elements: + # Coordinator - Topology Mode + - type: switch + label: Trigger + fullwidth: true + if: + type: function + name: isTopology + init: + type: func + value: setTrigger|autoscalingKubedbComSolrAutoscaler/spec/compute/coordinator/trigger + schema: temp/properties/compute/properties/coordinator/properties/trigger + watcher: + func: onTriggerChange|compute/coordinator + paths: + - temp/properties/compute/properties/coordinator/properties/trigger + - type: label-element + label: Pod lifetime threshold + subtitle: Specifies the duration a pod can exist before using considered for scaling decisions, ensuring resource optimization and workload stability + if: + type: function + name: isTopology + - type: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/coordinator/properties/podLifeTimeThreshold + customClass: width-300 + if: + type: function + name: isTopology + - type: block-layout + label: Coordinator + showLabels: true + if: + type: function + name: isTopology + # schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/coordinator + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/coordinator/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-coordinator-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|coordinator|min + loader: + name: getMachines|coordinator|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-coordinator-max + watcher: + func: onMachineChange|coordinator + paths: + - temp/properties/allowedMachine-coordinator-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/coordinator/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/coordinator/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-coordinator-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|coordinator|max + loader: + name: getMachines|coordinator|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-coordinator-min + watcher: + func: onMachineChange|coordinator + paths: + - temp/properties/allowedMachine-coordinator-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/coordinator/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/coordinator/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|coordinator + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/coordinator/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/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/coordinator/properties/containerControlledValues + + # Data - Topology Mode + - type: switch + label: Trigger + fullwidth: true + if: + type: function + name: isTopology + init: + type: func + value: setTrigger|autoscalingKubedbComSolrAutoscaler/spec/compute/data/trigger + schema: temp/properties/compute/properties/data/properties/trigger + watcher: + func: onTriggerChange|compute/data + paths: + - temp/properties/compute/properties/data/properties/trigger + - type: label-element + label: Pod lifetime threshold + subtitle: Specifies the duration a pod can exist before using considered for scaling decisions, ensuring resource optimization and workload stability + if: + type: function + name: isTopology + - type: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/data/properties/podLifeTimeThreshold + customClass: width-300 + if: + type: function + name: isTopology + - type: block-layout + label: Data + showLabels: true + if: + type: function + name: isTopology + # schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/data + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/data/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-data-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|data|min + loader: + name: getMachines|data|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-data-max + watcher: + func: onMachineChange|data + paths: + - temp/properties/allowedMachine-data-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/data/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/data/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-data-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|data|max + loader: + name: getMachines|data|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-data-min + watcher: + func: onMachineChange|data + paths: + - temp/properties/allowedMachine-data-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/data/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/data/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|data + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/data/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/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/data/properties/containerControlledValues + + # Overseer - Topology Mode + - type: switch + label: Trigger + fullwidth: true + if: + type: function + name: isTopology + init: + type: func + value: setTrigger|autoscalingKubedbComSolrAutoscaler/spec/compute/overseer/trigger + schema: temp/properties/compute/properties/overseer/properties/trigger + watcher: + func: onTriggerChange|compute/overseer + paths: + - temp/properties/compute/properties/overseer/properties/trigger + - type: label-element + label: Pod lifetime threshold + subtitle: Specifies the duration a pod can exist before using considered for scaling decisions, ensuring resource optimization and workload stability + if: + type: function + name: isTopology + - type: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/overseer/properties/podLifeTimeThreshold + customClass: width-300 + if: + type: function + name: isTopology + - type: block-layout + label: Overseer + showLabels: true + if: + type: function + name: isTopology + # schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/overseer + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/overseer/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-overseer-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|overseer|min + loader: + name: getMachines|overseer|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-overseer-max + watcher: + func: onMachineChange|overseer + paths: + - temp/properties/allowedMachine-overseer-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/overseer/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/overseer/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-overseer-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|overseer|max + loader: + name: getMachines|overseer|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-overseer-min + watcher: + func: onMachineChange|overseer + paths: + - temp/properties/allowedMachine-overseer-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/overseer/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/overseer/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|overseer + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/overseer/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/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/overseer/properties/containerControlledValues + + # Node - Combined/Standalone Mode + - type: switch + label: Trigger + fullwidth: true + if: + type: function + name: isNotTopology + init: + type: func + value: setTrigger|autoscalingKubedbComSolrAutoscaler/spec/compute/node/trigger + schema: temp/properties/compute/properties/node/properties/trigger + watcher: + func: onTriggerChange|compute/node + paths: + - temp/properties/compute/properties/node/properties/trigger + - type: label-element + label: Pod lifetime threshold + subtitle: Specifies the duration a pod can exist before using considered for scaling decisions, ensuring resource optimization and workload stability + if: + type: function + name: isNotTopology + - type: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/node/properties/podLifeTimeThreshold + customClass: width-300 + if: + type: function + name: isNotTopology + - type: block-layout + label: Node + showLabels: true + if: + type: function + name: isNotTopology + # schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/node + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/node/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-node-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|node|min + loader: + name: getMachines|node|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-node-max + watcher: + func: onMachineChange|node + paths: + - temp/properties/allowedMachine-node-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/node/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/node/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-node-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|node|max + loader: + name: getMachines|node|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-node-min + watcher: + func: onMachineChange|node + paths: + - temp/properties/allowedMachine-node-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/node/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/node/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|node + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/node/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/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/node/properties/containerControlledValues + + # Node Topology + - type: block-layout + label: NodeTopology + if: + type: function + name: hasNoAnnotations + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/nodeTopology + elements: + - type: select + label: Select NodeTopology + loader: fetchNodeTopology + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name + - type: threshold-input + label: Scale Up DiffPercentage + if: + type: function + name: isNodeTopologySelected|compute + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage + - type: threshold-input + label: Scale Down DiffPercentage + if: + type: function + name: isNodeTopologySelected|compute + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage + + # Ops Request Options + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + # schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/opsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComSolrAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply \ No newline at end of file diff --git a/charts/kubedbcom-solr-editor/ui/functions.js b/charts/kubedbcom-solr-editor/ui/functions.js index 67b2ee7874..2031bc960c 100644 --- a/charts/kubedbcom-solr-editor/ui/functions.js +++ b/charts/kubedbcom-solr-editor/ui/functions.js @@ -1,3428 +1,993 @@ -// ************************* common functions ******************************************** -// eslint-disable-next-line no-empty-pattern -async function fetchJsons({ axios, itemCtx, setDiscriminatorValue }, discriminatorPath) { - 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) - } - - if (discriminatorPath) { - setDiscriminatorValue(discriminatorPath, { - ui: ui.data || {}, - language: language.data || {}, - functions, - }) - } - - return { - ui: ui.data || {}, - language: language.data || {}, - functions, - } -} - -function disableLableChecker({ itemCtx }) { - const { key } = itemCtx - if (key.startsWith('app.kubernetes.io') || key.includes('helm')) return true - else return false -} - -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} - -async function getResources({ axios, storeGet }, 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 [] - } -} - -function isEqualToDiscriminatorPath( - { discriminator, getValue, watchDependency }, - value, - discriminatorPath, -) { - watchDependency('discriminator#' + discriminatorPath) - const discriminatorValue = getValue(discriminator, discriminatorPath) - return discriminatorValue === value -} - -function setValueFromModel({ getValue, model }, path) { - return getValue(model, path) -} - -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 -} - -async function getResourceList(axios, storeGet, { 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( - { axios, getValue, model, watchDependency, storeGet }, - 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 unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - 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, - } - }) -} - -function returnTrue() { - return true -} - -function returnStringYes() { - return 'yes' -} - -function isTopology({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComSolr/spec/topology') - const topo = getValue(model, '/resources/kubedbComSolr/spec/topology') - - return !!topo -} - -function isNotTopology({ model, getValue, watchDependency }) { - return !isTopology({ model, getValue, watchDependency }) -} - -function isDiscriminatorEqualTo( - { discriminator, getValue, watchDependency }, - discriminatorPath, - value, -) { - watchDependency('discriminator#' + discriminatorPath) - const pathValue = getValue(discriminator, discriminatorPath) - - return value === pathValue -} - -function isAuthPluginNotSearchGuard({ discriminator, getValue, watchDependency, commit }) { - watchDependency('discriminator#/selectedVersionAuthPlugin') - const pathValue = getValue(discriminator, '/selectedVersionAuthPlugin') - - if (!pathValue) return false - - const ret = pathValue !== 'SearchGuard' && pathValue !== '' - - if (!ret) { - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/topology/dataWarm') - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/topology/dataHot') - } - return ret -} - -// required for outer form section. where discriminator can not be saved -async function showInternalUsersAndRolesMapping({ - model, - getValue, - watchDependency, - axios, - storeGet, - setDiscriminatorValue, - commit, -}) { - watchDependency('model#/resources/kubedbComSolr/spec/disableSecurity') - watchDependency('model#/resources/kubedbComSolr/spec/version') - - const dist = await getSelectedVersionAuthPlugin({ - model, - getValue, - watchDependency, - axios, - storeGet, - setDiscriminatorValue, - }) - - const ret = - (dist === 'OpenDistro' || dist === 'SearchGuard') && - isSecurityEnabled({ model, getValue, watchDependency }) - - if (ret) { - commit('wizard/showSteps$update', { - stepId: 'internal-users', - show: true, - }) - - commit('wizard/showSteps$update', { - stepId: 'roles-mapping', - show: true, - }) - } else { - commit('wizard/showSteps$update', { - stepId: 'internal-users', - show: false, - }) - - commit('wizard/showSteps$update', { - stepId: 'roles-mapping', - show: false, - }) - } - return ret -} - -// required for outer form section. where discriminator can not be saved -async function showSecureCustomConfig({ - model, - getValue, - watchDependency, - axios, - storeGet, - setDiscriminatorValue, - commit, -}) { - watchDependency('model#/resources/kubedbComSolr/spec/version') - - const dist = await getSelectedVersionAuthPlugin({ - model, - getValue, - watchDependency, - axios, - storeGet, - setDiscriminatorValue, - }) - - const ret = dist === 'X-Pack' - - if (ret) { - commit('wizard/showSteps$update', { - stepId: 'secure-custom-config', - show: true, - }) - } else { - commit('wizard/showSteps$update', { - stepId: 'secure-custom-config', - show: false, - }) - - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/secureConfigSecret') - commit('wizard/model$delete', '/resources/secret_secure_config') - } - return ret -} - -// ************************* Basic Info ********************************************** - -async function getSolrVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null, authPlugin: null }, - }, - }, - } - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) - - const resources = (resp && resp.data && resp.data.items) || [] - - // keep only non deprecated versions - const filteredSolrVersions = resources.filter((item) => item.spec && !item.spec.deprecated) - - filteredSolrVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredSolrVersions -} - -function isSecurityEnabled({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComSolr/spec/disableSecurity') - const value = getValue(model, '/resources/kubedbComSolr/spec/disableSecurity') - return !value -} - -function onDisableSecurityChange({ model, getValue, commit }) { - const disableSecurity = getValue(model, '/resources/kubedbComSolr/spec/disableSecurity') - - if (disableSecurity) { - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/authSecret') - commit('wizard/model$delete', '/resources/secret_admin_cred') - commit('wizard/model$delete', '/resources/secret_elastic_cred') - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/internalUsers') - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/rolesMapping') - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/tls') - } -} - -async function onVersionChange({ - model, - getValue, - watchDependency, - axios, - storeGet, - commit, - setDiscriminatorValue, -}) { - const dist = await getSelectedVersionAuthPlugin({ - model, - getValue, - watchDependency, - axios, - storeGet, - setDiscriminatorValue, - }) - - const isOpenDistro = dist === 'OpenDistro' - const isSearchGuard = dist === 'SearchGuard' - const isXpack = dist === 'X-Pack' - - if (!isOpenDistro && !isSearchGuard) { - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/internalUsers') - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/rolesMapping') - if (isXpack) { - removeCertificatesOfAliases({ model, getValue, commit }, ['admin']) - } - } else { - if (!isOpenDistro) { - const internalUsers = getValue(model, '/resources/kubedbComSolr/spec/internalUsers') - - if (internalUsers) { - Object.keys(internalUsers).map((key) => { - if (internalUsers[key]?.opendistroSecurityRoles) - delete internalUsers[key]?.opendistroSecurityRoles - }) - } - - commit('wizard/model$update', { - path: '/resources/kubedbComSolr/spec/internalUsers', - value: internalUsers, - force: true, - }) - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/topology/dataHot') - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/topology/dataWarm') - } - if (!isSearchGuard) { - const internalUsers = getValue(model, '/resources/kubedbComSolr/spec/internalUsers') - - if (internalUsers) { - Object.keys(internalUsers).map((key) => { - if (internalUsers[key]?.searchGuardRoles) delete internalUsers[key]?.searchGuardRoles - }) - } - - commit('wizard/model$update', { - path: '/resources/kubedbComSolr/spec/internalUsers', - value: internalUsers, - force: true, - }) - } - - if (!isXpack) { - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/topology/dataCold') - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/topology/dataContent') - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/topology/dataFrozen') - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/topology/ml') - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/topology/transform') - } - } -} - -function onEnableSSLChange({ model, getValue, commit }) { - const enabelSSL = getValue(model, '/resources/kubedbComSolr/spec/enableSSL') - - if (enabelSSL === false) { - removeCertificatesOfAliases({ model, getValue, commit }, [ - 'http', - 'archiver', - 'metrics-exporter', - ]) - } -} - -function removeCertificatesOfAliases({ model, getValue, commit }, aliasesToRemove) { - const certificates = getValue(model, '/resources/kubedbComSolr/spec/tls/certificates') || [] - const updatedCertificates = certificates.filter((item) => !aliasesToRemove.includes(item.alias)) - commit('wizard/model$update', { - path: '/resources/kubedbComSolr/spec/tls/certificates', - value: updatedCertificates, - force: true, - }) -} - -/************************************* Database Secret Section ********************************************/ - -function getCreateAuthSecret({ model, getValue }) { - const authSecret = getValue(model, '/resources/kubedbComSolr/spec/authSecret') - - return !authSecret -} - -function showExistingSecretSection({ getValue, watchDependency, discriminator }) { - watchDependency('discriminator#/createAuthSecret') - - const hasAuthSecretName = getValue(discriminator, '/createAuthSecret') - return !hasAuthSecretName -} - -function showPasswordSection({ getValue, watchDependency, discriminator }) { - return !showExistingSecretSection({ - getValue, - watchDependency, - discriminator, - }) -} - -function setAuthSecretPassword({ model, getValue, watchDependency, discriminator, commit }) { - watchDependency('discriminator#/selectedVersionAuthPlugin') - - const dist = getValue(discriminator, '/selectedVersionAuthPlugin') - if (dist) { - if (dist === 'X-Pack') { - const encodedPassword = getValue(model, '/resources/secret_elastic_cred/data/password') - commit('wizard/model$delete', '/resources/secret_admin_cred') - return encodedPassword ? decodePassword({}, encodedPassword) : '' - } else { - const encodedPassword = getValue(model, '/resources/secret_admin_cred/data/password') - commit('wizard/model$delete', '/resources/secret_elastic_cred') - return encodedPassword ? decodePassword({}, encodedPassword) : '' - } - } -} - -function onAuthSecretPasswordChange({ getValue, discriminator, commit }) { - const stringPassword = getValue(discriminator, '/password') - const dist = getValue(discriminator, '/selectedVersionAuthPlugin') - - if (dist) { - if (stringPassword) { - if (dist === 'X-Pack') { - commit('wizard/model$update', { - path: '/resources/secret_elastic_cred/data/password', - value: encodePassword({}, stringPassword), - force: true, - }) - commit('wizard/model$update', { - path: '/resources/secret_elastic_cred/data/username', - value: encodePassword({}, 'elastic'), - force: true, - }) - commit('wizard/model$delete', '/resources/secret_admin_cred') - } else { - commit('wizard/model$update', { - path: '/resources/secret_admin_cred/data/password', - value: encodePassword({}, stringPassword), - force: true, - }) - commit('wizard/model$update', { - path: '/resources/secret_admin_cred/data/username', - value: encodePassword({}, 'admin'), - force: true, - }) - commit('wizard/model$delete', '/resources/secret_elastic_cred') - } - } else { - commit('wizard/model$delete', '/resources/secret_admin_cred') - commit('wizard/model$delete', '/resources/secret_elastic_cred') - } - } -} - -// eslint-disable-next-line no-empty-pattern -function encodePassword({}, value) { - return btoa(value) -} - -// eslint-disable-next-line no-empty-pattern -function decodePassword({}, value) { - return atob(value) -} - -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/authSecret') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/resources/secret_admin_cred') - commit('wizard/model$delete', '/resources/secret_elastic_cred') - } -} - -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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 [] - } -} - -function showSecretSection({ model, getValue, watchDependency, storeGet }) { - const steps = storeGet('/wizard/configureOptions') - - return ( - !steps.includes('internal-users') && isSecurityEnabled({ model, getValue, watchDependency }) - ) -} - -// ********************* Database Mode *********************** -function isNotCombinedMode({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - return mode !== 'Combined' -} - -function setDatabaseMode({ model, getValue }) { - isTopology = getValue(model, '/resources/kubedbComSolr/spec/topology') - if (isTopology) { - return 'Dedicated' - } else { - return 'Combined' - } -} - -let storageClassList = [] -async function getStorageClassNames( - { axios, storeGet, commit, setDiscriminatorValue, getValue, model }, - path, -) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/storage.k8s.io/v1/storageclasses`, - { - params: { - filter: { items: { metadata: { name: null, annotations: 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 - }) - - if (!path) { - setDiscriminatorValue('/storageClasses', resources) - } - storageClassList = resources - const initialStorageClass = getValue(model, path) - if (!initialStorageClass) setStorageClass({ model, getValue, commit }, path) - return resources -} - -function setStorageClass({ model, getValue, commit }, path) { - const deletionPolicy = getValue(model, 'resources/kubedbComSolr/spec/deletionPolicy') || '' - let storageClass = getValue(model, path) || '' - const suffix = '-retain' - - const simpleClassList = storageClassList.filter((item) => { - return !item.metadata?.name?.endsWith(suffix) - }) - - const retainClassList = storageClassList.filter((item) => { - return item.metadata?.name?.endsWith(suffix) - }) - - const defaultSimpleList = simpleClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] - ) - }) - - const defaultRetainList = retainClassList.filter((item) => { - return ( - item.metadata && - item.metadata.annotations && - item.metadata.annotations['storageclass.kubernetes.io/is-default-class'] - ) - }) - - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - if (simpleClassList.length > 1) { - const found = defaultSimpleList.length ? defaultSimpleList[0] : simpleClassList[0] - storageClass = found.value - } else if (simpleClassList.length === 1) { - storageClass = simpleClassList[0]?.value - } else { - const found = defaultRetainList.length - ? defaultRetainList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found - } - } else { - if (retainClassList.length > 1) { - const found = defaultRetainList.length ? defaultRetainList[0] : retainClassList[0] - storageClass = found.value - } else if (retainClassList.length === 1) { - storageClass = retainClassList[0]?.value - } else { - const found = defaultSimpleList.length - ? defaultSimpleList[0].value - : storageClassList.length - ? storageClassList[0].value - : '' - storageClass = found - } - } - - if (storageClass && path) { - commit('wizard/model$update', { - path: path, - value: storageClass, - force: true, - }) - } -} - -function deleteDatabaseModePath({ discriminator, getValue, commit }) { - const mode = getValue(discriminator, '/activeDatabaseMode') - if (mode === 'Dedicated') { - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/replicas') - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/storage') - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/maxUnavailable') - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/podTemplate') - } else if (mode === 'Combined') { - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/topology') - } -} - -function isEqualToDatabaseMode({ getValue, watchDependency, discriminator }, value) { - watchDependency('discriminator#/activeDatabaseMode') - const mode = getValue(discriminator, '/activeDatabaseMode') - - return mode === value -} - -function getMaxUnavailableOptions({ model, getValue, watchDependency, commit, elementUi }, path) { - let prefixPath - if (path) { - prefixPath = path - } else { - const { $ref } = elementUi.schema || {} - const replacedPath = ($ref || '').replace( - 'schema#/properties/resources/properties/kubedbComSolr/properties/spec/properties/topology/properties/', - '', - ) - const dyn = replacedPath.split('/').shift() - prefixPath = `/resources/kubedbComSolr/spec/topology/${dyn}` - } - - watchDependency(`model#${prefixPath}/replicas`) - - const replicas = getValue(model, `${prefixPath}/replicas`) - const maxUnavailable = getValue(model, `${prefixPath}/maxUnavailable`) - - if (maxUnavailable > replicas) { - commit('wizard/model$update', { - path: `${prefixPath}/maxUnavailable`, - value: replicas, - force: true, - }) - } - - const options = [] - - for (let i = 0; i <= Math.min(replicas, 1000); i++) { - options.push(i) - } - return options -} - -function getStorageClassNamesFromDiscriminator( - { model, discriminator, getValue, watchDependency, commit }, - path, -) { - watchDependency('discriminator#/storageClasses') - const options = getValue(discriminator, '/storageClasses') || [] - - setStorageClass({ model, getValue, commit }, path) - - return options -} - -async function getSelectedVersionAuthPlugin( - { model, getValue, watchDependency, axios, storeGet, setDiscriminatorValue }, - path, -) { - watchDependency('model#/resources/kubedbComSolr/spec/version') - const version = getValue(model, '/resources/kubedbComSolr/spec/version') || '' - - const elasticVersions = await getSolrVersions( - { axios, storeGet }, - 'catalog.kubedb.com', - 'v1alpha1', - 'solrversions', - ) - - const selectedVersion = elasticVersions?.find((item) => item.value === version) - - const ret = selectedVersion?.spec?.authPlugin || '' - - if (path) { - setDiscriminatorValue(path, ret) - } - - return ret -} - -function onNodeSwitchFalse({ elementSchema, commit }) { - const { $ref } = elementSchema || {} - const node = ($ref || '').split('/').pop() - commit('wizard/model$delete', `/resources/kubedbComSolr/spec/topology/${node}`) -} - -function hasTopologyNode({ model, getValue, itemCtx }) { - const nodeValue = getValue(model, `/resources/kubedbComSolr/spec/topology/${itemCtx}`) - - return !nodeValue -} - -function hideNode({ itemCtx, discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/selectedVersionAuthPlugin') - const authPlugin = getValue(discriminator, '/selectedVersionAuthPlugin') - - let hiddenNodes = ['coordinating'] - - if (authPlugin === 'OpenDistro') { - hiddenNodes = ['coordinating', 'ml', 'dataCold', 'dataFrozen', 'dataContent', 'transform'] - } else if (authPlugin === 'SearchGuard') { - hiddenNodes = [ - 'coordinating', - 'ml', - 'dataWarm', - 'dataHot', - 'dataCold', - 'dataFrozen', - 'dataContent', - 'transform', - ] - } - - const verd = hiddenNodes.includes(itemCtx) - return verd -} - -function setInitialStatusFalse({ elementSchema }) { - const disableNodes = ['master', 'data', 'ingest'] - const { $ref } = elementSchema || {} - const node = ($ref || '').split('/').pop() - return !disableNodes.includes(node) -} - -function disableNode({ elementSchema }) { - const disableNodes = ['master', 'data', 'ingest'] - const { $ref } = elementSchema || {} - const node = ($ref || '').split('/').pop() - return disableNodes.includes(node) -} - -// ************************** Internal Users ******************************** - -const defaultUsers = [ - 'admin', - 'kibanaro', - 'kibanaserver', - 'logstash', - 'readall', - 'snapshotrestore', - 'metrics_exporter', -] - -function onInternalUsersChange({ discriminator, getValue, commit }) { - const users = getValue(discriminator, '/internalUsers') - - const internalUsers = {} - - if (users) { - users.forEach((item) => { - const { username, createCred, secretName, password, ...obj } = item - if (createCred === 'no') { - obj.secretName = secretName - commit('wizard/model$delete', `/resources/secret_${username}_cred`) - } else if (createCred === 'yes') { - if (password) { - commit('wizard/model$update', { - path: `/resources/secret_${username}_cred/data/password`, - value: encodePassword({}, password), - force: true, - }) - commit('wizard/model$update', { - path: `/resources/secret_${username}_cred/data/username`, - value: encodePassword({}, username), - force: true, - }) - } else { - commit('wizard/model$delete', `/resources/secret_${username}_cred`) - } - } - internalUsers[username] = obj - }) - } - - if (Object.keys(internalUsers).length) { - commit('wizard/model$update', { - path: '/resources/kubedbComSolr/spec/internalUsers', - value: internalUsers, - force: true, - }) - } else { - // on initial call discriminator value is undefined - // to ignore model$delete for this case, - // users value checking is required, - // model$delete will be executed only if users value is not falsy value (empty array) - // and internalUsers is emptyObject - if (users) commit('wizard/model$delete', '/resources/kubedbComSolr/spec/internalUsers') - } -} - -function setInternalUsers({ model, getValue, watchDependency, setDiscriminatorValue }) { - watchDependency('model#/resources/kubedbComSolr/spec/internalUsers') - const internalUsers = getValue(model, '/resources/kubedbComSolr/spec/internalUsers') - - const users = [] - - for (const item in internalUsers) { - internalUsers[item].username = item - const encodedPassword = getValue(model, `/resources/secret_${item}_cred/data/password`) - if (internalUsers[item].secretName) { - internalUsers[item].createCred = 'no' - } else { - if (encodedPassword) { - internalUsers[item].password = decodePassword({}, encodedPassword) - } - internalUsers[item].createCred = 'yes' - } - users.push(internalUsers[item]) - } - - setDiscriminatorValue('/internalUsers', users) - - return users -} - -function validateNewUser({ itemCtx }) { - if (defaultUsers.includes(itemCtx.username) && itemCtx.isCreate) { - return { isInvalid: true, message: "Can't use this username" } - } - return {} -} - -function disableUsername({ rootModel }) { - return defaultUsers.includes(rootModel && rootModel.username) -} - -function disableUserEdit({ itemCtx }) { - if (defaultUsers.includes(itemCtx.username)) { - return { isEditDisabled: false, isDeleteDisabled: true } - } - return {} -} - -async function isAuthPluginEqualTo( - { model, getValue, watchDependency, axios, storeGet, setDiscriminatorValue }, - authPlugin, -) { - const dist = await getSelectedVersionAuthPlugin({ - model, - getValue, - watchDependency, - axios, - storeGet, - setDiscriminatorValue, - }) - return dist === authPlugin -} - -// internal user cred -function showPasswordCredSection({ rootModel, getValue, watchDependency }) { - watchDependency('rootModel#/createCred') - const createCred = getValue(rootModel, '/createCred') - - return createCred === 'yes' -} - -function showExistingCredSection({ rootModel, getValue, watchDependency }) { - return !showPasswordCredSection({ rootModel, getValue, watchDependency }) -} - -function disableRoleDeletion({ itemCtx, rootModel }) { - return itemCtx === 'admin' && rootModel.username === 'admin' -} - -// ************************** Roles Mapping ******************************** - -const defaultRoles = ['readall_and_monitor'] - -function onRolesMappingChange({ discriminator, getValue, commit }) { - const roles = getValue(discriminator, '/rolesMapping') - - const rolesMapping = {} - - if (roles) { - roles.forEach((item) => { - const { roleName, ...obj } = item - rolesMapping[roleName] = obj - }) - } - - if (Object.keys(rolesMapping).length) { - commit('wizard/model$update', { - path: '/resources/kubedbComSolr/spec/rolesMapping', - value: rolesMapping, - force: true, - }) - } else { - // on initial call discriminator value is undefined - // to ignore model$delete for this case, - // roles value checking is required, - // model$delete will be executed only if roles value is not falsy value (empty array) - // and rolesMapping is emptyObject - if (roles) commit('wizard/model$delete', '/resources/kubedbComSolr/spec/rolesMapping') - } -} - -function setRolesMapping({ model, getValue, watchDependency, setDiscriminatorValue }) { - watchDependency('model#/resources/kubedbComSolr/spec/rolesMapping') - const rolesMapping = getValue(model, '/resources/kubedbComSolr/spec/rolesMapping') - - const roles = [] - - for (const item in rolesMapping) { - rolesMapping[item].roleName = item - roles.push(rolesMapping[item]) - } - - setDiscriminatorValue('/rolesMapping', roles) - - return roles -} - -function disableRolesEdit({ itemCtx }) { - if (defaultRoles.includes(itemCtx.roleName)) { - return { isEditDisabled: false, isDeleteDisabled: true } - } - return {} -} - -function disableRoleName({ rootModel }) { - return defaultRoles.includes(rootModel && rootModel.roleName) -} - -function validateNewRole({ itemCtx }) { - if (defaultRoles.includes(itemCtx.roleName) && itemCtx.isCreate) { - return { isInvalid: true, message: "Can't use this role name" } - } - return {} -} - -function getInternalUsers({ model, getValue, watchDependency }) { - watchDependency('model#/resources/kubedbComSolr/spec/internalUsers') - const internalUsers = getValue(model, '/resources/kubedbComSolr/spec/internalUsers') - - return Object.keys(internalUsers) -} - -function disableUserDeletion({ itemCtx, rootModel }) { - return itemCtx.value === 'metrics_exporter' && rootModel.roleName === 'readall_and_monitor' -} - -// ************************* Kernel Settings ********************************* - -function onCustomizeKernelSettingChange({ discriminator, getValue, commit }) { - const customizeKernelSettings = getValue(discriminator, '/customizeKernelSettings') - - if (customizeKernelSettings === 'no') { - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/kernelSettings') - } else if (customizeKernelSettings === 'disable') { - commit('wizard/model$update', { - path: '/resources/kubedbComSolr/spec/kernelSettings', - value: {}, - force: true, - }) - } -} - -// ************************** TLS ******************************************* - -function setApiGroup() { - return 'cert-manager.io' -} - -function setApiGroupEdit({ model, getValue }) { - const kind = getValue(model, '/resources/kubedbComSolr/spec/tls/issuerRef/kind') - const name = getValue(model, '/resources/kubedbComSolr/spec/tls/issuerRef/name') - return kind && name ? 'cert-manager.io' : '' -} - -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - watchDependency('model#/resources/kubedbComSolr/spec/tls/issuerRef/apiGroup') - watchDependency('model#/resources/kubedbComSolr/spec/tls/issuerRef/kind') - watchDependency('model#/metadata/release/namespace') - const apiGroup = getValue(model, '/resources/kubedbComSolr/spec/tls/issuerRef/apiGroup') - const kind = getValue(model, '/resources/kubedbComSolr/spec/tls/issuerRef/kind') - const namespace = getValue(model, '/metadata/release/namespace') - - let url - if (kind === 'Issuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/namespaces/${namespace}/issuers` - } else if (kind === 'ClusterIssuer') { - url = `/clusters/${owner}/${cluster}/proxy/${apiGroup}/v1/clusterissuers` - } - - 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 [] - } -} - -async function hasIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await getIssuerRefsName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !!(resp && resp.length) -} - -async function hasNoIssuerRefName({ axios, storeGet, getValue, model, watchDependency }) { - const resp = await hasIssuerRefName({ - axios, - storeGet, - getValue, - model, - watchDependency, - }) - - return !resp -} - -function setClusterAuthMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComSolr/spec/clusterAuthMode') - return val || 'x509' -} - -function setSSLMode({ model, getValue }) { - const val = getValue(model, '/resources/kubedbComSolr/spec/sslMode') - return val || 'requireSSL' -} - -function showTlsConfigureSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configureTLS') - const configureStatus = getValue(discriminator, '/configureTLS') - return configureStatus -} - -function onTlsConfigureChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/configureTLS') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComSolr/spec/tls', - value: { issuerRef: {}, certificates: [] }, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/tls') - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/clusterAuthMode') - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/sslMode') - } -} - -async function showTlsRecommendation({ axios, storeGet }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const url = `/clusters/${owner}/${cluster}/proxy/cert-manager.io/v1/issuers` - - try { - await axios.get(url, { - params: { filter: { items: { metadata: { name: null } } } }, - }) - return false - } catch (err) { - // if any error response status is 404 or not - if (err.response && err.response.status === 404) { - resp = false - } - console.log(err) - return true - } -} - -async function getAliasOptions({ - model, - getValue, - watchDependency, - axios, - storeGet, - setDiscriminatorValue, -}) { - watchDependency('model#/resources/kubedbComSolr/spec/enableSSL') - watchDependency('model#/resources/kubedbComSolr/spec/monitor') - - const enableSSL = getValue(model, '/resources/kubedbComSolr/spec/enableSSL') - const monitor = getValue(model, '/resources/kubedbComSolr/spec/monitor') - const authPlugin = await getSelectedVersionAuthPlugin({ - model, - getValue, - watchDependency, - axios, - storeGet, - setDiscriminatorValue, - }) - - // always include transport cert alias - const aliases = ['transport'] - - if (authPlugin !== 'X-Pack') { - aliases.push('admin') - } - - if (enableSSL) { - aliases.push('http') - aliases.push('archiver') - if (monitor) { - aliases.push('metrics-exporter') - } - } - - return aliases -} - -/****** Monitoring *********/ - -function showMonitoringSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/enableMonitoring') - const configureStatus = getValue(discriminator, '/enableMonitoring') - return configureStatus -} - -function onEnableMonitoringChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/enableMonitoring') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComSolr/spec/monitor', - value: {}, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComSolr/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, getValue }) { - watchDependency('discriminator#/customizeExporter') - const configureStatus = getValue(discriminator, '/customizeExporter') - return configureStatus -} - -function onCustomizeExporterChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/customizeExporter') - if (configureStatus) { - commit('wizard/model$update', { - path: '/resources/kubedbComSolr/spec/monitor/prometheus/exporter', - value: {}, - force: true, - }) - } else { - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/monitor/prometheus/exporter') - } -} - -// ********************************* Initialization & Backup ************************************* -const stashAppscodeComRestoreSession_init = { - spec: { - repository: { - name: '', - }, - rules: [ - { - snapshots: ['latest'], - }, - ], - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} -const initScript = { - scriptPath: '', - secret: { - secretName: '', - }, -} -const stashAppscodeComRepository_init_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const stashAppscodeComRepository_repo = { - spec: { - backend: { - gcs: { - bucket: '', - prefix: '', - }, - storageSecretName: '', - }, - }, -} -const restoreSessionInitRunTimeSettings = { - container: { - resources: { - requests: { - cpu: '', - memory: '', - }, - limits: { - cpu: '', - memory: '', - }, - }, - nice: { - adjustment: null, - }, - ionice: { - class: null, - classData: null, - }, - securityContext: { - privileged: false, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - env: [], - envFrom: [], - }, - pod: { - serviceAccountName: '', - imagePullSecrets: [], - securityContext: { - fsGroup: null, - runAsNonRoot: false, - runAsUser: null, - runAsGroup: null, - seLinuxOptions: { - level: '', - role: '', - type: '', - user: '', - }, - }, - }, -} - -const stashAppscodeComBackupConfiguration = { - spec: { - repository: { - name: '', - }, - retentionPolicy: { - keepLast: 5, - name: 'keep-last-5', - prune: true, - }, - schedule: '*/5 * * * *', - target: { - ref: { - apiVersion: 'appcatalog.appscode.com/v1alpha1', - kind: 'AppBinding', - name: '', - }, - }, - }, -} - -function disableInitializationSection({ model, getValue, watchDependency }) { - const initialized = getValue(model, '/resources/kubedbComSolr/spec/init/initialized') - watchDependency('model#/resources/kubedbComSolr/spec/init/initialized') - return !!initialized -} - -function valueExists(value, getValue, path) { - const val = getValue(value, path) - if (val) return true - else return false -} - -function initPrePopulateDatabase({ getValue, model }) { - const waitForInitialRestore = getValue( - model, - '/resources/kubedbComSolr/spec/init/waitForInitialRestore', - ) - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - const script = getValue(model, '/resources/kubedbComSolr/spec/init/script') - - return waitForInitialRestore || !!stashAppscodeComRestoreSession_init || !!script ? 'yes' : 'no' -} - -function onPrePopulateDatabaseChange({ commit, getValue, discriminator, model }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - if (prePopulateDatabase === 'no') { - // delete related properties - commit('wizard/model$update', { - path: '/resources/kubedbComSolr/spec/init/waitForInitialRestore', - value: false, - }) - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/init/script') - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else { - const dbName = getValue(model, '/metadata/release/name') - // set stashAppscodeComRestoreSession_init if it doesn't exist - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - force: true, - }) - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - } - } -} - -function initDataSource({ getValue, model }) { - const script = getValue(model, '/resources/kubedbComSolr/spec/init/script') - const stashAppscodeComRestoreSession_init = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init', - ) - - if (script) return 'script' - else if (stashAppscodeComRestoreSession_init) return 'stashBackup' - else return undefined -} - -function onDataSourceChange({ commit, getValue, discriminator, model }) { - const dataSource = getValue(discriminator, '/dataSource') - - commit('wizard/model$update', { - path: '/resources/kubedbComSolr/spec/init/waitForInitialRestore', - value: dataSource === 'stashBackup', - force: true, - }) - - if (dataSource === 'script') { - commit('wizard/model$delete', '/resources/stashAppscodeComRestoreSession_init') - - // create a new script if there is no script property - if (!valueExists(model, getValue, '/resources/kubedbComSolr/spec/init/script')) - commit('wizard/model$update', { - path: '/resources/kubedbComSolr/spec/init/script', - value: initScript, - }) - } else if (dataSource === 'stashBackup') { - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/init/script') - - // create a new stashAppscodeComRestoreSession_init if there is no stashAppscodeComRestoreSession_init property - if (!valueExists(model, getValue, '/resources/stashAppscodeComRestoreSession_init')) { - const dbName = getValue(model, '/metadata/release/name') - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init', - value: stashAppscodeComRestoreSession_init, - }) - - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, - force: true, - }) - } - } -} - -// // for script -function initVolumeType({ getValue, model }) { - const configMap = getValue(model, '/resources/kubedbComSolr/spec/init/script/configMap/name') - const secret = getValue(model, '/resources/kubedbComSolr/spec/init/script/secret/secretName') - - if (configMap) return 'configMap' - else if (secret) return 'secret' - else return undefined -} - -function onVolumeTypeChange({ commit, getValue, discriminator, model }) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - if (sourceVolumeType === 'configMap') { - // add configMap object and delete secret object - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/init/script/secret') - - if (!valueExists(model, getValue, '/resources/kubedbComSolr/spec/init/script/configMap')) { - commit('wizard/model$update', { - path: '/resources/kubedbComSolr/spec/init/script/configMap', - value: { - name: '', - }, - }) - } - } else if (sourceVolumeType === 'secret') { - // delete configMap object and add secret object - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/init/script/configMap') - - if (!valueExists(model, getValue, '/resources/kubedbComSolr/spec/init/script/secret')) { - commit('wizard/model$update', { - path: '/resources/kubedbComSolr/spec/init/script/secret', - value: { - secretName: '', - }, - }) - } - } -} - -function showInitializationForm({ getValue, discriminator, watchDependency }) { - const prePopulateDatabase = getValue(discriminator, '/prePopulateDatabase') - watchDependency('discriminator#/prePopulateDatabase') - return prePopulateDatabase === 'yes' -} - -function showScriptOrStashForm({ getValue, discriminator, watchDependency }, value) { - const dataSource = getValue(discriminator, '/dataSource') - watchDependency('discriminator#/dataSource') - return dataSource === value -} - -function showConfigMapOrSecretName({ getValue, discriminator, watchDependency }, value) { - const sourceVolumeType = getValue(discriminator, '/sourceVolumeType') - watchDependency('discriminator#/sourceVolumeType') - return sourceVolumeType === value -} - -// for stash backup -function initializeNamespace({ getValue, model }) { - const namespace = getValue(model, '/metadata/release/namespace') - return namespace -} - -function showRepositorySelectOrCreate({ getValue, discriminator, watchDependency }, value) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') - - return repositoryChoise === value -} - -function onInitRepositoryChoiseChange({ getValue, discriminator, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - if (repositoryChoise === 'select') { - // delete stashAppscodeComRepository_init_repo from model - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_init_repo') - } else if (repositoryChoise === 'create') { - // add stashAppscodeComRepository_init_repo to model - commit('wizard/model$update', { - path: 'resources/stashAppscodeComRepository_init_repo', - value: stashAppscodeComRepository_init_repo, - }) - - const repositoryName = `${getValue(model, '/metadata/release/name')}-init-repo` - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: repositoryName, - }) - } -} - -function initCustomizeRestoreJobRuntimeSettings({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function initCustomizeRestoreJobRuntimeSettingsForBackup({ getValue, model }) { - const runtimeSettings = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - if (runtimeSettings) return 'yes' - else return 'no' -} - -function onCustomizeRestoreJobRuntimeSettingsChange({ commit, getValue, discriminator, model }) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/runtimeSettings', - value: restoreSessionInitRunTimeSettings, - }) - } - } -} - -function onCustomizeRestoreJobRuntimeSettingsChangeForBackup({ - commit, - getValue, - discriminator, - model, -}) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - if (customizeRestoreJobRuntimeSettings === 'no') { - commit( - 'wizard/model$delete', - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - } else if (customizeRestoreJobRuntimeSettings === 'yes') { - if ( - !valueExists( - model, - getValue, - '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - ) - ) { - // set new value - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/runtimeSettings', - value: {}, - force: true, - }) - } - } -} - -function showRuntimeForm({ discriminator, getValue, watchDependency }, value) { - const customizeRestoreJobRuntimeSettings = getValue( - discriminator, - '/customizeRestoreJobRuntimeSettings', - ) - watchDependency('discriminator#/customizeRestoreJobRuntimeSettings') - return customizeRestoreJobRuntimeSettings === value -} - -async function getImagePullSecrets({ getValue, model, watchDependency, axios, storeGet }) { - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - - let resources = await getNamespacedResourceList(axios, storeGet, { - namespace, - group: 'core', - version: 'v1', - resource: 'secrets', - }) - - resources = resources.filter((item) => { - const validType = ['kubernetes.io/dockerconfigjson'] - return validType.includes(item.type) - }) - - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: { name: name }, - } - }) -} - -// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// FOR Backup Configuration - -// schedule bakcup - -function getBackupConfigsAndAnnotations(getValue, model) { - const stashAppscodeComBackupConfiguration = getValue( - model, - '/resources/stashAppscodeComBackupConfiguration', - ) - const kubedbComSolrAnnotations = - getValue(model, '/resources/kubedbComSolr/metadata/annotations') || {} - - const isBluePrint = Object.keys(kubedbComSolrAnnotations).some( - (k) => - k === 'stash.appscode.com/backup-blueprint' || - k === 'stash.appscode.com/schedule' || - k.startsWith('params.stash.appscode.com/'), - ) - - return { - stashAppscodeComBackupConfiguration, - isBluePrint, - } -} - -function deleteKubedbComSolrDbAnnotation(getValue, model, commit) { - const annotations = getValue(model, '/resources/kubedbComSolr/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/kubedbComSolr/metadata/annotations', - value: filteredAnnotations, - }) -} - -function addKubedbComSolrDbAnnotation(getValue, model, commit, key, value, force) { - const annotations = getValue(model, '/resources/kubedbComSolr/metadata/annotations') || {} - - if (annotations[key] === undefined) { - annotations[key] = value - } else if (force) { - annotations[key] = value - } - - commit('wizard/model$update', { - path: '/resources/kubedbComSolr/metadata/annotations', - value: annotations, - force: true, - }) -} - -function initScheduleBackupForEdit({ getValue, model, setDiscriminatorValue }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function initScheduleBackup({ getValue, model }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, - model, - ) - - if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' - else return 'no' -} - -function onScheduleBackupChange({ commit, getValue, discriminator, model }) { - 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 kubedbComSolr annotation - deleteKubedbComSolrDbAnnotation(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, - }) - } - } -} - -// backup form -function showBackupForm({ getValue, discriminator, watchDependency }) { - const scheduleBackup = getValue(discriminator, '/scheduleBackup') - watchDependency('discriminator#/scheduleBackup') +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} - if (scheduleBackup === 'yes') return true - else return false -} - -// invoker form -async function initBackupInvoker({ getValue, model, storeGet, commit, axios }) { - const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( - getValue, +// ************************* common functions ******************************************** +// eslint-disable-next-line no-empty-pattern +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( model, + store.state, ) - const apiGroup = getValue(model, '/metadata/resource/group') - let kind = getValue(model, '/metadata/resource/kind') - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const name = storeGet('/route/params/name') - const namespace = storeGet('/route/query/namespace') - const group = storeGet('/route/params/group') - const version = storeGet('/route/params/version') - const resource = storeGet('/route/params/resource') - let labels = {} - - const sessions = getValue(model, '/resources/coreKubestashComBackupConfiguration/spec/sessions') - sessions[0].repositories[0].name = name - sessions[0].repositories[0].directory = `/${name}` - - commit('wizard/model$update', { - path: '/resources/coreKubestashComBackupConfiguration/spec/sessions', - value: sessions, - force: true, - }) - - const url = `clusters/${username}/${clusterName}/proxy/${group}/${version}/namespaces/${namespace}/${resource}/${name}` - - try { - const resp = await axios.get(url) - labels = resp.data.metadata.labels - kind = resp.data.kind - } catch (e) { - console.log(e) - } - - commit('wizard/model$update', { - path: '/metadata/release', - value: { - labels: labels, - name: name, - namespace: namespace, - }, - force: true, - }) - - commit('wizard/model$update', { - path: '/resources/coreKubestashComBackupConfiguration/metadata', - value: { - labels: labels, - name: name, - namespace: namespace, - }, - force: true, - }) - - commit('wizard/model$update', { - path: '/resources/coreKubestashComBackupConfiguration/spec/target', - value: { - apiGroup: apiGroup, - kind: kind, - name: name, - namespace: namespace, - }, - force: true, - }) - - let isStashPresetEnable = false - try { - const url = `/clusters/${username}/${clusterName}/proxy/ui.k8s.appscode.com/v1alpha1/features` - const resp = await axios.get(url) - const stashFeature = resp.data.items.filter((item) => { - return item.metadata.name === 'stash-presets' - }) - if (stashFeature[0].status?.enabled) { - isStashPresetEnable = true - } - } catch (e) { - console.log(e) - } - let schedule = '' - let storageRefName = '' - let storageRefNamespace = '' - let retentionPolicyName = '' - let retentionPolicyNamespace = '' - let encryptionSecretName = '' - let encryptionSecretNamespace = '' - - if (isStashPresetEnable) { - try { - const url = `clusters/${username}/${clusterName}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/stash-presets` - const resp = await axios.get(url) - schedule = resp.data.spec.values.spec.backup.kubestash.schedule - storageRefName = resp.data.spec.values.spec.backup.kubestash.storageRef.name - storageRefNamespace = resp.data.spec.values.spec.backup.kubestash.storageRef.namespace - retentionPolicyName = resp.data.spec.values.spec.backup.kubestash.retentionPolicy.name - retentionPolicyNamespace = - resp.data.spec.values.spec.backup.kubestash.retentionPolicy.namespace - encryptionSecretName = resp.data.spec.values.spec.backup.kubestash.encryptionSecret.name - encryptionSecretNamespace = - resp.data.spec.values.spec.backup.kubestash.encryptionSecret.namespace - } catch (e) { - console.log(e) - } - } - setInitSchedule( - { getValue, commit, model }, - 'resources/coreKubestashComBackupConfiguration/spec/sessions/', - schedule, - ) - setFileValueFromStash( - { getValue, commit, model }, - 'resources/coreKubestashComBackupConfiguration/spec/backends', - 'storageRef', - 'namespace', - storageRefNamespace, - ) - setFileValueFromStash( - { getValue, commit, model }, - 'resources/coreKubestashComBackupConfiguration/spec/backends', - 'storageRef', - 'name', - storageRefName, - ) - setFileValueFromStash( - { getValue, commit, model }, - 'resources/coreKubestashComBackupConfiguration/spec/backends', - 'retentionPolicy', - 'namespace', - retentionPolicyNamespace, - ) - setFileValueFromStash( - { getValue, commit, model }, - 'resources/coreKubestashComBackupConfiguration/spec/backends', - 'retentionPolicy', - 'name', - retentionPolicyName, - ) - setFileValueFromStash( - { getValue, commit, model }, - 'resources/coreKubestashComBackupConfiguration/spec/sessions', - 'encryptionSecret', - 'namespace', - encryptionSecretNamespace, - ) - setFileValueFromStash( - { getValue, commit, model }, - 'resources/coreKubestashComBackupConfiguration/spec/sessions', - 'encryptionSecret', - 'name', - encryptionSecretName, - ) - - if (stashAppscodeComBackupConfiguration) return 'backupConfiguration' - else if (isBluePrint) return 'backupBlueprint' - else return undefined -} - -function onBackupInvokerChange({ getValue, discriminator, commit, model }) { - const backupInvoker = getValue(discriminator, '/backupInvoker') - - if (backupInvoker === 'backupConfiguration') { - // delete annotation and create backup config object - deleteKubedbComSolrDbAnnotation(getValue, model, commit) - const dbName = getValue(model, '/metadata/release/name') - - if (!valueExists(model, getValue, '/resources/stashAppscodeComBackupConfiguration')) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration', - value: stashAppscodeComBackupConfiguration, - }) - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, - force: true, - }) - } - } else if (backupInvoker === 'backupBlueprint') { - // delete backup configuration object and create the annotation - commit('wizard/model$delete', '/resources/stashAppscodeComBackupConfiguration') - addKubedbComSolrDbAnnotation(getValue, model, commit, 'stash.appscode.com/backup-blueprint', '') - } -} - -function showInvokerForm({ getValue, discriminator, watchDependency }, value) { - const backupInvoker = getValue(discriminator, '/backupInvoker') - watchDependency('discriminator#/backupInvoker') - - return backupInvoker === value -} + /********** Initialize Discriminator **************/ -// backup configuration form -function initalizeTargetReferenceName({ getValue, model, watchDependency }) { - const databaseName = getValue(model, '/metadata/release/name') - watchDependency('model#/metadata/release/name') - - return databaseName -} - -// restore session repository -function setInitialRestoreSessionRepo({ getValue, model }) { - const value = getValue(model, 'resources/stashAppscodeComRepository_init_repo') - return value ? 'create' : 'select' -} + setDiscriminatorValue('binding', false) + setDiscriminatorValue('hidePreviewFromWizard', undefined) -// backup config repository -function initRepositoryChoise({ getValue, model }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) + setDiscriminatorValue('/enableMonitoring', false) + setDiscriminatorValue('/customizeExporter', true) + setDiscriminatorValue('/valueFromType', 'input') - if (stashAppscodeComRepository_repo) return 'create' - else return 'select' -} + // 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', '') -function initRepositoryChoiseForEdit({ getValue, model, setDiscriminatorValue }) { - const stashAppscodeComRepository_repo = getValue( - model, - '/resources/stashAppscodeComRepository_repo', - ) - const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' - setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) + // compute - return repoInitialSelectionStatus -} + let autoscaleType = '' + let dbDetails = {} + let instance = {} -function onRepositoryChoiseChange({ getValue, discriminator, watchDependency, commit, model }) { - const repositoryChoise = getValue(discriminator, '/repositoryChoise') - watchDependency('discriminator#/repositoryChoise') + function isConsole() { + const isKube = isKubedb() - if (repositoryChoise === 'select') { - // delete the stashAppscodeComRepository_repo - commit('wizard/model$delete', '/resources/stashAppscodeComRepository_repo') - } else if (repositoryChoise === 'create') { - // create new stashAppscodeComRepository_repo - if (!valueExists(model, getValue, '/resources/stashAppscodeComRepository_repo')) { + if (isKube) { + const dbName = storeGet('/route/params/name') || '' commit('wizard/model$update', { - path: '/resources/stashAppscodeComRepository_repo', - value: stashAppscodeComRepository_repo, + path: '/resources/autoscalingKubedbComSolrAutoscaler/spec/databaseRef/name', + value: dbName, + force: true, }) - const repositoryName = `${getValue(model, '/metadata/release/name')}-repo` - // set this name in stashAppscodeComRestoreSession_init + 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/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, + path: '/metadata/name', + value: modifiedName, + force: true, }) + const namespace = storeGet('/route/query/namespace') || '' + if (namespace) { + commit('wizard/model$update', { + path: '/metadata/namespace', + value: namespace, + force: true, + }) + } } - } -} - -function onRepositoryNameChange({ getValue, model, commit }) { - const repositoryName = getValue(model, 'resources/stashAppscodeComRepository_repo/metadata/name') - // set this name in stashAppscodeComRestoreSession_init - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: repositoryName, - }) -} - -// backup blueprint form -function getMongoAnnotations(getValue, model) { - const annotations = getValue(model, '/resources/kubedbComSolr/metadata/annotations') - return { ...annotations } || {} -} - -function initFromAnnotationValue({ getValue, model }, key) { - const annotations = getMongoAnnotations(getValue, model) - return annotations[key] -} - -function onBackupBlueprintNameChange({ getValue, discriminator, commit, model }) { - const backupBlueprintName = getValue(discriminator, '/backupBlueprintName') - addKubedbComSolrDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/backup-blueprint', - backupBlueprintName, - true, - ) -} - -function onBackupBlueprintScheduleChange({ getValue, discriminator, commit, model }) { - const backupBlueprintSchedule = getValue(discriminator, '/schedule') - addKubedbComSolrDbAnnotation( - getValue, - model, - commit, - 'stash.appscode.com/schedule', - backupBlueprintSchedule, - true, - ) -} - -function initFromAnnotationKeyValue({ getValue, model }, prefix) { - const annotations = getMongoAnnotations(getValue, model) - const newOb = {} - Object.keys(annotations).forEach((key) => { - if (key.startsWith(prefix)) { - const newKey = key.replace(prefix, '') - newOb[newKey] = annotations[key] - } - }) - return newOb -} - -function onTaskParametersChange({ getValue, discriminator, model, commit }) { - const taskParameters = getValue(discriminator, '/taskParameters') - - const taskParamterKeys = Object.keys(taskParameters).map( - (tp) => `params.stash.appscode.com/${tp}`, - ) - const oldAnnotations = getValue(model, '/resources/kubedbComSolr/metadata/annotations') || {} - const newAnnotations = {} - - const filteredAnnotationKeys = Object.keys(oldAnnotations).filter( - (key) => !taskParamterKeys.includes(key) && !key.startsWith('params.stash.appscode.com/'), - ) - filteredAnnotationKeys.forEach((key) => { - newAnnotations[key] = oldAnnotations[key] - }) + return !isKube + } - Object.keys(taskParameters).forEach((tpk) => { - newAnnotations[`params.stash.appscode.com/${tpk}`] = taskParameters[tpk] - }) + function isKubedb() { + return !!storeGet('/route/params/actions') + } - commit('wizard/model$update', { - path: '/resources/kubedbComSolr/metadata/annotations', - value: newAnnotations, - }) -} + function showOpsRequestOptions() { + if (isKubedb() === true) return true + watchDependency('model#/resources/autoscalingKubedbComSolrAutoscaler/spec/databaseRef/name') + watchDependency('discriminator#/autoscalingType') + return ( + !!getValue(model, '/resources/autoscalingKubedbComSolrAutoscaler/spec/databaseRef/name') && + !!getValue(discriminator, '/autoscalingType') + ) + } -function isValueExistInModel({ model, getValue }, path) { - const modelValue = getValue(model, path) - return !!modelValue -} + async function getNamespaces() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function onNamespaceChange({ commit, model, getValue }) { - const namespace = getValue(model, '/metadata/release/namespace') - const agent = getValue(model, '/resources/kubedbComSolr/spec/monitor/agent') - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', - value: [namespace], - force: true, + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, }) - } -} - -function onLabelChange({ commit, model, getValue }) { - const labels = getValue(model, '/resources/kubedbComSolr/spec/metadata/labels') - const agent = getValue(model, '/resources/kubedbComSolr/spec/monitor/agent') + const resources = (resp && resp.data && resp.data.items) || [] - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } }) } -} -function onNameChange({ commit, model, getValue }) { - const dbName = getValue(model, '/metadata/release/name') + async function getDbs() { + watchDependency('model#/metadata/namespace') + const namespace = getValue(model, '/metadata/namespace') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - const agent = getValue(model, '/resources/kubedbComSolr/spec/monitor/agent') + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/solrs`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) - const labels = getValue(model, '/resources/kubedbComSolr/spec/metadata/labels') + const resources = (resp && resp.data && resp.data.items) || [] - if (agent === 'prometheus.io') { - commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', - value: labels, - force: true, + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } }) } - const scheduleBackup = getValue(model, '/resources/stashAppscodeComBackupConfiguration') + async function getDbDetails() { + const annotations = getValue( + model, + '/resources/autoscalingKubedbComSolrAutoscaler/metadata/annotations', + ) + instance = annotations['kubernetes.io/instance-type'] + 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, '/resources/autoscalingKubedbComSolrAutoscaler/spec/databaseRef/name') || + '' + + if (namespace && name) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/solrs/${name}`, + ) + dbDetails = resp.data || {} + setDiscriminatorValue('/dbDetails', true) + } catch (e) { + console.log(e) + } + } - if (scheduleBackup) { commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/target/ref/name', - value: dbName, + path: `/metadata/release/name`, + value: name, force: true, }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_repo') - if (creatingNewRepo) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComBackupConfiguration/spec/repository/name', - value: `${dbName}-repo`, - force: true, - }) - } - } - - const prePopulateDatabase = getValue(model, '/resources/stashAppscodeComRestoreSession_init') - - if (prePopulateDatabase) { commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/target/ref/name', - value: dbName, + path: `/metadata/release/namespace`, + value: namespace, force: true, }) - const creatingNewRepo = getValue(model, '/resources/stashAppscodeComRepository_init_repo') - if (creatingNewRepo) { - commit('wizard/model$update', { - path: '/resources/stashAppscodeComRestoreSession_init/spec/repository/name', - value: `${dbName}-init-repo`, - force: true, - }) - } - } - - // to reset configSecret name field - const hasSecretConfig = getValue(model, '/resources/secret_user_config') - if (hasSecretConfig) { commit('wizard/model$update', { - path: '/resources/kubedbComSolr/spec/configSecret/name', - value: `${dbName}-config`, + path: `/resources/autoscalingKubedbComSolrAutoscaler/spec/databaseRef/name`, + value: name, force: true, }) - } -} - -function returnFalse() { - return false -} - -function onAgentChange({ commit, model, getValue }) { - const agent = getValue(model, '/resources/kubedbComSolr/spec/monitor/agent') - - if (!agent) { - removeCertificatesOfAliases({ model, getValue, commit }, ['metrics-exporter']) - } - - if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', - value: [], + path: `/resources/autoscalingKubedbComSolrAutoscaler/metadata/labels`, + value: dbDetails.metadata.labels, force: true, }) - - onNamespaceChange({ commit, model, getValue }) - onLabelChange({ commit, model, getValue }) - } else { - commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') } -} - -//////////////////// service monitor /////////////////// - -function isEqualToServiceMonitorType({ rootModel, watchDependency }, value) { - watchDependency('rootModel#/spec/type') - return rootModel && rootModel.spec && rootModel.spec.type === value -} -//////////////////// custom config ///////////////// -function onConfigurationSourceChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSource') - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_user_config') - commit('wizard/model$delete', '/resources/config_secret') - } else { - const value = getValue(model, '/resources/secret_user_config') - if (!value) { + function initMetadata() { + const dbName = + getValue(model, '/resources/autoscalingKubedbComSolrAutoscaler/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/secret_user_config', - value: {}, + path: '/metadata/name', + value: modifiedName, force: true, }) - } - const configSecretName = `${getValue(model, '/metadata/release/name')}-config` - commit('wizard/model$update', { - path: '/resources/kubedbComSolr/spec/configSecret/name', - value: configSecretName, - force: true, - }) - } -} - -function setConfigurationSource({ model, getValue }) { - const modelValue = getValue(model, '/resources/secret_user_config') - if (modelValue) { - return 'create-new-config' - } - return 'use-existing-config' -} -function setConfigFiles({ model, getValue, watchDependency, setDiscriminatorValue }) { - watchDependency('model#/resources/secret_user_config/stringData') - const configFiles = getValue(model, '/resources/secret_user_config/stringData') - - const files = [] - - for (const item in configFiles) { - const obj = {} - obj.key = item - obj.value = configFiles[item] - files.push(obj) - } - - setDiscriminatorValue('/configFiles', files) - - return files -} - -function onConfigFilesChange({ discriminator, getValue, commit }) { - const files = getValue(discriminator, '/configFiles') - - const configFiles = {} - - if (files) { - files.forEach((item) => { - const { key, value } = item - configFiles[key] = value - }) + // delete the other type object from model + if (type === 'compute') + commit('wizard/model$delete', '/resources/autoscalingKubedbComSolrAutoscaler/spec/storage') + if (type === 'storage') + commit('wizard/model$delete', '/resources/autoscalingKubedbComSolrAutoscaler/spec/compute') } - commit('wizard/model$update', { - path: '/resources/secret_user_config/stringData', - value: configFiles, - force: true, - }) -} - -function onSetCustomConfigChange({ discriminator, getValue, commit }) { - const value = getValue(discriminator, '/setCustomConfig') - - if (value === 'no') { - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/configSecret') - commit('wizard/model$delete', '/resources/secret_user_config') + function onNamespaceChange() { + const namespace = getValue(model, '/metadata/namespace') + if (!namespace) { + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComSolrAutoscaler/spec/databaseRef/name', + ) + } } -} -function initSetCustomConfig({ model, getValue }) { - const configSecret = getValue(model, '/resources/kubedbComSolr/spec/configSecret/name') - - if (configSecret) return 'yes' - else return 'no' -} - -//////////////////// secret custom config ///////////////// -function onSecretConfigurationSourceChange({ getValue, discriminator, commit, model }) { - const configurationSource = getValue(discriminator, '/configurationSource') - if (configurationSource === 'use-existing-config') { - commit('wizard/model$delete', '/resources/secret_secure_config') - } else { - const value = getValue(model, '/resources/secret_secure_config') - if (!value) { - commit('wizard/model$update', { - path: '/resources/secret_secure_config', - value: {}, - force: true, + 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) } - const configSecretName = `${getValue(model, '/metadata/release/name')}-secure-config` - commit('wizard/model$update', { - path: '/resources/kubedbComSolr/spec/secureConfigSecret/name', - value: configSecretName, - force: true, - }) - } -} - -function setSecretConfigurationSource({ model, getValue }) { - const modelValue = getValue(model, '/resources/secret_secure_config') - if (modelValue) { - return 'create-new-config' + return [] } - return 'use-existing-config' -} - -function setSecretConfigFiles({ model, getValue, watchDependency, setDiscriminatorValue }) { - watchDependency('model#/resources/secret_secure_config/stringData') - const configFiles = getValue(model, '/resources/secret_secure_config/stringData') - - const files = [] - for (const item in configFiles) { - const obj = {} - obj.key = item - obj.value = configFiles[item] - files.push(obj) + function isNodeTopologySelected(type) { + // watchDependency( + // `model#/resources/autoscalingKubedbComSolrAutoscaler/spec/${type}/nodeTopology/name`, + // ) + const nodeTopologyName = + getValue( + model, + `/resources/autoscalingKubedbComSolrAutoscaler/spec/${type}/nodeTopology/name`, + ) || '' + return !!nodeTopologyName.length } - setDiscriminatorValue('/configFiles', files) - - return files -} - -function onSecretConfigFilesChange({ discriminator, getValue, commit }) { - const files = getValue(discriminator, '/configFiles') - - const configFiles = {} - - if (files) { - files.forEach((item) => { - const { key, value } = item - configFiles[key] = value + function setControlledResources(type) { + const list = ['cpu', 'memory'] + const path = `/resources/autoscalingKubedbComSolrAutoscaler/spec/compute/${type}/controlledResources` + commit('wizard/model$update', { + path: path, + value: list, + force: true, }) + return list } - commit('wizard/model$update', { - path: '/resources/secret_secure_config/stringData', - value: configFiles, - force: true, - }) -} - -function onSetSecretCustomConfigChange({ discriminator, getValue, commit }) { - const value = getValue(discriminator, '/setSecretCustomConfig') - - if (value === 'no') { - commit('wizard/model$delete', '/resources/kubedbComSolr/spec/secureConfigSecret') - commit('wizard/model$delete', '/resources/secret_secure_config') + function setTrigger(path) { + let value = getValue(model, `/resources/${path}`) + if (value) return value + return 'On' } -} - -function initSetSecureCustomConfig({ model, getValue }) { - const configSecret = getValue(model, '/resources/kubedbComSolr/spec/secureConfigSecret/name') - - if (configSecret) return 'yes' - else return 'no' -} -function getOpsRequestUrl({ storeGet, model, getValue, mode }, 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 + `/create-opsrequest-${reqType.toLowerCase()}?namespace=${namespace}` - - if (mode === 'standalone-step') return pathConstructedForKubedb - else - return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/solropsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=${reqType}` -} - -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + function setApplyToIfReady() { + return 'IfReady' } -} -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} - -function showScheduleBackup({ storeGet }) { - const operationQuery = storeGet('/route/params/actions') || '' - const isBackupOperation = operationQuery === 'edit-self-backupconfiguration' ? true : false - return !isBackupOperation -} - -function showBackupOptions({ discriminator, getValue, watchDependency }, backup) { - const backupEnabled = getValue(discriminator, '/backupEnabled') - if (backupEnabled) { - if (backup === 'alert') return true - else return false - } else { - if (backup === 'alert') return false - else return true + function setMetadata() { + const dbname = storeGet('/route/params/name') || '' + const namespace = storeGet('/route/query/namespace') || '' + if (mode === 'standalone-step') { + commit('wizard/model$update', { + path: '/metadata/release/name', + value: dbname, + force: true, + }) + commit('wizard/model$update', { + path: '/metadata/release/namespace', + value: namespace, + force: true, + }) + } } -} -function isBlueprintOption({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/blueprintOptions') - const blueprintOptions = getValue(discriminator, '/blueprintOptions') - return blueprintOptions === value -} + async function fetchTopologyMachines() { + const instance = hasAnnotations() -function ifUsagePolicy({ discriminator, getValue, watchDependency, model }, value) { - watchDependency( - 'model#/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', - ) - const usagePolicy = getValue( - model, - '/resources/coreKubestashComBackupBlueprint/spec/usagePolicy/allowedNamespaces/from/default', - ) - return usagePolicy === value -} + 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) -async function getBlueprints({ getValue, model, setDiscriminatorValue, axios, storeGet }, backup) { - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const url = `clusters/${username}/${clusterName}/proxy/core.kubestash.com/v1alpha1/backupblueprints` - - try { - const resp = await axios.get(url) - let data = resp.data.items - return data - } catch (e) { - console.log(e) + const nodeGroups = resp.data?.spec?.nodeGroups || [] + setDiscriminatorValue('/topologyMachines', nodeGroups) + return nodeGroups + } catch (e) { + console.log(e) + return [] + } + } } -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function setAllowedMachine(type, minmax) { + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = {} + } -async function fetchNamespaces({ axios, storeGet }) { - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const group = storeGet('/route/params/group') - const version = storeGet('/route/params/version') - const resource = storeGet('/route/params/resource') + const machine = parsedInstance[type] || '' + const mx = machine?.includes(',') ? machine.split(',')[1] : '' + const mn = machine?.includes(',') ? machine.split(',')[0] : '' + const machineName = minmax === 'min' ? mn : mx - const url = `clusters/${username}/${clusterName}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews` + // Find the machine details from topologyMachines + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] + const machineData = nodeGroups.find((item) => item.topologyValue === machineName) - try { - const resp = await axios.post(url, { - _recurringCall: false, - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], - }, - }) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] + // 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, + } } - } catch (e) { - console.log(e) - } - return [] -} - -async function fetchNames( - { getValue, axios, storeGet, watchDependency, discriminator }, - version, - type, - discriminatorName, -) { - watchDependency(`discriminator#/${discriminatorName}`) - const username = storeGet('/route/params/user') - const clusterName = storeGet('/route/params/cluster') - const namespace = getValue(discriminator, `${discriminatorName}`) - const url = - type !== 'secrets' - ? `clusters/${username}/${clusterName}/proxy/storage.kubestash.com/${version}/namespaces/${namespace}/${type}` - : `clusters/${username}/${clusterName}/proxy/core/${version}/namespaces/${namespace}/${type}` - try { - if (namespace) { - const resp = await axios.get(url) - let data = resp.data.items - data = data.map((ele) => ele.metadata.name) - return data + // Return empty object if no machine found + return { + machine: machineName || '', + cpu: '', + memory: '', } - } catch (e) { - console.log(e) } - return [] -} -function initBlueprint() { - return 'create' -} -function initUsagePolicy() { - return 'Same' -} + function getMachines(type, minmax) { + // watchDependency('discriminator#/topologyMachines') + const depends = minmax === 'min' ? 'max' : 'min' + const dependantPath = `/allowedMachine-${type}-${depends}` -function onInputChange( - { getValue, discriminator, commit, model }, - modelPath, - field, - subfield, - discriminatorName, -) { - const value = getValue(discriminator, `/${discriminatorName}`) - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') backends[0][field][subfield] = value - else backends[0]['repositories'][0][field][subfield] = value - commit('wizard/model$update', { - path: modelPath, - value: backends, - }) -} -function setFileValueFromStash({ getValue, commit, model }, modelPath, field, subfield, value) { - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') backends[0][field][subfield] = value - else backends[0]['repositories'][0][field][subfield] = value - commit('wizard/model$update', { - path: modelPath, - value: backends, - }) -} + //watchDependency(`discriminator#${dependantPath}`) + const dependantMachineObj = getValue(discriminator, dependantPath) + const dependantMachine = dependantMachineObj?.machine || '' -function onInputChangeSchedule( - { getValue, discriminator, watchDependency, commit, model }, - modelPath, - discriminatorName, -) { - watchDependency(`discriminator#/${discriminatorName}`) - const value = getValue(discriminator, `/${discriminatorName}`) - const session = getValue(model, modelPath) - session[0].scheduler.schedule = value - commit('wizard/model$update', { - path: modelPath, - value: session, - }) -} + const nodeGroups = getValue(discriminator, '/topologyMachines') || [] -function setInitSchedule( - { getValue, discriminator, watchDependency, commit, model }, - modelPath, - value, -) { - const session = getValue(model, modelPath) - session[0].scheduler.schedule = value - commit('wizard/model$update', { - path: modelPath, - value: session, - }) -} + 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, + }, + } + }) -function getDefault({ getValue, model }, modelPath, field, subfield) { - const backends = getValue(model, modelPath) - if (field !== 'encryptionSecret') return backends[0][field][subfield] - else { - return backends[0]['repositories'][0][field][subfield] + const filteredMachine = machines?.filter((item, ind) => + minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, + ) + + return dependantIndex === -1 ? machines : filteredMachine } -} -function getDefaultSchedule( - { getValue, discriminator, watchDependency, commit, model }, - modelPath, - discriminatorName, -) { - watchDependency(`model#/${modelPath}`) - const session = getValue(model, modelPath) - return session[0].scheduler.schedule -} + function hasAnnotations(type) { + const annotations = getValue( + model, + '/resources/autoscalingKubedbComSolrAutoscaler/metadata/annotations', + ) + const instance = annotations['kubernetes.io/instance-type'] -////////////////// auto scaler ////////////// -let autoscaleType = '' -let dbDetails = {} + return !!instance + } -function isConsole({ storeGet, commit }) { - const isKube = isKubedb({ storeGet }) + function hasNoAnnotations() { + return !hasAnnotations() + } - if (isKube) { - const dbName = storeGet('/route/params/name') || '' - commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComSolrAutoscaler/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: '/metadata/name', - value: modifiedName, - force: true, - }) - const namespace = storeGet('/route/query/namespace') || '' - if (namespace) { + function onMachineChange(type) { + const annoPath = '/resources/autoscalingKubedbComSolrAutoscaler/metadata/annotations' + const annotations = getValue(model, annoPath) || {} + const instance = annotations['kubernetes.io/instance-type'] + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = {} + } + + // Now discriminator values are objects with { machine, cpu, memory } + const minMachineObj = getValue(discriminator, `/allowedMachine-${type}-min`) + const maxMachineObj = getValue(discriminator, `/allowedMachine-${type}-max`) + const minMachine = minMachineObj?.machine || '' + const maxMachine = maxMachineObj?.machine || '' + const minMaxMachine = `${minMachine},${maxMachine}` + + parsedInstance[type] = minMaxMachine + const instanceString = JSON.stringify(parsedInstance) + annotations['kubernetes.io/instance-type'] = instanceString + + // 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/autoscalingKubedbComSolrAutoscaler/spec/compute/${type}` + + if (minMachine && maxMachine && instance !== instanceString) { commit('wizard/model$update', { - path: '/metadata/namespace', - value: namespace, + 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, }) } } - return !isKube -} - -function isKubedb({ storeGet }) { - return !!storeGet('/route/params/actions') -} - -function showOpsRequestOptions({ model, getValue, watchDependency, storeGet, discriminator }) { - if (isKubedb({ storeGet }) === true) return true - watchDependency('model#/resources/autoscalingKubedbComSolrAutoscaler/spec/databaseRef/name') - watchDependency('discriminator#/autoscalingType') - return ( - !!getValue(model, '/resources/autoscalingKubedbComSolrAutoscaler/spec/databaseRef/name') && - !!getValue(discriminator, '/autoscalingType') - ) -} - -async function getNamespaces({ axios, storeGet }) { - 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) || [] + // storage - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, + 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, + }) + } } - }) -} - -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - watchDependency('model#/metadata/namespace') - const namespace = getValue(model, '/metadata/namespace') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/solrs`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + /****** Monitoring *********/ - const resources = (resp && resp.data && resp.data.items) || [] + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -async function getDbDetails({ setDiscriminatorValue, commit, axios, storeGet, getValue, model }) { - 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, '/resources/autoscalingKubedbComSolrAutoscaler/spec/databaseRef/name') || - '' - - if (namespace && name) { try { const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/solrs/${name}`, + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, ) - dbDetails = resp.data || {} - setDiscriminatorValue('/dbDetails', true) + + 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 [] } } - commit('wizard/model$update', { - path: `/metadata/release/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/metadata/release/namespace`, - value: namespace, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComRedisAutoscaler/spec/databaseRef/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComRedisAutoscaler/metadata/labels`, - value: dbDetails.metadata.labels, - force: true, - }) -} + async function getNamespacedResourceList( + axios, + storeGet, + { namespace, group, version, resource }, + ) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -async function dbTypeEqualsTo({ axios, storeGet, watchDependency, model, getValue, commit }, type) { - watchDependency('discriminator#/dbDetails') + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` - const { spec } = dbDetails || {} - const { topology } = spec || {} - let verd = '' - if (topology) verd = 'topology' - else verd = 'standalone' - clearSpecModel({ commit }, verd) - return type === verd && spec -} + let ans = [] + try { + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) -function clearSpecModel({ commit }, dbtype) { - if (dbtype === 'node') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComSolrAutoscaler/spec/${autoscaleType}/data`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComSolrAutoscaler/spec/${autoscaleType}/ingest`, - ) - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComSolrAutoscaler/spec/${autoscaleType}/master`, - ) - } else if (dbtype === 'topology') { - commit( - 'wizard/model$delete', - `/resources/autoscalingKubedbComSolrAutoscaler/spec/${autoscaleType}/node`, - ) + const items = (resp && resp.data && resp.data.items) || [] + ans = items + } catch (e) { + console.log(e) + } + + return ans } -} -function initMetadata({ getValue, discriminator, model, commit, storeGet }) { - const dbName = - getValue(model, '/resources/autoscalingKubedbComSolrAutoscaler/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) + function removeCertificatesOfAliases(aliasesToRemove) { + const certificates = getValue(model, '/resources/kubedbComSolr/spec/tls/certificates') || [] + const updatedCertificates = certificates.filter((item) => !aliasesToRemove.includes(item.alias)) commit('wizard/model$update', { - path: '/metadata/name', - value: modifiedName, + path: '/resources/kubedbComSolr/spec/tls/certificates', + value: updatedCertificates, force: true, }) + } - // delete the other type object from model - if (type === 'compute') - commit('wizard/model$delete', '/resources/autoscalingKubedbComSolrAutoscaler/spec/storage') - if (type === 'storage') - commit('wizard/model$delete', '/resources/autoscalingKubedbComSolrAutoscaler/spec/compute') -} - -function onNamespaceChange({ model, getValue, commit }) { - const namespace = getValue(model, '/metadata/namespace') - if (!namespace) { - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComSolrAutoscaler/spec/databaseRef/name', - ) + function showMonitoringSection() { + // watchDependency('discriminator#/enableMonitoring') + const configureStatus = getValue(discriminator, '/enableMonitoring') + return configureStatus } -} -function ifScalingTypeEqualsTo( - { storeGet, watchDependency, getValue, discriminator, model }, - type, -) { - watchDependency('discriminator#/autoscalingType') - watchDependency('model#/resources/autoscalingKubedbComSolrAutoscaler/spec/databaseRef/name') - - const operation = storeGet('/route/params/actions') || '' - if (operation.length) { - const splitOp = operation.split('-') - if (splitOp.length > 2) autoscaleType = splitOp[2] - } else autoscaleType = getValue(discriminator, '/autoscalingType') || '' - const isDatabaseSelected = !!getValue( - model, - '/resources/autoscalingKubedbComSolrAutoscaler/spec/databaseRef/name', - ) - return autoscaleType === type && isDatabaseSelected -} + function onEnableMonitoringChange() { + const configureStatus = getValue(discriminator, '/enableMonitoring') + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComSolr/spec/monitor', + value: {}, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/kubedbComSolr/spec/monitor') + } -async function fetchNodeTopology({ axios, storeGet }) { - 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 + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: configureStatus ? 'warning' : 'none', + force: true, }) - return mappedList - } catch (e) { - console.log(e) } - return [] -} -function isNodeTopologySelected({ watchDependency, model, getValue }, type) { - watchDependency( - `model#/resources/autoscalingKubedbComSolrAutoscaler/spec/${type}/nodeTopology/name`, - ) - const nodeTopologyName = - getValue( - model, - `/resources/autoscalingKubedbComSolrAutoscaler/spec/${type}/nodeTopology/name`, - ) || '' - return !!nodeTopologyName.length -} + function showCustomizeExporterSection() { + // watchDependency('discriminator#/customizeExporter') + const configureStatus = getValue(discriminator, '/customizeExporter') + return configureStatus + } -function setControlledResources({ commit }, type) { - const list = ['cpu', 'memory'] - const path = `/resources/autoscalingKubedbComSolrAutoscaler/spec/compute/${type}/controlledResources` - commit('wizard/model$update', { - path: path, - value: list, - force: true, - }) - return list -} + function onCustomizeExporterChange() { + const configureStatus = getValue(discriminator, '/customizeExporter') + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComSolr/spec/monitor/prometheus/exporter', + value: {}, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/kubedbComSolr/spec/monitor/prometheus/exporter') + } + } -function setTrigger({ model, getValue }, path) { - let value = getValue(model, `/resources/${path}`) - if (value) return value - return 'On' -} + function isValueExistInModel(path) { + const modelValue = getValue(model, path) + return !!modelValue + } -function setApplyToIfReady() { - return 'IfReady' -} + // function onNamespaceChange({ commit, model, getValue }) { + // const namespace = getValue(model, '/metadata/release/namespace') + // const agent = getValue(model, '/resources/kubedbComSolr/spec/monitor/agent') + // if (agent === 'prometheus.io') { + // commit('wizard/model$update', { + // path: '/resources/monitoringCoreosComServiceMonitor/spec/namespaceSelector/matchNames', + // value: [namespace], + // force: true, + // }) + // } + // } -function handleUnit({ commit, model, getValue }, 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)) { + function onLabelChange() { + const labels = getValue(model, '/resources/kubedbComSolr/spec/metadata/labels') + + const agent = getValue(model, '/resources/kubedbComSolr/spec/monitor/agent') + + if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: `/resources/${path}`, - value: updatedValue, + path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', + value: labels, force: true, }) } - } else { - if (!isNaN(value)) { - value += 'Gi' + } + + function onAgentChange() { + const agent = getValue(model, '/resources/kubedbComSolr/spec/monitor/agent') + + if (!agent) { + removeCertificatesOfAliases(['metrics-exporter']) + } + + if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: `/resources/${path}`, - value: value, + 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 + `/create-opsrequest-${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/solropsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=${reqType}` + } + + function onNamespaceChange() { + const namespace = getValue(model, 'onNamespaceChange') + if (!namespace) { + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComSolrAutoscaler/spec/databaseRef/name', + ) } } -} -function isBindingAlreadyOn({ model, getValue }) { - const value = getValue(model, '/resources') - const keys = Object.keys(value) - isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComSolrBinding') - return isExposeBinding -} + function setValueFrom() { + if (isConfigMapTypeValueFrom()) { + return 'configMap' + } else if (isSecretTypeValueFrom()) { + return 'secret' + } else { + return 'input' + } + } -async function addOrRemoveBinding({ commit, model, getValue, discriminator }) { - const value = getValue(discriminator, `/binding`) - const dbName = getValue(model, '/metadata/release/name') - const dbNamespace = getValue(model, '/metadata/release/namespace') - const labels = getValue(model, '/resources/kubedbComSolr/metadata/labels') - const bindingValues = { - apiVersion: 'catalog.appscode.com/v1alpha1', - kind: 'SolrBinding', - metadata: { - labels, - name: dbName, - namespace: dbNamespace, - }, - spec: { - sourceRef: { - name: dbName, - namespace: dbNamespace, - }, - }, + function isConfigMapTypeValueFrom() { + const valueFrom = getValue(discriminator, '/valueFrom') + return !!(valueFrom && valueFrom.configMapKeyRef) } - if (value) { - await commit('wizard/model$update', { - path: '/resources/catalogAppscodeComSolrBinding', - value: bindingValues, - force: true, - }) - } else { - await commit('wizard/model$delete', '/resources/catalogAppscodeComSolrBinding') + function isSecretTypeValueFrom() { + const valueFrom = getValue(discriminator, '/valueFrom') + return !!(valueFrom && valueFrom.secretKeyRef) } -} -function setMetadata({ storeGet, mode, commit }) { - const dbname = storeGet('/route/params/name') || '' - const namespace = storeGet('/route/query/namespace') || '' - if (mode === 'standalone-step') { - commit('wizard/model$update', { - path: '/metadata/release/name', - value: dbname, - force: true, + 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, }) - commit('wizard/model$update', { - path: '/metadata/release/namespace', - value: namespace, - force: true, + + 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 fetchTopologyMachines({ axios, getValue, storeGet, model, setDiscriminatorValue }) { - const instance = hasAnnotations({ model, getValue }) + async function getConfigMapKeys() { + 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/kubedbComSolr/spec/monitor/prometheus/exporter/env/items/valueFrom/configMapKeyRef/name', + ) + + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/configMapKeyRef/name') + + if (!configMapName) return [] - 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 resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/configmaps/${configMapName}`, + ) - const nodeGroups = resp.data?.spec?.nodeGroups || [] - setDiscriminatorValue('/topologyMachines', nodeGroups) - return nodeGroups + 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 [] } } -} -function setAllowedMachine({ model, getValue }, type, minmax) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComSolrAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - let parsedInstance = {} - try { - if (instance) parsedInstance = JSON.parse(instance) - } catch (e) { - console.log(e) - parsedInstance = {} - } + 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') - const machine = parsedInstance[type] || '' - const mx = machine?.includes(',') ? machine.split(',')[1] : '' - const mn = machine?.includes(',') ? machine.split(',')[0] : '' + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }, + ) - if (minmax === 'min') return mn - else return mx -} + const secrets = (resp && resp.data && resp.data.items) || [] -async function getMachines({ getValue, watchDependency, discriminator }, type, minmax) { - watchDependency('discriminator#/topologyMachines') - const depends = minmax === 'min' ? 'max' : 'min' - const dependantPath = `/allowedMachine-${type}-${depends}` + const filteredSecrets = secrets.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) - watchDependency(`discriminator#${dependantPath}`) - const dependantMachine = getValue(discriminator, dependantPath) + 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 [] + } + } - const nodeGroups = getValue(discriminator, '/topologyMachines') || [] + async function getSecretKeys() { + 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/kubedbComSolr/spec/monitor/prometheus/exporter/env/items/valueFrom/secretKeyRef/name', + ) - const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/secretKeyRef/name') - const machines = nodeGroups?.map((item) => { - const subText = `CPU: ${item.allocatable.cpu}, Memory: ${item.allocatable.memory}` - const text = item.topologyValue - return { text, subText, value: item.topologyValue } - }) + if (!secretName) return [] - const filteredMachine = machines?.filter((item, ind) => - minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, - ) + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets/${secretName}`, + ) - return dependantIndex === -1 ? machines : filteredMachine -} + const secret = (resp && resp.data && resp.data.data) || {} -function hasAnnotations({ model, getValue }, type) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComSolrAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] + const secretKeys = Object.keys(secret).map((item) => ({ + text: item, + value: item, + })) - return !!instance -} + return secretKeys + } catch (e) { + console.log(e) + return [] + } + } -function hasNoAnnotations({ model, getValue }) { - return !hasAnnotations({ model, getValue }) -} + 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/kubedbComSolr/metadata/labels') + const bindingValues = { + apiVersion: 'catalog.appscode.com/v1alpha1', + kind: 'SolrBinding', + metadata: { + labels, + name: dbName, + namespace: dbNamespace, + }, + spec: { + sourceRef: { + name: dbName, + namespace: dbNamespace, + }, + }, + } + + if (value) { + commit('wizard/model$update', { + path: '/resources/catalogAppscodeComSolrBinding', + value: bindingValues, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/catalogAppscodeComSolrBinding') + } + } -function onMachineChange({ model, getValue, discriminator, commit }, type) { - const annoPath = '/resources/autoscalingKubedbComSolrAutoscaler/metadata/annotations' - const annotations = getValue(model, annoPath) - const instance = annotations['kubernetes.io/instance-type'] - let parsedInstance = {} - try { - if (instance) parsedInstance = JSON.parse(instance) - } catch (e) { - console.log(e) - parsedInstance = {} + function isBindingAlreadyOn() { + const value = getValue(model, '/resources') + const keys = Object.keys(value) + const isExposeBinding = !!keys.find((str) => str === 'catalogAppscodeComSolrBinding') + return isExposeBinding } - const minMachine = getValue(discriminator, `/allowedMachine-${type}-min`) - const maxMachine = getValue(discriminator, `/allowedMachine-${type}-max`) - const minMaxMachine = `${minMachine},${maxMachine}` + function setValueFromDbDetails(path) { + const value = getValue(model, path) + return value + } - parsedInstance[type] = minMaxMachine - const instanceString = JSON.stringify(parsedInstance) - annotations['kubernetes.io/instance-type'] = instanceString + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } - const machines = getValue(discriminator, `/topologyMachines`) || [] - const minMachineObj = machines.find((item) => item.topologyValue === minMachine) - const maxMachineObj = machines.find((item) => item.topologyValue === maxMachine) - const minMachineAllocatable = minMachineObj?.allocatable - const maxMachineAllocatable = maxMachineObj?.allocatable - const allowedPath = `/resources/autoscalingKubedbComSolrAutoscaler/spec/compute/${type}` + function isTopology() { + // watchDependency('model#/resources/kubedbComSolr/spec/topology') + const topo = getValue(model, '/resources/kubedbComSolr/spec/topology') + + return !!topo + } + + function isNotTopology() { + return !isTopology() + } + + function onTriggerChange(type) { + const trigger = getValue(discriminator, `/${type}/trigger`) + const commitPath = `/resources/autoscalingKubedbComSolrAutoscaler/spec/${type}/trigger` - if (minMachine && maxMachine && instance !== instanceString) { - 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, + path: commitPath, + value: trigger ? 'On' : 'Off', force: true, }) } -} -return { - setMetadata, - handleUnit, - isConsole, - getNamespaces, - getDbs, - isKubedb, - getDbDetails, - dbTypeEqualsTo, - clearSpecModel, - initMetadata, - onNamespaceChange, - ifScalingTypeEqualsTo, - fetchNodeTopology, - isNodeTopologySelected, - setControlledResources, - setTrigger, - setApplyToIfReady, - showOpsRequestOptions, - setInitSchedule, - fetchNames, - fetchNamespaces, - isRancherManaged, - onInputChangeSchedule, - getDefaultSchedule, - getBlueprints, - ifUsagePolicy, - initUsagePolicy, - isBlueprintOption, - initBlueprint, - getDefault, - onInputChange, - showBackupOptions, - showScheduleBackup, - fetchJsons, - disableLableChecker, - isEqualToModelPathValue, - getResources, - isEqualToDiscriminatorPath, - setValueFromModel, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - returnTrue, - returnStringYes, - isTopology, - isNotTopology, - isDiscriminatorEqualTo, - isAuthPluginNotSearchGuard, - showInternalUsersAndRolesMapping, - showSecureCustomConfig, - getSolrVersions, - isSecurityEnabled, - onDisableSecurityChange, - onVersionChange, - onEnableSSLChange, - removeCertificatesOfAliases, - setDatabaseMode, - getStorageClassNames, - getStorageClassNamesFromDiscriminator, - deleteDatabaseModePath, - isEqualToDatabaseMode, - getSelectedVersionAuthPlugin, - onNodeSwitchFalse, - hasTopologyNode, - hideNode, - disableNode, - setInitialStatusFalse, - onInternalUsersChange, - disableRoleDeletion, - setInternalUsers, - validateNewUser, - disableUsername, - disableUserEdit, - isAuthPluginEqualTo, - showExistingCredSection, - showPasswordCredSection, - onRolesMappingChange, - setRolesMapping, - disableRolesEdit, - disableRoleName, - validateNewRole, - disableUserDeletion, - onCustomizeKernelSettingChange, - getInternalUsers, - setApiGroup, - setApiGroupEdit, - getIssuerRefsName, - hasIssuerRefName, - hasNoIssuerRefName, - setClusterAuthMode, - setSSLMode, - showTlsConfigureSection, - onTlsConfigureChange, - showTlsRecommendation, - getAliasOptions, - showMonitoringSection, - onEnableMonitoringChange, - showCustomizeExporterSection, - onCustomizeExporterChange, - disableInitializationSection, - valueExists, - initPrePopulateDatabase, - onPrePopulateDatabaseChange, - initDataSource, - onDataSourceChange, - initVolumeType, - onVolumeTypeChange, - showInitializationForm, - showScriptOrStashForm, - showConfigMapOrSecretName, - initializeNamespace, - showRepositorySelectOrCreate, - onInitRepositoryChoiseChange, - initCustomizeRestoreJobRuntimeSettings, - initCustomizeRestoreJobRuntimeSettingsForBackup, - onCustomizeRestoreJobRuntimeSettingsChange, - onCustomizeRestoreJobRuntimeSettingsChangeForBackup, - showRuntimeForm, - getImagePullSecrets, - getBackupConfigsAndAnnotations, - deleteKubedbComSolrDbAnnotation, - addKubedbComSolrDbAnnotation, - initScheduleBackup, - initScheduleBackupForEdit, - onScheduleBackupChange, - showBackupForm, - initBackupInvoker, - onBackupInvokerChange, - showInvokerForm, - initalizeTargetReferenceName, - setInitialRestoreSessionRepo, - initRepositoryChoise, - initRepositoryChoiseForEdit, - onRepositoryChoiseChange, - onRepositoryNameChange, - getMongoAnnotations, - initFromAnnotationValue, - onBackupBlueprintNameChange, - onBackupBlueprintScheduleChange, - initFromAnnotationKeyValue, - onTaskParametersChange, - isValueExistInModel, - onNamespaceChange, - onLabelChange, - onNameChange, - returnFalse, - onAgentChange, - getCreateAuthSecret, - showExistingSecretSection, - showPasswordSection, - encodePassword, - decodePassword, - onCreateAuthSecretChange, - setAuthSecretPassword, - onAuthSecretPasswordChange, - showSecretSection, - getSecrets, - isEqualToServiceMonitorType, - onConfigurationSourceChange, - setConfigurationSource, - getMaxUnavailableOptions, - setConfigFiles, - onConfigFilesChange, - onSetCustomConfigChange, - onSecretConfigurationSourceChange, - setSecretConfigurationSource, - setSecretConfigFiles, - onSecretConfigFilesChange, - onSetSecretCustomConfigChange, - initSetCustomConfig, - initSetSecureCustomConfig, - getOpsRequestUrl, - getCreateNameSpaceUrl, - isVariantAvailable, - setStorageClass, - isBindingAlreadyOn, - addOrRemoveBinding, - getMachines, - setAllowedMachine, - hasAnnotations, - hasNoAnnotations, - fetchTopologyMachines, - onMachineChange, + return { + isConsole, + isKubedb, + showOpsRequestOptions, + getNamespaces, + getDbs, + getDbDetails, + initMetadata, + onNamespaceChange, + fetchNodeTopology, + isNodeTopologySelected, + setControlledResources, + setTrigger, + setApplyToIfReady, + setMetadata, + fetchTopologyMachines, + setAllowedMachine, + getMachines, + hasAnnotations, + hasNoAnnotations, + onMachineChange, + handleUnit, + // Monitoring + isEqualToModelPathValue, + getResources, + getNamespacedResourceList, + removeCertificatesOfAliases, + showMonitoringSection, + onEnableMonitoringChange, + showCustomizeExporterSection, + onCustomizeExporterChange, + isValueExistInModel, + getOpsRequestUrl, + onNamespaceChange, + setValueFrom, + isConfigMapTypeValueFrom, + isSecretTypeValueFrom, + onValueFromChange, + isEqualToValueFromType, + resourceNames, + getConfigMapKeys, + getSecrets, + getSecretKeys, + // binding + addOrRemoveBinding, + isBindingAlreadyOn, + setValueFromDbDetails, + + isRancherManaged, + isTopology, + isNotTopology, + onTriggerChange, + } } diff --git a/charts/kubedbcom-zookeeper-editor-options/ui/create-ui.yaml b/charts/kubedbcom-zookeeper-editor-options/ui/create-ui.yaml index f943f17627..66f6f586be 100644 --- a/charts/kubedbcom-zookeeper-editor-options/ui/create-ui.yaml +++ b/charts/kubedbcom-zookeeper-editor-options/ui/create-ui.yaml @@ -1,298 +1,304 @@ -steps: -- form: - discriminator: - bundleApiLoaded: - default: false - type: boolean +step: +- type: single-step-form + loader: initBundle + elements: + - type: label-element + label: '' + subtitle: Select the ZooKeeper version you want to deploy on Kubernetes. The chosen version determines the ZooKeeper engine features, compatibility, and runtime behavior of your database. + - disableUnselect: true + loader: getAdminOptions|databases/ZooKeeper/versions + if: + type: function + name: isToggleOn|databases/ZooKeeper/versions + label: Database Version + schema: schema/properties/spec/properties/admin/properties/databases/properties/ZooKeeper/properties/versions/properties/default + type: select + - init: + type: func + value: getDefault|databases/ZooKeeper/mode + loader: getAdminOptions|databases/ZooKeeper/mode + isHorizontal: true + if: + type: function + name: isToggleOn|databases/ZooKeeper/mode + label: Database Mode + schema: schema/properties/spec/properties/mode + type: radio + - if: + type: function + name: isEqualToModelPathValue|Replicaset|/spec/mode + label: Replicas + schema: schema/properties/spec/properties/replicas + type: input + - elements: + - type: label-element + label: '' + subtitle: Select a machine profile to allocate CPU and memory resources for your database. Choose 'custom' to manually specify resource requirements or select a predefined profile. + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setMachineToCustom + loader: getMachineListForOptions + label: Machine + schema: schema/properties/spec/properties/podResources/properties/machine + type: select + - init: + type: func + value: setLimits|cpu + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: CPU + loader: setLimits|cpu + watcher: + func: setRequests|cpu + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu + type: input + - init: + type: func + value: setLimits|memory + disable: isMachineNotCustom + if: + type: function + name: isMachineCustom + label: Memory + loader: setLimits|memory + watcher: + func: setRequests|memory + paths: + - schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + - schema/properties/spec/properties/podResources/properties/machine + schema: schema/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory + type: input + label: Machine Profile + showLabels: true + type: block-layout + - elements: + - type: horizontal-layout + showLabels: true + elements: + - loader: getAdminOptions|storageClasses + label: Storage Class + schema: schema/properties/spec/properties/admin/properties/storageClasses/properties/default + type: select + - if: + type: function + name: showStorageSizeField + label: Storage Size + schema: schema/properties/spec/properties/persistence/properties/size + type: input + type: block-layout + - description: Configure Credentials, Deployment Mode etc. elements: - - computed: initBundle - if: returnFalse - type: label-element - - disableUnselect: true - fetch: getAdminOptions|databases/ZooKeeper/versions - if: isToggleOn|databases/ZooKeeper/versions - label: - text: labels.database.version - schema: - $ref: schema#/properties/spec/properties/admin/properties/databases/properties/ZooKeeper/properties/versions/properties/default - type: select - - computed: getDefault|databases/ZooKeeper/mode - fetch: getAdminOptions|databases/ZooKeeper/mode - hasDescription: true - if: isToggleOn|databases/ZooKeeper/mode - label: - text: labels.database.mode - schema: - $ref: schema#/properties/spec/properties/mode - type: radio - - if: isEqualToModelPathValue|Replicaset|/spec/mode - label: - text: labels.cluster.replicas - schema: - $ref: schema#/properties/spec/properties/replicas - type: input - elements: - - computed: setMachineToCustom - fetch: getMachineListForOptions - label: - text: Machine - schema: - $ref: schema#/properties/spec/properties/podResources/properties/machine - type: select - - computed: setLimits|cpu - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.cpu - onChange: setRequests|cpu - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/cpu - type: input - - computed: setLimits|memory - disabled: isMachineNotCustom - if: isMachineCustom - label: - text: labels.memory - onChange: setRequests|memory - schema: - $ref: schema#/properties/spec/properties/podResources/properties/resources/properties/requests/properties/memory - type: input - label: - text: labels.machine_profile - show_label: true - type: single-step-form - - fetch: getAdminOptions|storageClasses - label: - text: labels.storage.class - schema: - $ref: schema#/properties/spec/properties/admin/properties/storageClasses/properties/default + - type: label-element + label: '' + subtitle: Add custom labels and annotations to your database resources for organization, monitoring, and integration with other Kubernetes tools and services. + - type: object-item + label: Labels + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/annotations + hideBlock: true + label: Labels & Annotations + showLabels: true + type: block-layout + - init: + type: func + value: getDefault|deletionPolicy + customClass: mt-20 + if: + type: function + name: isToggleOn|deletionPolicy + label: Deletion Policy + watcher: + func: setStorageClass + paths: + - schema/properties/spec/properties/deletionPolicy + options: + - description: options.deletionPolicy.delete.description + text: Delete ( Keep only database Secrets and backed up data ) + value: Delete + - description: options.deletionPolicy.halt.description + text: Halt ( Keep PVCs, database Secrets and backed up data ) + value: Halt + - description: options.deletionPolicy.wipeOut.description + text: WipeOut ( Delete everything including backed up data ) + value: WipeOut + - description: options.deletionPolicy.doNotTerminate.description + text: DoNotTerminate ( Prevent deletion of the ZooKeeper CRD ) + value: DoNotTerminate + schema: schema/properties/spec/properties/deletionPolicy + type: select + - if: + type: function + name: getDefaultValue|spec/admin/authCredential/customize + label: Provide Authentication Credentials? + watcher: + func: onAuthChange + paths: + - temp/createAuthSecret + schema: temp/createAuthSecret + type: switch + - if: + type: function + name: showReferSecretSwitch + label: Refer existing Secret? + watcher: + func: onReferSecretChange + paths: + - temp/referSecret + schema: temp/referSecret + type: switch + - loader: getReferSecrets + if: + type: function + name: showSecretDropdown + label: Secret + schema: schema/properties/spec/properties/authSecret/properties/name type: select - - if: showStorageSizeField - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/persistence/properties/size + - if: + type: function + name: showReferSecret + label: Password (leave it blank to auto generate password) + schema: schema/properties/spec/properties/authSecret/properties/password type: input - - accordion: true - description: - text: Configure Credentials, Deployment Mode etc. - discriminator: - configDatabase: - default: false - type: boolean - createAuthSecret: - default: false - type: boolean - referSecret: - default: false - type: boolean - elements: - - elements: - - isArray: true - keys: - label: - text: labels.labels.key - label: - text: labels.labels.label - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties - type: input - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.annotations.label - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties - type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - computed: getDefault|deletionPolicy - customClass: mt-20 - if: isToggleOn|deletionPolicy - 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/spec/properties/deletionPolicy - type: select - - if: getDefaultValue|spec/admin/authCredential/customize - label: - text: Provide Authentication Credentials? - onChange: onAuthChange - schema: - $ref: discriminator#/createAuthSecret - type: switch - - if: showReferSecretSwitch - label: - text: Refer existing Secret? - onChange: onReferSecretChange - schema: - $ref: discriminator#/referSecret - type: switch - - fetch: getReferSecrets - if: showSecretDropdown - label: - text: Secret - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/name - type: select - - if: showReferSecret - label: - text: labels.password - schema: - $ref: schema#/properties/spec/properties/authSecret/properties/password - type: input - - computed: isConfigAvailable - if: getDefaultValue|spec/admin/customConfiguration - label: - text: Configure Database? - onChange: clearConfiguration - schema: - $ref: discriminator#/configDatabase + - if: + type: function + name: getDefaultValue|spec/admin/customConfiguration + label: Configure Database? + watcher: + func: clearConfiguration + paths: + - temp/configDatabase + schema: temp/configDatabase + type: switch + - if: + type: function + name: isConfigDatabaseOn + label: Configuration + schema: schema/properties/spec/properties/configuration + type: textarea + - if: + type: function + name: isToggleOn|deployment + label: Deployment Mode + watcher: + func: setResourceLimit + paths: + - schema/properties/spec/properties/admin/properties/deployment/properties/default + options: + - description: For exploring databases when high-performance is not required. + text: Shared + value: Shared + - description: For production applications with sophisticated workload + text: Dedicated + value: Dedicated + schema: schema/properties/spec/properties/admin/properties/deployment/properties/default + type: radio + - if: + type: function + name: isToggleOn|clusterTier + isHorizontal: true + label: Cluster Tier + options: + - text: General Purpose + value: GeneralPurpose + - text: Memory Optimized + value: MemoryOptimized + - text: CPU Optimized + value: CPUOptimized + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/default + type: radio + - disableUnselect: true + loader: getAdminOptions|clusterTier/placement + if: + type: function + name: isToggleOn|clusterTier/placement + label: Placement Policy + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default + type: select + - disableUnselect: true + loader: getNodeTopology + if: + type: function + name: isToggleOn|clusterTier/nodeTopology + label: Node Topology + schema: schema/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + type: select + hideBlock: true + label: Advanced Configuration + showLabels: true + type: block-layout + - description: Enable Backup, Monitoring, TLS etc. + elements: + - elements: + - init: + type: func + value: setMonitoring + label: Enable Monitoring + watcher: + func: updateAlertValue + paths: + - temp/monitoring + schema: temp/monitoring type: switch - - if: isConfigDatabaseOn - label: - text: Configuration - schema: - $ref: schema#/properties/spec/properties/configuration - type: editor - - hasDescription: true - if: isToggleOn|deployment - label: - text: labels.deployment.name - onChange: setResourceLimit + - customClass: mt-10 + if: + type: function + name: showAlerts + label: Alert Options options: - - description: labels.deployment.shared - text: Shared - value: Shared - - description: labels.deployment.dedicated - text: Dedicated - value: Dedicated - schema: - $ref: schema#/properties/spec/properties/admin/properties/deployment/properties/default - type: radio - - if: isToggleOn|clusterTier - isHorizontal: true - label: - text: labels.clusterTier - options: - - text: General Purpose - value: GeneralPurpose - - text: Memory Optimized - value: MemoryOptimized - - text: CPU Optimized - value: CPUOptimized - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/default - type: radio - - disableUnselect: true - fetch: getAdminOptions|clusterTier/placement - if: isToggleOn|clusterTier/placement - label: - text: labels.placement - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/placement/properties/default - type: select - - disableUnselect: true - fetch: getNodeTopology - if: isToggleOn|clusterTier/nodeTopology - label: - text: labels.nodeTopology - schema: - $ref: schema#/properties/spec/properties/admin/properties/clusterTier/properties/nodeTopology/properties/default + - text: None + value: none + - text: Critical + value: critical + - text: Warning + value: warning + - text: Info + value: info + schema: schema/properties/form/properties/alert/properties/enabled type: select - hideForm: true - label: - text: Advanced Configuration - show_label: true - type: single-step-form - - accordion: true - description: - text: Enable Backup, Monitoring, TLS etc. - elements: - - discriminator: - monitoring: - default: false - type: boolean - elements: - - computed: setMonitoring - label: - text: labels.enable_monitoring - onChange: updateAlertValue - schema: - $ref: discriminator#/monitoring - type: switch - - customClass: mt-10 - if: showAlerts - label: - text: labels.alert.options - options: - - text: None - value: none - - text: Critical - value: critical - - text: Warning - value: warning - - text: Info - value: info - schema: - $ref: schema#/properties/form/properties/alert/properties/enabled - sortable: true - type: select - if: isToggleOn|monitoring - type: single-step-form - - computed: setBackup - if: isToggleOn|backup - label: - text: Enable Backup? - onChange: onBackupSwitch - schema: - $ref: discriminator#/backup + if: + type: function + name: isToggleOn|monitoring + type: block-layout + - init: + type: func + value: setBackup + if: + type: function + name: isToggleOn|backup + label: Enable Backup? + watcher: + func: onBackupSwitch + paths: + - temp/backup + schema: temp/backup + type: switch + - elements: + - label: Expose via Gateway? + schema: schema/properties/spec/properties/admin/properties/expose/properties/default type: switch - - elements: - - label: - text: Expose via Gateway? - schema: - $ref: schema#/properties/spec/properties/admin/properties/expose/properties/default - type: switch - if: isToggleOn|expose - type: single-step-form - if: showAdditionalSettings - label: - text: Additional Options - show_label: true - type: single-step-form - type: single-step-form + if: + type: function + name: isToggleOn|expose + type: block-layout + if: + type: function + name: showAdditionalSettings + label: Additional Options + showLabels: true + type: block-layout id: options - title: steps.0.label + # title: steps.0.label type: multi-step-form diff --git a/charts/kubedbcom-zookeeper-editor-options/ui/functions.js b/charts/kubedbcom-zookeeper-editor-options/ui/functions.js index 520b070b66..17e1f6dc45 100644 --- a/charts/kubedbcom-zookeeper-editor-options/ui/functions.js +++ b/charts/kubedbcom-zookeeper-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -315,976 +317,1034 @@ const modeDetails = { }, } -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} +let placement = [] +let versions = [] +let storageClass = [] +let clusterIssuers = [] +let nodetopologiesShared = [] +let nodetopologiesDedicated = [] +let features = [] -function showAuthSecretField({ discriminator, getValue, watchDependency }) { - return !showAuthPasswordField({ - discriminator, - getValue, - watchDependency, - }) -} +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) -function showStorageSizeField({ model, getValue, watchDependency }) { - const modelPathValue = getValue(model, '/spec/mode') - watchDependency('model#/spec/mode') - const validType = ['Standalone', 'Replicaset'] - return validType.includes(modelPathValue) -} + setDiscriminatorValue('bundleApiLoaded', false) + setDiscriminatorValue('configDatabase', false) + setDiscriminatorValue('createAuthSecret', false) + setDiscriminatorValue('referSecret', false) + setDiscriminatorValue('monitoring', false) + setDiscriminatorValue('backup', false) + + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } -async function getResources({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function showAuthSecretField() { + return !showAuthPasswordField() + } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + function showStorageSizeField() { + const modelPathValue = getValue(model, '/spec/mode') + // watchDependency('model#/spec/mode') + const validType = ['Standalone', 'Replicaset'] + return validType.includes(modelPathValue) + } - const resources = (resp && resp.data && resp.data.items) || [] + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return resources -} + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) -async function getMongoDbVersions({ axios, storeGet }, group, version, resource) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + const resources = (resp && resp.data && resp.data.items) || [] - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null }, - }, - }, + resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true + }) + return resources } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, - { - params: queryParams, - }, - ) + async function getMongoDbVersions(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + + const queryParams = { + filter: { + items: { + metadata: { name: null }, + spec: { version: null, deprecated: null }, + }, + }, + } - const resources = (resp && resp.data && resp.data.items) || [] + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}`, + { + params: queryParams, + }, + ) - // keep only non deprecated versions - const filteredMongoDbVersions = resources.filter((item) => item.spec && !item.spec.deprecated) + const resources = (resp && resp.data && resp.data.items) || [] - filteredMongoDbVersions.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' - item.text = `${name} (${specVersion})` - item.value = name - return true - }) - return filteredMongoDbVersions -} + // keep only non deprecated versions + const filteredMongoDbVersions = resources.filter((item) => item.spec && !item.spec.deprecated) -function onCreateAuthSecretChange({ discriminator, getValue, commit }) { - const createAuthSecret = getValue(discriminator, '/createAuthSecret') - if (createAuthSecret) { - commit('wizard/model$delete', '/spec/authSecret/name') - } else if (createAuthSecret === false) { - commit('wizard/model$delete', '/spec/authSecret/password') + filteredMongoDbVersions.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + const specVersion = (item.spec && item.spec.version) || '' + item.text = `${name} (${specVersion})` + item.value = name + return true + }) + return filteredMongoDbVersions } -} -async function getSecrets({ storeGet, axios, model, getValue, watchDependency }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, + function onCreateAuthSecretChange() { + const createAuthSecret = getValue(discriminator, '/createAuthSecret') + if (createAuthSecret) { + commit('wizard/model$delete', '/spec/authSecret/name') + } else if (createAuthSecret === false) { + commit('wizard/model$delete', '/spec/authSecret/password') + } + } + + 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') + + 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 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) - }) + 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 -} + filteredSecrets.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true + }) + return filteredSecrets + } -function getMachineListForOptions({ model, getValue }) { - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') let array = [] + function getMachineListForOptions() { + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') - if (available.length) { - array = available.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - else { - let subText = '', - text = '' - const machineData = machinesFromPreset.find((val) => val.id === machine) - if (machineData) { - subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` - text = machineData.name ? machineData.name : machineData.id - } - return { text, subText, value: machine } - } - }) - } else { - array = machineList - .map((machine) => { + if (available.length) { + array = available.map((machine) => { if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + else { + let subText = '', + text = '' + const machineData = machinesFromPreset.find((val) => val.id === machine) + if (machineData) { + subText = `CPU: ${machineData.limits.cpu}, Memory: ${machineData.limits.memory}` + text = machineData.name ? machineData.name : machineData.id + } + return { text, subText, value: machine } + } }) - .filter((val) => !!val) + } else { + array = machineList + .map((machine) => { + if (machine === 'custom') return { text: machine, value: machine } + const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` + const text = machine + return { text, subText, value: machine } + }) + .filter((val) => !!val) + } + return array } - return array -} -function setLimits({ model, getValue, commit, watchDependency }, resource, type) { - const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' - watchDependency(`model#${path}`) - const selectedMachine = getValue(model, path) || 'custom' - const reqCommitPath = type - ? `/spec/${type}/podResources/resources/limits/${resource}` - : `/spec/podResources/resources/limits/${resource}` - const comparePath = type - ? `/spec/${type}/podResources/resources/requests/${resource}` - : `/spec/podResources/resources/requests/${resource}` - - const resourceValue = getValue(model, comparePath) - const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') - const available = getValue(model, '/spec/admin/machineProfiles/available') - - let cpu = '', - memory = '' - if (available.length && selectedMachine !== 'custom') { - const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) - if (machineData) { - cpu = machineData.limits.cpu - memory = machineData.limits.memory + function setLimits(resource, type) { + const path = type ? `/spec/${type}/podResources/machine` : '/spec/podResources/machine' + // watchDependency(`model#${path}`) + const selectedMachine = getValue(model, path) || 'custom' + const reqCommitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + const comparePath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + + const resourceValue = getValue(model, comparePath) + const machinesFromPreset = getValue(model, '/spec/admin/machineProfiles/machines') + const available = getValue(model, '/spec/admin/machineProfiles/available') + + let cpu = '', + memory = '' + if (available.length && selectedMachine !== 'custom') { + const machineData = machinesFromPreset.find((val) => val.id === selectedMachine) + if (machineData) { + cpu = machineData.limits.cpu + memory = machineData.limits.memory + } + } else { + if (selectedMachine === 'custom') { + cpu = resourceValue + memory = resourceValue + } else { + cpu = machines[selectedMachine].resources.limits.cpu + memory = machines[selectedMachine].resources.limits.memory + } } - } else { - if (selectedMachine === 'custom') { - cpu = resourceValue - memory = resourceValue + + if (resource === 'memory') { + commit('wizard/model$update', { + path: reqCommitPath, + value: memory, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: memory, + force: true, + }) + return memory } else { - cpu = machines[selectedMachine].resources.limits.cpu - memory = machines[selectedMachine].resources.limits.memory + commit('wizard/model$update', { + path: reqCommitPath, + value: cpu, + force: true, + }) + commit('wizard/model$update', { + path: comparePath, + value: cpu, + force: true, + }) + return cpu } } - if (resource === 'memory') { + function setRequests(resource, type) { + const modelPath = type + ? `/spec/${type}/podResources/resources/requests/${resource}` + : `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + const commitPath = type + ? `/spec/${type}/podResources/resources/limits/${resource}` + : `/spec/podResources/resources/limits/${resource}` + + const fullpath = `/spec/podResources/machine` + const modelPathValue = getValue(model, fullpath) + commit('wizard/model$update', { - path: reqCommitPath, - value: memory, + path: commitPath, + value: val, force: true, }) - commit('wizard/model$update', { - path: comparePath, - value: memory, - force: true, + + if (modelPathValue === 'custom') { + return + } + let commitCpuMemory, ModelPathValue + if (resource && type) { + const fullPath = `/spec/${type}/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/${type}/podResources/resources/requests/${resource}` + } else { + const fullPath = `/spec/podResources/machine` + ModelPathValue = getValue(model, fullPath) + commitCpuMemory = `spec/podResources/resources/requests/${resource}` + } + let cpuMemoryValue + array.forEach((item) => { + if (item.value === ModelPathValue) { + // Parse subText like "CPU: 2, Memory: 2Gi" + const subText = item.subText || '' + if (resource === 'cpu') { + // Extract CPU value + const cpuMatch = subText.match(/CPU:\s*([^,]+)/) + cpuMemoryValue = cpuMatch ? cpuMatch[1].trim() : '' + } else if (resource === 'memory') { + // Extract Memory value + const memoryMatch = subText.match(/Memory:\s*(.+)/) + cpuMemoryValue = memoryMatch ? memoryMatch[1].trim() : '' + } + } }) - return memory - } else { commit('wizard/model$update', { - path: reqCommitPath, - value: cpu, + path: commitCpuMemory, + value: cpuMemoryValue, force: true, }) + return cpuMemoryValue + } + + function setRequests(resource) { + const modelPath = `/spec/podResources/resources/requests/${resource}` + const val = getValue(model, modelPath) + commitPath = `/spec/podResources/resources/limits/${resource}` commit('wizard/model$update', { - path: comparePath, - value: cpu, + path: commitPath, + value: val, force: true, }) - return cpu } -} -function setRequests({ getValue, model, commit }, resource) { - const modelPath = `/spec/podResources/resources/requests/${resource}` - const val = getValue(model, modelPath) - commitPath = `/spec/podResources/resources/limits/${resource}` - commit('wizard/model$update', { - path: commitPath, - value: val, - force: true, - }) -} + function setMachineToCustom() { + const machine = getValue(model, '/spec/admin/machineProfiles/default') + return machine || 'custom' + } -function setMachineToCustom({ getValue, model }) { - const machine = getValue(model, '/spec/admin/machineProfiles/default') - return machine || 'custom' -} + async function fetchJsons(itemCtx) { + let ui = {} + let language = {} + let functions = {} + const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart -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) + } - 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, + } } - return { - ui: ui.data || {}, - language: language.data || {}, - functions, - } -} + function updateAgentValue(val) { + commit('wizard/model$update', { + path: '/spec/monitoring/agent', + value: val ? 'prometheus.io/operator' : '', + force: true, + }) -function updateAgentValue({ commit }, val) { - commit('wizard/model$update', { - path: '/spec/monitoring/agent', - value: val ? 'prometheus.io/operator' : '', - force: true, - }) - - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: val ? 'warning' : 'none', - force: true, - }) -} + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: val ? 'warning' : 'none', + force: true, + }) + } -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function getCreateNameSpaceUrl() { + 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + const domain = storeGet('/domain') || '' + if (domain.includes('bb.test')) { + return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } } -} -const ifCapiProviderIsNotEmpty = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/provider') - const val = getValue(model, '/form/capi/provider') - if (val) return true -} + const ifCapiProviderIsNotEmpty = () => { + // watchDependency('model#/form/capi/provider') + const val = getValue(model, '/form/capi/provider') + if (val) return true + } -const showMultiselectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') + const showMultiselectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') - if (val === 'capz' && ifDedicated({ model, getValue })) return true -} + if (val === 'capz' && ifDedicated()) return true + } -const showSelectZone = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/dedicated') - const val = getValue(model, '/form/capi/provider') - if (val !== 'capz' && ifDedicated({ model, getValue })) return true -} + const showSelectZone = () => { + // watchDependency('model#/form/capi/dedicated') + const val = getValue(model, '/form/capi/provider') + if (val !== 'capz' && ifDedicated()) return true + } -const ifDedicated = ({ model, getValue }) => { - const val = getValue(model, 'form/capi/dedicated') - if (val) return true -} + const ifDedicated = () => { + const val = getValue(model, 'form/capi/dedicated') + if (val) return true + } -const dedicatedOnChange = ({ model, getValue, commit }) => { - const val = getValue(model, 'form/capi/dedicated') - if (!val) { - commit('wizard/model$delete', 'form/capi/zones') - commit('wizard/model$delete', 'form/capi/sku') + const dedicatedOnChange = () => { + const val = getValue(model, 'form/capi/dedicated') + if (!val) { + commit('wizard/model$delete', 'form/capi/zones') + commit('wizard/model$delete', 'form/capi/sku') + } } -} -const ifZones = ({ model, getValue, watchDependency }) => { - watchDependency('model#/form/capi/zones') - watchDependency('model#/form/capi/dedicated') - const zones = getValue(model, 'form/capi/zones') || [] - const isDedicated = getValue(model, 'form/capi/dedicated') - if (zones.length && isDedicated) return true -} + const ifZones = () => { + // watchDependency('model#/form/capi/zones') + // watchDependency('model#/form/capi/dedicated') + const zones = getValue(model, 'form/capi/zones') || [] + const isDedicated = getValue(model, 'form/capi/dedicated') + if (zones.length && isDedicated) return true + } -const zonesOnChange = ({ model, getValue, commit }) => { - const zones = getValue(model, 'form/capi/zones') || [] - if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') -} + const zonesOnChange = () => { + const zones = getValue(model, 'form/capi/zones') || [] + if (!zones.length) commit('wizard/model$delete', 'form/capi/sku') + } -async function getZones({ storeGet, axios, model, getValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const isDedicated = getValue(model, 'form/capi/dedicated') - if (isDedicated) { - try { - const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) - const val = resp.data.map((item) => { - return { value: item, text: item } - }) - return val - } catch (e) { - console.log(e) - return [] + async function getZones() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const isDedicated = getValue(model, 'form/capi/dedicated') + if (isDedicated) { + try { + const resp = await axios.get(`clustersv2/${owner}/${cluster}/zones`) + const val = resp.data.map((item) => { + return { value: item, text: item } + }) + return val + } catch (e) { + console.log(e) + return [] + } } } -} -async function getSKU({ storeGet, axios, model, getValue, watchDependency }) { - watchDependency('model#/form/capi/zones') - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const zones = getValue(model, 'form/capi/zones') || [] - if (zones.length) { - try { - let url = `clustersv2/${owner}/${cluster}/vms?` - if (typeof zones === 'string') { - url += `zones=${encodeURIComponent(zones)}` - } else { - zones.forEach((item) => { - url += `zones=${encodeURIComponent(item)}&` + async function getSKU() { + // watchDependency('model#/form/capi/zones') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const zones = getValue(model, 'form/capi/zones') || [] + if (zones.length) { + try { + let url = `clustersv2/${owner}/${cluster}/vms?` + if (typeof zones === 'string') { + url += `zones=${encodeURIComponent(zones)}` + } else { + zones.forEach((item) => { + url += `zones=${encodeURIComponent(item)}&` + }) + url = url.slice(0, -1) + } + const resp = await axios.get(url) + const val = resp.data.map((item) => { + return { + value: item.name, + text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, + } }) - url = url.slice(0, -1) + return val + } catch (e) { + console.log(e) + return [] } - const resp = await axios.get(url) - const val = resp.data.map((item) => { - return { - value: item.name, - text: `${item.name} [CPU: ${item.cpu}] [Memory: ${item.memory}mb] `, - } - }) - return val - } catch (e) { - console.log(e) - return [] } } -} - -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} -function setStorageClass({ model, getValue, commit, watchDependency, discriminator }) { - const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' - let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' - const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] - const suffix = '-retain' - - const simpleClassList = storageClassList.filter((item) => { - return !item.endsWith(suffix) - }) - const retainClassList = storageClassList.filter((item) => { - return item.endsWith(suffix) - }) - if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { - storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] - } else { - storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false } - const isChangeable = isToggleOn( - { getValue, model, watchDependency, discriminator }, - 'storageClasses', - ) - if (isChangeable && storageClass) { - commit('wizard/model$update', { - path: '/spec/admin/storageClasses/default', - value: storageClass, - force: true, - }) - } -} + function setStorageClass() { + const deletionPolicy = getValue(model, '/spec/deletionPolicy') || '' + let storageClass = getValue(model, '/spec/admin/storageClasses/default') || '' + const storageClassList = getValue(model, '/spec/admin/storageClasses/available') || [] + const suffix = '-retain' -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], - }, - }, - ) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace + const simpleClassList = storageClassList.filter((item) => { + return !item.endsWith(suffix) + }) + const retainClassList = storageClassList.filter((item) => { + return item.endsWith(suffix) + }) + if (deletionPolicy === 'WipeOut' || deletionPolicy === 'Delete') { + storageClass = simpleClassList.length ? simpleClassList[0] : retainClassList[0] } else { - return resp.data?.status?.namespaces || [] + storageClass = retainClassList.length ? retainClassList[0] : simpleClassList[0] } - } catch (e) { - console.log(e) - } - return [] -} - -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} -let placement = [] -let versions = [] -let storageClass = [] -let clusterIssuers = [] -let nodetopologiesShared = [] -let nodetopologiesDedicated = [] -let features = [] -async function initBundle({ commit, model, getValue, axios, storeGet, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/release/namespace') - - let db = getValue(model, '/metadata/resource/kind') - db = db.toLowerCase() - let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` - const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` - - try { - const resp = await axios.get(url) - features = resp.data.features || [] - placement = resp.data.placementpolicies || [] - versions = resp.data.versions || [] - storageClass = resp.data.storageclasses || [] - clusterIssuers = resp.data.clusterissuers || [] - nodetopologiesDedicated = resp.data.dedicated || [] - nodetopologiesShared = resp.data.shared || [] - - const response = await axios.get(annotationUrl) - const annotations = response.data?.metadata?.annotations || {} - const uidRange = annotations['openshift.io/sa.scc.uid-range'] - if (uidRange) { - const val = uidRange.split('/')[0] + const isChangeable = isToggleOn('storageClasses') + if (isChangeable && storageClass) { commit('wizard/model$update', { - path: '/spec/openshift/securityContext/runAsUser', - value: val, + path: '/spec/admin/storageClasses/default', + value: storageClass, force: true, }) } - } catch (e) { - console.log(e) } - commit('wizard/model$update', { - path: '/spec/deletionPolicy', - value: getDefault({ getValue, model }, 'deletionPolicy'), - force: true, - }) - - if (!getValue(model, `/spec/admin/databases/ZooKeeper/mode/toggle`)) { - let defMode = getDefault({ getValue, model }, 'databases/ZooKeeper/mode') || '' - if (defMode === '') { - const arr = getValue(model, '/spec/databases/ZooKeeper/mode/available') || [] - if (arr.length) defMode = arr[0] + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, + }, + ) + if (resp.data?.status?.projects) { + const projects = resp.data?.status?.projects + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } + } catch (e) { + console.log(e) } - commit('wizard/model$update', { - path: '/spec/mode', - value: defMode, - force: true, - }) + return [] } - if (!features.includes('tls')) { - commit('wizard/model$update', { - path: '/spec/admin/tls/default', - value: false, - force: true, - }) - } - if (!features.includes('binding')) { - commit('wizard/model$update', { - path: '/spec/admin/expose/default', - value: false, - force: true, - }) - } - if (!features.includes('monitoring')) { - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: 'none', - force: true, - }) - } - if (!features.includes('backup')) { - commit('wizard/model$update', { - path: '/spec/admin/archiver/enable/default', - value: false, - force: true, - }) - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: '', - force: true, - }) + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found } - setDiscriminatorValue('/bundleApiLoaded', true) -} + async function initBundle() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/release/namespace') -function fetchOptions({ model, getValue, commit }, type) { - let kind = getValue(model, '/metadata/resource/kind') - - let returnArray = [] - if (type === 'clusterTier/placement') { - returnArray = placement - } else if (type === `databases/${kind}/versions`) { - returnArray = versions - } else if (type === 'storageClasses') { - returnArray = storageClass - } else if (type === 'clusterIssuers') { - returnArray = clusterIssuers - } + let db = getValue(model, '/metadata/resource/kind') + db = db.toLowerCase() + let url = `clusters/${owner}/${cluster}/db-bundle?type=features,common,versions&db-singular=${db}` + const annotationUrl = `clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}` + + try { + const resp = await axios.get(url) + features = resp.data.features || [] + placement = resp.data.placementpolicies || [] + versions = resp.data.versions || [] + storageClass = resp.data.storageclasses || [] + clusterIssuers = resp.data.clusterissuers || [] + nodetopologiesDedicated = resp.data.dedicated || [] + nodetopologiesShared = resp.data.shared || [] + + const response = await axios.get(annotationUrl) + const annotations = response.data?.metadata?.annotations || {} + const uidRange = annotations['openshift.io/sa.scc.uid-range'] + if (uidRange) { + const val = uidRange.split('/')[0] + commit('wizard/model$update', { + path: '/spec/openshift/securityContext/runAsUser', + value: val, + force: true, + }) + } + } catch (e) { + console.log(e) + } - if (returnArray.length === 1) { - const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: path, - value: returnArray[0], + path: '/spec/deletionPolicy', + value: getDefault('deletionPolicy'), force: true, }) - } - return returnArray -} - -function getAdminOptions({ getValue, model, watchDependency, commit }, type) { - watchDependency('discriminator#/bundleApiLoaded') + if (!getValue(model, `/spec/admin/databases/ZooKeeper/mode/toggle`)) { + let defMode = getDefault('databases/ZooKeeper/mode') || '' + if (defMode === '') { + const arr = getValue(model, '/spec/databases/ZooKeeper/mode/available') || [] + if (arr.length) defMode = arr[0] + } + commit('wizard/model$update', { + path: '/spec/mode', + value: defMode, + force: true, + }) + } - const options = getValue(model, `/spec/admin/${type}/available`) || [] + if (!features.includes('tls')) { + commit('wizard/model$update', { + path: '/spec/admin/tls/default', + value: false, + force: true, + }) + } + if (!features.includes('binding')) { + commit('wizard/model$update', { + path: '/spec/admin/expose/default', + value: false, + force: true, + }) + } + if (!features.includes('monitoring')) { + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: 'none', + force: true, + }) + } + if (!features.includes('backup')) { + commit('wizard/model$update', { + path: '/spec/admin/archiver/enable/default', + value: false, + force: true, + }) + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: '', + force: true, + }) + } - if (options.length === 0) { - return fetchOptions({ model, getValue, commit }, type) + setDiscriminatorValue('/bundleApiLoaded', true) } - if (type.endsWith('/mode')) { - return ( - options?.map((item) => ({ - description: modeDetails[item]?.description || '', - text: modeDetails[item]?.text || '', - value: item, - })) || [] - ) - } - return options -} -function checkIfFeatureOn({ getValue, model }, type) { - let val = getValue(model, `/spec/admin/${type}/toggle`) - if (type === 'backup' || type === 'archiver') { - val = getValue(model, `/spec/admin/${type}/enable/toggle`) - } - const backupVal = getValue(model, '/spec/backup/tool') - - if (type === 'backup') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } else if (type === 'tls') { - return features.includes('tls') && val - } else if (type === 'expose') { - return features.includes('binding') && val - } else if (type === 'monitoring') { - return features.includes('monitoring') && val - } else if (type === 'archiver') { - return features.includes('backup') && backupVal === 'KubeStash' && val - } -} + function fetchOptions(type) { + let kind = getValue(model, '/metadata/resource/kind') + + let returnArray = [] + if (type === 'clusterTier/placement') { + returnArray = placement + } else if (type === `databases/${kind}/versions`) { + returnArray = versions + } else if (type === 'storageClasses') { + returnArray = storageClass + } else if (type === 'clusterIssuers') { + returnArray = clusterIssuers + } -function isToggleOn({ getValue, model, discriminator, watchDependency }, type) { - watchDependency('discriminator#/bundleApiLoaded') - watchDependency('model#/spec/admin/deployment/default') - const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') - let deploymentType = getValue(model, `/spec/admin/deployment/default`) - if ( - type === 'tls' || - type === 'backup' || - type === 'expose' || - type === 'monitoring' || - type === 'archiver' - ) { - return checkIfFeatureOn({ getValue, model }, type) - } else if ( - type === 'clusterTier' || - type === 'clusterTier/placement' || - type === 'clusterTier/nodeTopology' - ) { - if (deploymentType === 'Dedicated' && bundleApiLoaded) return true - else return false - } else if (type === 'deployment') { - const deploymentType = getValue(model, '/spec/admin/deployment/default') - if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + if (returnArray.length === 1) { + const path = `/spec/admin/${type}/default` commit('wizard/model$update', { - path: '/spec/admin/deployment/default', - value: 'Shared', + path: path, + value: returnArray[0], force: true, }) } - return ( - getValue(model, `/spec/admin/${type}/toggle`) && - nodetopologiesDedicated.length && - bundleApiLoaded - ) - } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded -} -async function getNodeTopology({ model, getValue, axios, storeGet, watchDependency }) { - watchDependency('model#/spec/admin/deployment/default') - watchDependency('model#/spec/admin/clusterTier/default') - const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' - const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' - let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + return returnArray + } - const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + function getAdminOptions(type) { + // watchDependency('discriminator#/bundleApiLoaded') - if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared - else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + const options = getValue(model, `/spec/admin/${type}/available`) || [] - const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) - return filteredList -} + if (options.length === 0) { + return fetchOptions(type) + } + if (type.endsWith('/mode')) { + return ( + options?.map((item) => ({ + description: modeDetails[item]?.description || '', + text: modeDetails[item]?.text || '', + value: item, + })) || [] + ) + } + return options + } + + function checkIfFeatureOn(type) { + let val = getValue(model, `/spec/admin/${type}/toggle`) + if (type === 'backup' || type === 'archiver') { + val = getValue(model, `/spec/admin/${type}/enable/toggle`) + } + const backupVal = getValue(model, '/spec/backup/tool') + + if (type === 'backup') { + return features.includes('backup') && backupVal === 'KubeStash' && val + } else if (type === 'tls') { + return features.includes('tls') && val + } else if (type === 'expose') { + return features.includes('binding') && val + } else if (type === 'monitoring') { + return features.includes('monitoring') && val + } else if (type === 'archiver') { + return features.includes('backup') && backupVal === 'KubeStash' && val + } + } -function filterNodeTopology(list, tier, provider) { - // first filter the list from value that exists from the filtered list got from API - const filteredlist = list + function isToggleOn(type) { + // watchDependency('discriminator#/bundleApiLoaded') + // watchDependency('model#/spec/admin/deployment/default') + const bundleApiLoaded = getValue(discriminator, '/bundleApiLoaded') + let deploymentType = getValue(model, `/spec/admin/deployment/default`) + if ( + type === 'tls' || + type === 'backup' || + type === 'expose' || + type === 'monitoring' || + type === 'archiver' + ) { + return checkIfFeatureOn(type) + } else if ( + type === 'clusterTier' || + type === 'clusterTier/placement' || + type === 'clusterTier/nodeTopology' + ) { + if (deploymentType === 'Dedicated' && bundleApiLoaded) return true + else return false + } else if (type === 'deployment') { + const deploymentType = getValue(model, '/spec/admin/deployment/default') + if (!nodetopologiesDedicated.length && deploymentType === 'Dedicated') { + commit('wizard/model$update', { + path: '/spec/admin/deployment/default', + value: 'Shared', + force: true, + }) + } + return ( + getValue(model, `/spec/admin/${type}/toggle`) && + nodetopologiesDedicated.length && + bundleApiLoaded + ) + } else return getValue(model, `/spec/admin/${type}/toggle`) && bundleApiLoaded + } - // filter the list based on clusterTier - if (provider === 'EKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('c') - else if (tier === 'MemoryOptimized') return item.startsWith('r') - else return !item.startsWith('c') && !item.startsWith('r') - }) - } else if (provider === 'AKS') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('e') || - item.startsWith('eb') || - item.startsWith('ec') || - item.startsWith('m') || - item.startsWith('d') - ) - else - return ( - !(item.startsWith('f') || item.startsWith('fx')) && - !( + async function getNodeTopology() { + // watchDependency('model#/spec/admin/deployment/default') + // watchDependency('model#/spec/admin/clusterTier/default') + const deploymentType = getValue(model, '/spec/admin/deployment/default') || '' + const clusterTier = getValue(model, '/spec/admin/clusterTier/default') || '' + let nodeTopologyList = getValue(model, `/spec/admin/clusterTier/nodeTopology/available`) || [] + + const provider = storeGet('/cluster/clusterDefinition/result/provider') || '' + + if (deploymentType === 'Shared') nodeTopologyList = nodetopologiesShared + else if (deploymentType === 'Dedicated') nodeTopologyList = nodetopologiesDedicated + + const filteredList = filterNodeTopology(nodeTopologyList, clusterTier, provider) + return filteredList + } + + function filterNodeTopology(list, tier, provider) { + // first filter the list from value that exists from the filtered list got from API + const filteredlist = list + + // filter the list based on clusterTier + if (provider === 'EKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('c') + else if (tier === 'MemoryOptimized') return item.startsWith('r') + else return !item.startsWith('c') && !item.startsWith('r') + }) + } else if (provider === 'AKS') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') return item.startsWith('f') || item.startsWith('fx') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('e') || item.startsWith('eb') || item.startsWith('ec') || item.startsWith('m') || item.startsWith('d') ) - ) - }) - } else if (provider === 'GKE') { - return filteredlist.filter((item) => { - if (tier === 'CPUOptimized') - return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') - else if (tier === 'MemoryOptimized') - return ( - item.startsWith('x4') || - item.startsWith('m1') || - item.startsWith('m2') || - item.startsWith('m3') - ) - else - return ( - !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && - !( + else + return ( + !(item.startsWith('f') || item.startsWith('fx')) && + !( + item.startsWith('e') || + item.startsWith('eb') || + item.startsWith('ec') || + item.startsWith('m') || + item.startsWith('d') + ) + ) + }) + } else if (provider === 'GKE') { + return filteredlist.filter((item) => { + if (tier === 'CPUOptimized') + return item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d') + else if (tier === 'MemoryOptimized') + return ( item.startsWith('x4') || item.startsWith('m1') || item.startsWith('m2') || item.startsWith('m3') ) - ) - }) - } else return filteredlist -} + else + return ( + !(item.startsWith('h3') || item.startsWith('c2') || item.startsWith('c2d')) && + !( + item.startsWith('x4') || + item.startsWith('m1') || + item.startsWith('m2') || + item.startsWith('m3') + ) + ) + }) + } else return filteredlist + } -function returnFalse() { - return false -} + function returnFalse() { + return false + } -function isMachineCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue === 'custom' -} + function isMachineCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue === 'custom' + } -function isMachineNotCustom({ model, getValue, watchDependency }, path) { - const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' - const modelPathValue = getValue(model, fullpath) - watchDependency(`model#${fullpath}`) - return modelPathValue !== 'custom' && !!modelPathValue -} + function isMachineNotCustom(path) { + const fullpath = path ? `/spec/${path}/podResources/machine` : '/spec/podResources/machine' + const modelPathValue = getValue(model, fullpath) + // watchDependency(`model#${fullpath}`) + return modelPathValue !== 'custom' && !!modelPathValue + } -function onAuthChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) - commit('wizard/model$update', { - path: '/spec/authSecret/password', - value: '', - force: true, - }) -} + function onAuthChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/spec/authSecret/password', + value: '', + force: true, + }) + } -function clearConfiguration({ discriminator, getValue, commit }) { - const configOn = getValue(discriminator, '/configDatabase') + function clearConfiguration() { + const configOn = getValue(discriminator, '/configDatabase') - if (!configOn) { - commit('wizard/model$delete', '/spec/configuration') + if (!configOn) { + commit('wizard/model$delete', '/spec/configuration') + } } -} -function isConfigDatabaseOn({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/configDatabase') - return getValue(discriminator, '/configDatabase') -} + function isConfigDatabaseOn() { + // watchDependency('discriminator#/configDatabase') + return getValue(discriminator, '/configDatabase') + } -function showIssuer({ model, getValue, watchDependency, discriminator }) { - watchDependency('model#/spec/admin/tls/default') - const isTlsEnabled = getValue(model, '/spec/admin/tls/default') - const isIssuerToggleEnabled = isToggleOn( - { getValue, model, watchDependency, discriminator }, - 'clusterIssuers', - ) - return isTlsEnabled && isIssuerToggleEnabled -} + function showIssuer() { + // watchDependency('model#/spec/admin/tls/default') + const isTlsEnabled = getValue(model, '/spec/admin/tls/default') + const isIssuerToggleEnabled = isToggleOn('clusterIssuers') + return isTlsEnabled && isIssuerToggleEnabled + } -function setMonitoring({ getValue, model }) { - const agent = getValue(model, '/spec/admin/monitoring/agent') || '' - return !!agent -} + function setMonitoring() { + const agent = getValue(model, '/spec/admin/monitoring/agent') || '' + return !!agent + } -function updateAlertValue({ commit, model, discriminator, getValue }) { - const isMonitorEnabled = getValue(discriminator, '/monitoring') - const alert = isMonitorEnabled ? 'warning' : 'none' - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: alert, - force: true, - }) - const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' - commit('wizard/model$update', { - path: '/spec/admin/monitoring/agent', - value: agent, - force: true, - }) -} + function updateAlertValue() { + const isMonitorEnabled = getValue(discriminator, '/monitoring') + const alert = isMonitorEnabled ? 'warning' : 'none' + // update alert value depend on monitoring profile + commit('wizard/model$update', { + path: '/form/alert/enabled', + value: alert, + force: true, + }) + const agent = isMonitorEnabled ? 'prometheus.io/operator' : '' + commit('wizard/model$update', { + path: '/spec/admin/monitoring/agent', + value: agent, + force: true, + }) + } -function showAlerts({ watchDependency, model, getValue, discriminator }) { - watchDependency('discriminator#/monitoring') - const isMonitorEnabled = getValue(discriminator, '/monitoring') - return ( - isMonitorEnabled && isToggleOn({ getValue, model, watchDependency, discriminator }, 'alert') - ) -} + function showAlerts() { + // watchDependency('discriminator#/monitoring') + const isMonitorEnabled = getValue(discriminator, '/monitoring') + return isMonitorEnabled && isToggleOn('alert') + } -function setBackup({ model, getValue }) { - const backup = getValue(model, '/spec/backup/tool') - const val = getValue(model, '/spec/admin/backup/enable/default') - return backup === 'KubeStash' && features.includes('backup') && val -} + function setBackup() { + const backup = getValue(model, '/spec/backup/tool') + const val = getValue(model, '/spec/admin/backup/enable/default') + return backup === 'KubeStash' && features.includes('backup') && val + } -function onBackupSwitch({ discriminator, getValue, commit }) { - const isBackupOn = getValue(discriminator, '/backup') - commit('wizard/model$update', { - path: '/spec/backup/tool', - value: isBackupOn ? 'KubeStash' : '', - force: true, - }) -} + function onBackupSwitch() { + const isBackupOn = getValue(discriminator, '/backup') + commit('wizard/model$update', { + path: '/spec/backup/tool', + value: isBackupOn ? 'KubeStash' : '', + force: true, + }) + } -function showAdditionalSettings({ watchDependency }) { - watchDependency('discriminator#/bundleApiLoaded') - return features.length -} + function showAdditionalSettings() { + // watchDependency('discriminator#/bundleApiLoaded') + return features.length + } -function getDefault({ getValue, model }, type) { - const val = getValue(model, `/spec/admin/${type}/default`) || '' - return val -} + function getDefault(type) { + const val = getValue(model, `/spec/admin/${type}/default`) || '' + return val + } -function isConfigAvailable({ getValue, model }) { - const val = getValue(model, '/spec/configuration') - return val !== '' -} + async function getReferSecrets() { + const referSecret = getValue(discriminator, '/referSecret') + if (!referSecret) { + return [] + } -async function getReferSecrets({ getValue, model, storeGet, axios, discriminator }) { - const referSecret = getValue(discriminator, '/referSecret') - if (!referSecret) { - return [] + const params = storeGet('/route/params') + const { user, cluster } = params + const namespace = getValue(model, `/metadata/release/namespace`) + let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` + + const options = [] + try { + const resp = await axios.get(url) + const items = resp.data?.items + items.forEach((ele) => { + options.push(ele.metadata?.name) + }) + } catch (e) { + console.log(e) + } + return options } - const params = storeGet('/route/params') - const { user, cluster } = params - const namespace = getValue(model, `/metadata/release/namespace`) - let url = `/clusters/${user}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets` - - const options = [] - try { - const resp = await axios.get(url) - const items = resp.data?.items - items.forEach((ele) => { - options.push(ele.metadata?.name) - }) - } catch (e) { - console.log(e) + function showAuthPasswordField() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !modelPathValue && showReferSecret() } - return options -} -function showAuthPasswordField({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showSecretDropdown() { + const modelPathValue = getValue(discriminator, '/referSecret') + // watchDependency('discriminator#/referSecret') + return !!modelPathValue && showReferSecret() + } -function showSecretDropdown({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/referSecret') - watchDependency('discriminator#/referSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function showReferSecret() { + const modelPathValue = getValue(discriminator, '/createAuthSecret') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue + } -function showReferSecret({ discriminator, getValue, watchDependency }) { - const modelPathValue = getValue(discriminator, '/createAuthSecret') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue -} + function getDefaultValue(path) { + const val = getValue(model, `/${path}`) || '' + return val + } -function getDefaultValue({ getValue, model }, path) { - const val = getValue(model, `/${path}`) || '' - return val -} + function showReferSecretSwitch() { + const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') + // watchDependency('discriminator#/createAuthSecret') + return !!modelPathValue && showReferSecret() + } -function showReferSecretSwitch({ model, getValue, watchDependency, discriminator }) { - const modelPathValue = getValue(model, '/spec/admin/authCredential/referExisting') - watchDependency('discriminator#/createAuthSecret') - return !!modelPathValue && showReferSecret({ discriminator, getValue, watchDependency }) -} + function onReferSecretChange() { + commit('wizard/model$update', { + path: '/spec/authSecret/name', + value: '', + force: true, + }) + } -function onReferSecretChange({ commit }) { - commit('wizard/model$update', { - path: '/spec/authSecret/name', - value: '', - force: true, - }) -} + function setResourceLimit() { + // This function is referenced in the watcher but needs to be defined + // Add your implementation here if needed + } -return { - showReferSecretSwitch, - onReferSecretChange, - getDefaultValue, - isRancherManaged, - showSecretDropdown, - showReferSecret, - getReferSecrets, - isConfigAvailable, - initBundle, - returnFalse, - isVariantAvailable, - fetchJsons, - showAuthPasswordField, - isEqualToModelPathValue, - showAuthSecretField, - showStorageSizeField, - getResources, - getMongoDbVersions, - onCreateAuthSecretChange, - getSecrets, - getMachineListForOptions, - setLimits, - setRequests, - setMachineToCustom, - updateAgentValue, - getCreateNameSpaceUrl, - ifCapiProviderIsNotEmpty, - ifDedicated, - dedicatedOnChange, - ifZones, - zonesOnChange, - getZones, - getSKU, - showMultiselectZone, - showSelectZone, - setStorageClass, - getNamespaces, - isToggleOn, - getAdminOptions, - getNodeTopology, - filterNodeTopology, - isMachineNotCustom, - isMachineCustom, - onAuthChange, - clearConfiguration, - isConfigDatabaseOn, - showIssuer, - setMonitoring, - updateAlertValue, - showAlerts, - onBackupSwitch, - setBackup, - showAdditionalSettings, - getDefault, + return { + showReferSecretSwitch, + onReferSecretChange, + getDefaultValue, + isRancherManaged, + showSecretDropdown, + showReferSecret, + getReferSecrets, + initBundle, + returnFalse, + isVariantAvailable, + fetchJsons, + showAuthPasswordField, + isEqualToModelPathValue, + showAuthSecretField, + showStorageSizeField, + getResources, + getMongoDbVersions, + onCreateAuthSecretChange, + getSecrets, + getMachineListForOptions, + setLimits, + setRequests, + setMachineToCustom, + updateAgentValue, + getCreateNameSpaceUrl, + ifCapiProviderIsNotEmpty, + ifDedicated, + dedicatedOnChange, + ifZones, + zonesOnChange, + getZones, + getSKU, + showMultiselectZone, + showSelectZone, + setStorageClass, + getNamespaces, + isToggleOn, + getAdminOptions, + getNodeTopology, + filterNodeTopology, + isMachineNotCustom, + isMachineCustom, + onAuthChange, + clearConfiguration, + isConfigDatabaseOn, + showIssuer, + setMonitoring, + updateAlertValue, + showAlerts, + onBackupSwitch, + setBackup, + showAdditionalSettings, + getDefault, + setResourceLimit, + } } diff --git a/charts/kubedbcom-zookeeper-editor/ui/edit-ui.yaml b/charts/kubedbcom-zookeeper-editor/ui/edit-ui.yaml index 1ddc1cf03d..90e17d6728 100644 --- a/charts/kubedbcom-zookeeper-editor/ui/edit-ui.yaml +++ b/charts/kubedbcom-zookeeper-editor/ui/edit-ui.yaml @@ -1,577 +1,630 @@ -steps: -- form: - elements: - - disabled: true - label: - text: labels.database.name - onChange: onNameChange - schema: - $ref: schema#/properties/metadata/properties/release/properties/name - type: input - type: single-step-form - id: basic - title: steps.0.label -- form: - discriminator: - scheduleBackup: - default: "yes" - type: string - elements: - - discriminator: - backupType: - type: string - isBackupDataLoaded: - default: false - type: boolean - elements: - - computed: initBackupData - if: returnFalse - type: input - - computed: setBackupType - fetch: getTypes - hasDescription: true - if: isBackupDataLoadedTrue - label: - text: Select Backup Type - onChange: onBackupTypeChange - schema: - $ref: discriminator#/backupType - type: radio - - discriminator: - backupConfigContext: - type: string - config: - type: string - paused: - default: false - type: boolean - schedule: - type: string - elements: - - fetch: getContext - label: - text: Select Context - onChange: onContextChange - required: true - schema: - $ref: discriminator#/backupConfigContext - type: select - - fetch: getConfigList - if: showConfigList - label: - text: Select BackupConfig - onChange: onConfigChange - required: true - schema: - $ref: discriminator#/config - type: select - - computed: getDefaultSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions - if: showSchedule - label: - text: Schedule - onChange: onInputChangeSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions|schedule - required: true - schema: - $ref: discriminator#/schedule - type: input - - if: showPause - label: - text: Paused - schema: - $ref: schema#/properties/resources/properties/coreKubestashComBackupConfiguration/properties/spec/properties/paused - type: switch - if: isBackupType|BackupConfig - type: single-step-form - - discriminator: - blueprintEnabled: - default: false - type: boolean - elements: - - computed: setBlueprintSwitch - label: - text: Enable Backup Blueprint - onChange: onBlueprintChange - schema: - $ref: discriminator#/blueprintEnabled - type: switch - if: isBackupType|BackupBlueprint - type: single-step-form - - discriminator: - archiverEnabled: - default: false - type: boolean - elements: - - computed: setArchiverSwitch - label: - text: Enable Archiver - onChange: onArchiverChange - schema: - $ref: discriminator#/archiverEnabled - type: switch - if: isBackupType|Archiver - type: single-step-form - label: - text: Backup Form - type: single-step-form - type: single-step-form - id: backupconfiguration - title: steps.4.label -- form: - discriminator: - dbDetails: - default: false - type: boolean +type: multi-step-form +step: + - type: single-step-form + id: backupconfiguration + # label: Backup + schema: schema/ elements: - - computed: getDbDetails - if: returnFalse - type: input - - elements: - - label: - text: Name - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/metadata/properties/name - type: input - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: SelectNamespace - onChange: onNamespaceChange - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/metadata/properties/namespace - type: select - - fetch: getDbs - label: - text: Select Db - onChange: initMetadata - refresh: true - required: true - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/databaseRef/properties/name - type: select - if: isConsole - type: single-step-form - - hasDescription: true - if: isConsole - label: - text: Select Type - onChange: initMetadata + - type: radio + label: Schedule a Backup? + schema: temp/properties/scheduleBackup + isHorizontal: true 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 - required: true - schema: - $ref: discriminator#/properties/autoscalingType - type: radio - - discriminator: - topologyMachines: - default: [] - type: array + - text: 'Yes' + value: 'yes' + - text: 'No' + value: 'no' + if: + type: function + name: showScheduleBackup + init: + type: func + value: initScheduleBackupForEdit + watcher: + func: onScheduleBackupChange + paths: + - temp/properties/scheduleBackup + - type: block-layout + label: Backup Form + showLabels: false + loader: initBackupData + if: + type: function + name: showBackupForm elements: - - fetch: fetchTopologyMachines - if: returnFalse - schema: - $ref: discriminator#/topologyMachines - type: input - - elements: - - computed: setTrigger|autoscalingKubedbComZooKeeperAutoscaler/spec/compute/zookeeper/trigger - label: - text: Trigger + - type: radio + label: Select Backup Type + schema: temp/properties/backupType + isHorizontal: true options: - - "On" - - "Off" - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/zookeeper/properties/trigger - type: select - - label: - text: Pod LifeTime Threshold - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/zookeeper/properties/podLifeTimeThreshold - type: input - - label: - text: Resource Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/zookeeper/properties/resourceDiffPercentage - type: input - - discriminator: - allowedMachine-max: - type: string - allowedMachine-min: - type: string + - text: BackupConfig + value: BackupConfig + description: 'Create, Delete or Modify BackupConfig' + - text: BackupBlueprint + value: BackupBlueprint + description: Enable/Disable BackupBlueprint + if: + type: function + name: isBackupDataLoadedTrue + init: + type: func + value: setBackupType + loader: getTypes + watcher: + func: onBackupTypeChange + paths: + - temp/properties/backupType + - type: block-layout + label: Config + if: + type: function + name: isBackupType|BackupConfig elements: - - computed: setAllowedMachine|min - disableUnselect: true - fetch: getMachines|min - if: hasAnnotations - label: - text: Min Allowed Profile - onChange: onMachineChange|zookeeper - schema: - $ref: discriminator#/properties/allowedMachine-min - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/zookeeper/properties/minAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/zookeeper/properties/minAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Min Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/zookeeper/properties/minAllowed - show_label: true - type: single-step-form - - computed: setAllowedMachine|max - disableUnselect: true - fetch: getMachines|max - if: hasAnnotations - label: - text: Max Allowed Profile - onChange: onMachineChange|zookeeper - schema: - $ref: discriminator#/properties/allowedMachine-max - type: select - - elements: - - label: - text: cpu - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/zookeeper/properties/maxAllowed/properties/cpu - type: input - - label: - text: memory - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/zookeeper/properties/maxAllowed/properties/memory - type: input - if: hasNoAnnotations - label: - text: Max Allowed - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/zookeeper/properties/maxAllowed - show_label: true - type: single-step-form - type: single-step-form - - fetch: setControlledResources|zookeeper - label: - text: Controlled Resources - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/zookeeper/properties/controlledResources - type: multiselect - label: - text: Zookeeper - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/zookeeper - show_label: true - type: single-step-form - - elements: - - fetch: fetchNodeTopology - label: - text: Select Node Topology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name - type: select - - if: isNodeTopologySelected - label: - text: ScaleUp Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage - type: input - - if: isNodeTopologySelected - label: - text: ScaleDown Diff Percentage - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage - type: input - if: hasNoAnnotations - label: - text: NodeTopology - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/nodeTopology - show_label: true - type: single-step-form - type: single-step-form - - elements: - - label: - text: Timeout - options: - - text: 5 minutes - value: 5m0s - - text: 10 minutes - value: 10m0s - - text: 30 minutes - value: 30m0s - - text: 1 hour - value: 1h0m - - text: 2 hours - value: 2h0m - - text: 5 hours - value: 5h0m - - text: 10 hours - value: 10h0m - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: Apply + - type: select + label: Select Context + schema: temp/properties/backupConfigContext + validation: + type: required + loader: getContext + watcher: + func: onContextChange + paths: + - temp/properties/backupConfigContext + - type: select + label: Select BackupConfig + schema: temp/properties/config + validation: + type: required + if: + type: function + name: showConfigList + loader: getConfigList + watcher: + func: onConfigChange + paths: + - temp/properties/config + - type: input + label: Schedule + schema: temp/properties/schedule + validation: + type: required + if: + type: function + name: showSchedule + loader: + name: getDefaultSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions + watchPaths: + - temp/properties/config + watcher: + func: onInputChangeSchedule|/resources/coreKubestashComBackupConfiguration/spec/sessions|schedule + paths: + - temp/properties/schedule + - type: switch + label: Paused + fullwidth: true + schema: schema/properties/resources/properties/coreKubestashComBackupConfiguration/properties/spec/properties/paused + if: + type: function + name: showPause + watcher: + func: setPausedValue + paths: + - temp/properties/config + init: + type: func + value: setPausedValue + - type: block-layout + label: Blueprint + if: + type: function + name: isBackupType|BackupBlueprint + elements: + - type: switch + label: Enable Backup Blueprint + fullwidth: true + subtitle: Use a backup blueprint template to automatically configure backups for similar databases + schema: temp/properties/blueprintEnabled + init: + type: func + value: setBlueprintSwitch + watcher: + func: onBlueprintChange + paths: + - temp/properties/blueprintEnabled + - type: block-layout + label: Archiver + if: + type: function + name: isBackupType|Archiver + elements: + - type: switch + label: Enable Archiver + fullwidth: true + schema: temp/properties/archiverEnabled + init: + type: func + value: setArchiverSwitch + watcher: + func: onArchiverChange + paths: + - temp/properties/archiverEnabled + - type: single-step-form + id: compute-autoscaler + loader: getDbDetails + elements: + - type: block-layout + if: + type: function + name: isConsole + elements: + - type: input + label: Name + schema: schema/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/metadata/properties/name + - type: select + label: Select Namespace + loader: getNamespaces + if: + type: function + name: isRancherManaged + schema: schema/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/metadata/properties/namespace + - type: select + label: Select Db + loader: getDbs + validation: + type: required + refresh: true + schema: schema/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/databaseRef/properties/name + watcher: + func: initMetadata + paths: + - schema/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/databaseRef/properties/name + + - type: radio + if: + type: function + name: isConsole + label: Select Type + validation: + type: required + schema: temp/properties/autoscalingType + watcher: + func: initMetadata + paths: + - temp/properties/autoscalingType options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply - type: radio - if: showOpsRequestOptions - label: - text: Ops Request Options - schema: - $ref: schema#/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/opsRequestOptions - show_label: true - type: single-step-form - type: single-step-form - id: compute-autoscaler - title: steps.6.label -- form: - discriminator: - enableMonitoring: - default: true - type: boolean + - text: Compute + value: compute + description: Scale your CPU Memory based on resource usage + - text: Storage + value: storage + description: Expand your database size based on volume usage + + - type: block-layout + showLabels: false + loader: fetchTopologyMachines + elements: + # zookeeper mode + - type: switch + label: Trigger + fullwidth: true + init: + type: func + value: setTrigger|autoscalingKubedbComZooKeeperAutoscaler/spec/compute/zookeeper/trigger + schema: temp/properties/compute/properties/zookeeper/properties/trigger + watcher: + func: onTriggerChange|compute/zookeeper + paths: + - temp/properties/compute/properties/zookeeper/properties/trigger + - type: label-element + 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: input + label: Pod LifeTime Threshold (e.g., 10m 30s) + schema: schema/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/zookeeper/properties/podLifeTimeThreshold + customClass: width-300 + - type: block-layout + label: Zookeeper + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/zookeeper + elements: + - type: threshold-input + label: ResourceDiff Percentage + schema: schema/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/zookeeper/properties/resourceDiffPercentage + customClass: width-300 + - type: label-element + label: Resource Configuration + subtitle: Define minimum and maximum allowed resources to ensure optimal database performance + - type: block-layout + showLabels: false + elements: + - type: machine-compare + label: Min Allowed Profile + header: Minimum Resource Limit + schema: temp/properties/allowedMachine-zookeeper-min + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|zookeeper|min + loader: + name: getMachines|zookeeper|min + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-zookeeper-max + watcher: + func: onMachineChange|zookeeper + paths: + - temp/properties/allowedMachine-zookeeper-min + - type: block-layout + label: Min Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/zookeeper/properties/minAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/zookeeper/properties/minAllowed/properties/memory + - type: machine-compare + label: Max Allowed Profile + header: Maximum Resource Limit + schema: temp/properties/allowedMachine-zookeeper-max + if: + type: function + name: hasAnnotations + init: + type: func + value: setAllowedMachine|zookeeper|max + loader: + name: getMachines|zookeeper|max + watchPaths: + - temp/properties/topologyMachines + - temp/properties/allowedMachine-zookeeper-min + watcher: + func: onMachineChange|zookeeper + paths: + - temp/properties/allowedMachine-zookeeper-max + - type: block-layout + label: Max Allowed + fixedBlock: true + if: + type: function + name: hasNoAnnotations + showLabels: true + elements: + - type: input-compare + label: Cpu + schema: schema/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/zookeeper/properties/maxAllowed/properties/cpu + - type: input-compare + label: Memory + schema: schema/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/zookeeper/properties/maxAllowed/properties/memory + - type: select + label: Controlled Resources + loader: setControlledResources|zookeeper + multiple: true + schema: schema/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/zookeeper/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/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/zookeeper/properties/containerControlledValues + + - type: block-layout + label: Node Topology + if: + type: function + name: hasNoAnnotations + showLabels: true + # schema: schema/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/nodeTopology + elements: + - type: select + label: Select Node Topology + loader: fetchNodeTopology + schema: schema/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/name + - type: threshold-input + label: Scale Up DiffPercentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleUpDiffPercentage + - type: threshold-input + label: Scale Down DiffPercentage + if: + type: function + name: isNodeTopologySelected + schema: schema/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/compute/properties/nodeTopology/properties/scaleDownDiffPercentage + + - type: block-layout + label: Ops Request Options + showLabels: true + if: + type: function + name: showOpsRequestOptions + # schema: schema/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/opsRequestOptions + elements: + - type: time-picker + label: Timeout + schema: schema/properties/resources/properties/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/opsRequestOptions/properties/timeout + - type: radio + label: Apply + init: + type: func + value: setApplyToIfReady + 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/autoscalingKubedbComZooKeeperAutoscaler/properties/spec/properties/opsRequestOptions/properties/apply + - type: single-step-form + id: monitoring + loader: initMonitoring elements: - - label: - text: labels.to_update_exporter_resources - type: label-element - - customClass: mb-20 - label: - text: labels.create_opsrequest - type: anchor - url: - function: getOpsRequestUrl|VerticalScaling - - computed: isValueExistInModel|/resources/kubedbComZooKeeper/spec/monitor - label: - text: labels.enable_monitoring - onChange: onEnableMonitoringChange - schema: - $ref: discriminator#/enableMonitoring - type: switch - - discriminator: - customizeExporter: - default: true - type: boolean + - type: label-element + label: To update Exporter Resource section click on Create OpsRequest + - type: anchor + label: Create OpsRequest + schema: temp/properties/opsRequestUrl + init: + type: func + value: getOpsRequestUrl|scale-vertically + - type: switch + label: Enable Monitoring + fullwidth: true + schema: temp/properties/enableMonitoring + init: + type: func + value: isValueExistInModel|/resources/kubedbComZooKeeper/spec/monitor + watcher: + func: onEnableMonitoringChange + paths: + - temp/properties/enableMonitoring + - type: block-layout + if: + type: function + name: showMonitoringSection 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/kubedbComZooKeeper/properties/spec/properties/monitor/properties/agent - type: radio - - elements: - - label: - text: labels.scrapping_interval - schema: - $ref: schema#/properties/resources/properties/kubedbComZooKeeper/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval - type: input - if: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComZooKeeper/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: radio + label: Select a Monitoring Method + schema: schema/properties/resources/properties/kubedbComZooKeeper/properties/spec/properties/monitor/properties/agent + isHorizontal: true + options: + - text: Prometheus Operator + value: prometheus.io/operator + description: Inject metric exporter sidecar and creates a ServiceMonitor + - text: Custom ServiceMonitor + value: prometheus.io + description: Injects the metric exporter sidecar and let you customize ServiceMonitor + - text: Custom Scrapper + value: prometheus.io/builtin + description: Inject metric exporter sidecar and add Prometheus annotations to the stats Service + init: + type: static + value: prometheus.io/operator + watcher: + func: onAgentChange + paths: + - schema/properties/resources/properties/kubedbComZooKeeper/properties/spec/properties/monitor/properties/agent + - type: block-layout + label: ServiceMonitor Configuration + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io/operator|/resources/kubedbComZooKeeper/spec/monitor/agent + elements: + - label: Scrapping Interval + schema: schema/properties/resources/properties/kubedbComZooKeeper/properties/spec/properties/monitor/properties/prometheus/properties/serviceMonitor/properties/interval + type: input + - type: block-layout + label: Service Monitor + showLabels: true + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComZooKeeper/spec/monitor/agent + elements: + - type: array-object-form + label: Endpoints + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/endpoints + elements: + - type: switch + label: Honor labels + fullwidth: true + schema: honorLabels + - type: input + label: Interval + schema: interval + validation: + type: required + - type: input + label: Path + schema: path + validation: + type: required + - type: input + label: Port + schema: port + validation: + type: required + - type: select + multiple: true + label: Match Namespaces + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/namespaceSelector/properties/matchNames + loader: getResources|core|v1|namespaces + if: + type: function + name: returnFalse + - type: block-layout + showLabels: false + # schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector + if: + type: function + name: returnFalse + elements: + - type: object-item + label: Labels + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/spec/properties/selector/properties/matchLabels + - type: object-item + schema: schema/properties/resources/properties/monitoringCoreosComServiceMonitor/properties/metadata/properties/labels + label : Labels + buttonClass: is-light is-outlined + if: + type: function + name: isEqualToModelPathValue|prometheus.io|/resources/kubedbComZooKeeper/spec/monitor/agent + # individualItemDisabilityCheck: disableLableChecker + - type: label-element + label: Exporter Configuration + schema: '' + - type: switch + label: Customize Exporter Sidecar + fullwidth: true + schema: temp/properties/customizeExporter + init: + type: static + value: true + watcher: + func: onCustomizeExporterChange + paths: + - temp/properties/customizeExporter + - type: block-layout + label: Customer Exporter Section + showLabels: false + if: + type: function + name: showCustomizeExporterSection + elements: + - type: machine-compare + label: Resources + schema: schema/properties/resources/properties/kubedbComZooKeeper/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/resources + if: + type: function + name: returnFalse + - type: label-element + label: Security Context + schema: '' + - type: input + schema: schema/properties/resources/properties/kubedbComZooKeeper/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsUser + label: Run as User + - type: input + schema: schema/properties/resources/properties/kubedbComZooKeeper/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup + label: Run as Group + - type: input + schema: schema/properties/resources/properties/kubedbComZooKeeper/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/port + label: Port + - type: array-item-form + label: Args + buttonClass: is-light is-outlined + schema: schema/properties/resources/properties/kubedbComZooKeeper/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args + init: + type: static + value: ['--compatible-mode'] + element: 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/kubedbComZooKeeper/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/kubedbComZooKeeper/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: - - if: returnFalse - label: - text: labels.resources - schema: - $ref: schema#/properties/resources/properties/kubedbComZooKeeper/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/kubedbComZooKeeper/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/kubedbComZooKeeper/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/securityContext/properties/runAsGroup - type: input - - label: - text: labels.port - schema: - $ref: schema#/properties/resources/properties/kubedbComZooKeeper/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/kubedbComZooKeeper/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args/items - type: input - label: - text: labels.args - schema: - $ref: schema#/properties/resources/properties/kubedbComZooKeeper/properties/spec/properties/monitor/properties/prometheus/properties/exporter/properties/args - type: list-input-form - - alias: reusable_env - chart: - name: uibytebuildersdev-component-env - version: v0.29.0 - dataContext: - namespace: - $ref: schema#/properties/metadata/properties/release/properties/namespace - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/resources/properties/kubedbComZooKeeper/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 -type: multi-step-form + label: Args + # isSubsection: true + - type: block-layout + label: Metadata + showLabels: false + elements: + - type: array-object-form + init: + type: func + value: initEnvArray + label: Environment Variables + buttonClass: is-light is-outlined + watcher: + func: onEnvArrayChange + paths: + - temp/properties/env + schema: temp/properties/env + elements: + - type: input + label: Name + schema: name + validation: + type: required + - type: radio + label: Value From + schema: temp/properties/valueFromType + validation: + type: required + init: + type: func + value: setValueFrom + options: + - text: Input + value: input + - text: Secret + value: secret + - text: ConfigMap + value: configMap + watcher: + func: onValueFromChange + paths: + - temp/properties/valueFromType + - type: input + label: Value + schema: value + validation: + type: required + if: + name: isEqualToTemp|input + type: function + - type: select + if: + type: function + name: isEqualToTemp|configMap + label: ConfigMap Name + schema: valueFrom/properties/configMapKeyRef/properties/name + loader: + name: resourceNames|core|v1|configmaps + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: ConfigMap Key + schema: valueFrom/properties/configMapKeyRef/properties/key + if: + type: function + name: isEqualToTemp|configMap + loader: + name: getConfigMapKeys + watchPaths: + - schema/resources/kubedbComZooKeeper/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/configMapKeyRef/name + - schema/metadata/release/namespace + - type: select + label: Secret Name + schema: valueFrom/properties/secretKeyRef/properties/name + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecrets + watchPaths: + - schema/metadata/release/namespace + validation: + type: required + - type: select + label: Secret Key + schema: valueFrom/properties/secretKeyRef/properties/key + if: + type: function + name: isEqualToTemp|secret + loader: + name: getSecretKeys + watchPaths: + - schema/resources/kubedbComZooKeeper/spec/monitor/prometheus/exporter/env/dynamicIndex/valueFrom/secretKeyRef/name + - schema/metadata/release/namespace \ No newline at end of file diff --git a/charts/kubedbcom-zookeeper-editor/ui/functions.js b/charts/kubedbcom-zookeeper-editor/ui/functions.js index 8c37583e7c..d60aeacc4e 100644 --- a/charts/kubedbcom-zookeeper-editor/ui/functions.js +++ b/charts/kubedbcom-zookeeper-editor/ui/functions.js @@ -1,877 +1,1394 @@ -// backup form -function showBackupForm({ getValue, discriminator, watchDependency }) { - const scheduleBackup = getValue(discriminator, '/scheduleBackup') - watchDependency('discriminator#/scheduleBackup') +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} - 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({ storeGet, axios, getValue, model, setDiscriminatorValue }) { - // 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/kubedbComZooKeeper') - initialDbMetadata = objectCopy(dbResource.metadata) - - // 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 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, +// ************************* common functions ******************************************** +// eslint-disable-next-line no-empty-pattern +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, ) - // 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, + /********** 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', []) + + // Compute Autoscaler Discriminators + setDiscriminatorValue('/dbDetails', false) + setDiscriminatorValue('/topologyMachines', []) + + function initScheduleBackupForEdit() { + const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( + getValue, + model, ) - // 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 + initRepositoryChoiseForEdit() - const tempBackends = valuesFromWizard.spec?.backends - tempBackends[0]['storageRef'] = storageRef - tempBackends[0]['retentionPolicy'] = retentionPolicy - valuesFromWizard.spec['backends'] = tempBackends + if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' + else return 'no' + } - 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}` + function initScheduleBackup() { + const { stashAppscodeComBackupConfiguration, isBluePrint } = getBackupConfigsAndAnnotations( + getValue, + model, + ) - tempSessions[0]['repositories'] = tempRepositories - tempSessions[0]['scheduler']['schedule'] = schedule - valuesFromWizard.spec['sessions'] = tempSessions + if (stashAppscodeComBackupConfiguration || isBluePrint) return 'yes' + else return 'no' } - 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, + // backup form + function showBackupForm() { + const scheduleBackup = getValue(discriminator, '/scheduleBackup') + // watchDependency('discriminator#/scheduleBackup') + if (scheduleBackup === 'yes') return true + else return false } - setDiscriminatorValue('isBackupDataLoaded', true) -} + let initialModel = {} + let isBackupOn = false + let isBackupOnModel = false + let dbResource = {} + let initialDbMetadata = {} + let backupConfigurationsFromStore = {} + let valuesFromWizard = {} + let initialArchiver = {} + let isArchiverAvailable = false + let archiverObjectToCommit = {} + let instance = {} + + 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/kubedbComZooKeeper') + initialDbMetadata = objectCopy(dbResource.metadata) + initialArchiver = dbResource.spec?.archiver ? objectCopy(dbResource.spec?.archiver) : undefined -function isBackupDataLoadedTrue({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/isBackupDataLoaded') - return !!getValue(discriminator, '/isBackupDataLoaded') -} + // 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 -async function setBackupType() { - return 'BackupConfig' -} + let url = `/clusters/${user}/${cluster}/helm/packageview/values?name=${chartName}&sourceApiGroup=${sourceApiGroup}&sourceKind=${sourceKind}&sourceNamespace=${sourceNamespace}&sourceName=${sourceName}&version=${chartVersion}&format=json` -async function getTypes() { - const arr = [ - { - description: 'Create, Delete or Modify BackupConfig', - text: 'BackupConfig', - value: 'BackupConfig', - }, - { - description: 'Enable/Disable BackupBlueprint', - text: 'BackupBlueprint', - value: 'BackupBlueprint', - }, - ] - - return arr -} + if (spoke) + url = `/clusters/${user}/${spoke}/helm/packageview/values?name=${chartName}&sourceApiGroup=${sourceApiGroup}&sourceKind=${sourceKind}&sourceNamespace=${sourceNamespace}&sourceName=${sourceName}&version=${chartVersion}&format=json` -function onBackupTypeChange({ commit, getValue, discriminator }) { - 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/kubedbComZooKeeper', - value: objectCopy(dbResource), - force: true, - }) -} + const resp = await axios.get(url) -function isBackupType({ watchDependency, getValue, discriminator }, type) { - watchDependency('discriminator#/backupType') - const selectedType = getValue(discriminator, '/backupType') + valuesFromWizard = objectCopy(resp.data?.resources?.coreKubestashComBackupConfiguration) || {} + } catch (e) { + console.log(e) + } - return selectedType === type -} + // 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) + } + } -function setBlueprintSwitch() { - const annotations = initialDbMetadata?.annotations + // 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, + ) - return !!( - annotations['blueprint.kubestash.com/name'] && annotations['blueprint.kubestash.com/namespace'] - ) -} + // 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, + ) -function onBlueprintChange({ getValue, discriminator, commit, model, storeGet }) { - const blueprintSwitch = getValue(discriminator, '/blueprintEnabled') - if (blueprintSwitch) addLabelAnnotation(commit, storeGet, 'annotations') - else deleteLabelAnnotation(commit, 'annotations') -} + // set backup switch here + isBackupOn = !!config -function setArchiverSwitch() { - const archiver = dbResource?.spec?.archiver - return !!archiver -} + // set initial data from stash-presets + const stashPreset = storeGet('/backup/stashPresets') + if (stashPreset) { + const { retentionPolicy, encryptionSecret, schedule, storageRef } = stashPreset -function onArchiverChange({ getValue, discriminator, commit }) { - const archiverSwitch = getValue(discriminator, '/archiverEnabled') - const path = 'resources/kubedbComZooKeeper/spec/archiver' - if (archiverSwitch) { - commit('wizard/model$update', { - path: path, - value: initialArchiver ? initialArchiver : archiverObjectToCommit, - }) - } else { - commit('wizard/model$delete', path) - } -} + const tempBackends = valuesFromWizard.spec?.backends + tempBackends[0]['storageRef'] = storageRef + tempBackends[0]['retentionPolicy'] = retentionPolicy + valuesFromWizard.spec['backends'] = tempBackends -function addLabelAnnotation(commit, storeGet, type) { - const obj = objectCopy(initialDbMetadata[type]) + 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}` - 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' - } + tempSessions[0]['repositories'] = tempRepositories + tempSessions[0]['scheduler']['schedule'] = schedule + valuesFromWizard.spec['sessions'] = tempSessions + } - commit('wizard/model$update', { - path: `/resources/kubedbComZooKeeper/metadata/${type}`, - value: obj, - force: true, - }) -} + 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, + } -function deleteLabelAnnotation(commit, type) { - const obj = initialDbMetadata[type] + setDiscriminatorValue('isBackupDataLoaded', true) + } - if (type === 'annotations') { - delete obj['blueprint.kubestash.com/name'] - delete obj['blueprint.kubestash.com/namespace'] - } else delete obj['kubedb.com/archiver'] + function isBackupDataLoadedTrue() { + // watchDependency('discriminator#/isBackupDataLoaded') + return !!getValue(discriminator, '/isBackupDataLoaded') + } - commit('wizard/model$update', { - path: `/resources/kubedbComZooKeeper/metadata/${type}`, - value: obj, - force: true, - }) -} + function setBackupType() { + return 'BackupConfig' + } -function getContext() { - if (isBackupOn) return ['Create', 'Delete', 'Modify'] - return ['Create'] -} + 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 onContextChange({ getValue, discriminator, commit, model }) { - const context = getValue(discriminator, '/backupConfigContext') - commit('wizard/model$update', { - path: '/context', - value: context, - force: true, - }) - if (context === 'Create') { + function onBackupTypeChange() { + const type = getValue(discriminator, '/backupType') commit('wizard/model$update', { - path: '/resources/coreKubestashComBackupConfiguration', - value: valuesFromWizard, + 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/kubedbComZooKeeper', + value: objectCopy(dbResource), force: true, }) } -} - -function getConfigList({ storeGet }) { - 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({ getValue, discriminator, commit, storeGet, model }) { - const configName = getValue(discriminator, '/config') - const configs = objectCopy(backupConfigurationsFromStore) - const configDetails = configs?.find((item) => item?.metadata?.name === configName) + function isBackupType(type) { + // watchDependency('discriminator#/backupType') + const selectedType = getValue(discriminator, '/backupType') - commit('wizard/model$update', { - path: '/resources/coreKubestashComBackupConfiguration', - value: configDetails, - force: true, - }) -} - -function showPause({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/backupConfigContext') - watchDependency('discriminator#/config') - const contex = getValue(discriminator, '/backupConfigContext') - const configName = getValue(discriminator, '/config') - return !!configName && contex === 'Modify' -} - -function showConfigList({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/backupConfigContext') - const contex = getValue(discriminator, '/backupConfigContext') - return contex === 'Modify' || contex === 'Delete' -} + return selectedType === type + } -function showSchedule({ watchDependency, getValue, discriminator }) { - 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 setBlueprintSwitch() { + const annotations = initialDbMetadata?.annotations -function onInputChangeSchedule( - { getValue, discriminator, commit, model }, - modelPath, - discriminatorName, -) { - const value = getValue(discriminator, `/${discriminatorName}`) - const session = getValue(model, modelPath) - session[0].scheduler.schedule = value - commit('wizard/model$update', { - path: modelPath, - value: session, - }) -} + return !!( + annotations['blueprint.kubestash.com/name'] && + annotations['blueprint.kubestash.com/namespace'] + ) + } -function getDefaultSchedule({ getValue, model, watchDependency }, modelPath) { - watchDependency('discriminator#/config') - const session = getValue(model, modelPath) - return session?.length ? session[0]?.scheduler.schedule : '' -} + function onBlueprintChange() { + const blueprintSwitch = getValue(discriminator, '/blueprintEnabled') + if (blueprintSwitch) addLabelAnnotation('annotations') + else deleteLabelAnnotation('annotations') + } -function objectCopy(obj) { - const temp = JSON.stringify(obj) - return JSON.parse(temp) -} + function setArchiverSwitch() { + const archiver = dbResource?.spec?.archiver + return !!archiver + } -function returnFalse() { - return false -} + function onArchiverChange() { + const archiverSwitch = getValue(discriminator, '/archiverEnabled') + const path = 'resources/kubedbComZooKeeper/spec/archiver' + if (archiverSwitch) { + commit('wizard/model$update', { + path: path, + value: initialArchiver ? initialArchiver : archiverObjectToCommit, + }) + } else { + commit('wizard/model$delete', path) + } + } -function isValueExistInModel({ model, getValue }, path) { - const modelValue = getValue(model, path) - return !!modelValue -} + function addLabelAnnotation(type) { + const obj = objectCopy(initialDbMetadata[type]) -function showMonitoringSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/enableMonitoring') - const configureStatus = getValue(discriminator, '/enableMonitoring') - return configureStatus -} + 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' + } -function onEnableMonitoringChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/enableMonitoring') - if (configureStatus) { commit('wizard/model$update', { - path: '/resources/kubedbComZooKeeper/spec/monitor', - value: {}, + path: `/resources/kubedbComZooKeeper/metadata/${type}`, + value: obj, force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComZooKeeper/spec/monitor') } - // update alert value depend on monitoring profile - commit('wizard/model$update', { - path: '/form/alert/enabled', - value: configureStatus ? 'warning' : 'none', - force: true, - }) -} + function deleteLabelAnnotation(type) { + const obj = initialDbMetadata[type] -function showCustomizeExporterSection({ watchDependency, discriminator, getValue }) { - watchDependency('discriminator#/customizeExporter') - const configureStatus = getValue(discriminator, '/customizeExporter') - return configureStatus -} + if (type === 'annotations') { + delete obj['blueprint.kubestash.com/name'] + delete obj['blueprint.kubestash.com/namespace'] + } else delete obj['kubedb.com/archiver'] -function onCustomizeExporterChange({ discriminator, getValue, commit }) { - const configureStatus = getValue(discriminator, '/customizeExporter') - if (configureStatus) { commit('wizard/model$update', { - path: '/resources/kubedbComZooKeeper/spec/monitor/prometheus/exporter', - value: {}, + path: `/resources/kubedbComZooKeeper/metadata/${type}`, + value: obj, force: true, }) - } else { - commit('wizard/model$delete', '/resources/kubedbComZooKeeper/spec/monitor/prometheus/exporter') } -} -function isEqualToModelPathValue({ model, getValue, watchDependency }, value, modelPath) { - const modelPathValue = getValue(model, modelPath) - watchDependency('model#' + modelPath) - return modelPathValue === value -} + function getContext() { + if (isBackupOn) return ['Create', 'Delete', 'Modify'] + return ['Create'] + } -function setMetadata({ storeGet, mode, commit }) { - const dbname = storeGet('/route/params/name') || '' - const namespace = storeGet('/route/query/namespace') || '' - if (mode === 'standalone-step') { + function onContextChange() { + const context = getValue(discriminator, '/backupConfigContext') commit('wizard/model$update', { - path: '/metadata/release/name', - value: dbname, + 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: '/metadata/release/namespace', - value: namespace, + path: '/resources/coreKubestashComBackupConfiguration', + value: configDetails, force: true, }) } -} -async function fetchJsons({ axios, itemCtx }) { - let ui = {} - let language = {} - let functions = {} - const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart + function showPause() { + // watchDependency('discriminator#/backupConfigContext') + // watchDependency('discriminator#/config') + const contex = getValue(discriminator, '/backupConfigContext') + const configName = getValue(discriminator, '/config') + return !!configName && contex === 'Modify' + } - 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`, + 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, ) - 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}`, + 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', ) - // declare evaluate the functionString to get the functions Object - const evalFunc = new Function(functionString.data || '') - functions = evalFunc() - } catch (e) { - console.log(e) + const repoInitialSelectionStatus = stashAppscodeComRepository_repo ? 'yes' : 'no' + setDiscriminatorValue('/repoInitialSelectionStatus', repoInitialSelectionStatus) + + return repoInitialSelectionStatus } - return { - ui: ui.data || {}, - language: language.data || {}, - functions, + 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) + } + + // monitoring + + function isValueExistInModel(path) { + const modelValue = getValue(model, path) + return !!modelValue + } + + function showMonitoringSection() { + // watchDependency('discriminator#/enableMonitoring') + const configureStatus = getValue(discriminator, '/enableMonitoring') + return configureStatus } -} -function onAgentChange({ commit, model, getValue }) { - const agent = getValue(model, '/resources/kubedbComZooKeeper/spec/monitor/agent') - if (agent === 'prometheus.io') { + function onEnableMonitoringChange() { + const configureStatus = getValue(discriminator, '/enableMonitoring') + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComZooKeeper/spec/monitor', + value: {}, + force: true, + }) + } else { + commit('wizard/model$delete', '/resources/kubedbComZooKeeper/spec/monitor') + } + + // update alert value depend on monitoring profile commit('wizard/model$update', { - path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', - value: [], + path: '/form/alert/enabled', + value: configureStatus ? 'warning' : 'none', force: true, }) + } - onNamespaceChange({ commit, model, getValue }) - onLabelChange({ commit, model, getValue }) - } else { - commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') + function showCustomizeExporterSection() { + // watchDependency('discriminator#/customizeExporter') + const configureStatus = getValue(discriminator, '/customizeExporter') + return configureStatus } -} -function getOpsRequestUrl({ storeGet, model, getValue, mode }, 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 + `/create-opsrequest-${reqType.toLowerCase()}?namespace=${namespace}` - - if (mode === 'standalone-step') return pathConstructedForKubedb - else - return `${domain}/console/${owner}/kubernetes/${cluster}/ops.kubedb.com/v1alpha1/zookeeperopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=${reqType}` -} + function onCustomizeExporterChange() { + const configureStatus = getValue(discriminator, '/customizeExporter') + if (configureStatus) { + commit('wizard/model$update', { + path: '/resources/kubedbComZooKeeper/spec/monitor/prometheus/exporter', + value: {}, + force: true, + }) + } else { + commit( + 'wizard/model$delete', + '/resources/kubedbComZooKeeper/spec/monitor/prometheus/exporter', + ) + } + } -///////////////////////// Autoscaler /////////////////// -let autoscaleType = '' -let dbDetails = {} + function isEqualToModelPathValue(value, modelPath) { + const modelPathValue = getValue(model, modelPath) + // watchDependency('model#' + modelPath) + return modelPathValue === value + } -function isConsole({ storeGet, commit }) { - const isKube = isKubedb({ storeGet }) + function onAgentChange() { + const agent = getValue(model, '/resources/kubedbComZooKeeper/spec/monitor/agent') + if (agent === 'prometheus.io') { + commit('wizard/model$update', { + path: '/resources/monitoringCoreosComServiceMonitor/spec/endpoints', + value: [], + force: true, + }) - if (isKube) { - const dbName = storeGet('/route/params/name') || '' - commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComZooKeeperAutoscaler/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] + onNamespaceChange() + onLabelChange() + } else { + commit('wizard/model$delete', '/resources/monitoringCoreosComServiceMonitor') } - const date = Math.floor(Date.now() / 1000) - const modifiedName = `${dbName}-${date}-autoscaling-${autoscaleType}` - commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComZooKeeperAutoscaler/metadata/name', - value: modifiedName, - force: true, - }) - const namespace = storeGet('/route/query/namespace') || '' - if (namespace) { + } + + function onLabelChange() { + const labels = getValue(model, '/resources/kubedbComZooKeeper/spec/metadata/labels') + + const agent = getValue(model, '/resources/kubedbComZooKeeper/spec/monitor/agent') + + if (agent === 'prometheus.io') { commit('wizard/model$update', { - path: '/resources/autoscalingKubedbComZooKeeperAutoscaler/metadata/namespace', - value: namespace, + path: '/resources/monitoringCoreosComServiceMonitor/spec/selector/matchLabels', + value: labels, force: true, }) } } - return !isKube -} + 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/zookeeperopsrequests/create?name=${dbname}&namespace=${namespace}&group=${group}&version=${version}&resource=${resource}&kind=${kind}&page=operations&requestType=${reqType}` + } -function isKubedb({ storeGet }) { - return !!storeGet('/route/params/actions') -} + function onNamespaceChange() { + const namespace = getValue( + model, + '/resources/autoscalingKubedbComZooKeeperAutoscaler/metadata/namespace', + ) + if (!namespace) { + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComZooKeeperAutoscaler/spec/databaseRef/name', + ) + } + } -function showOpsRequestOptions({ model, getValue, watchDependency, storeGet, discriminator }) { - if (isKubedb({ storeGet }) === true) return true - watchDependency('model#/resources/autoscalingKubedbComZooKeeperAutoscaler/spec/databaseRef/name') - watchDependency('discriminator#/autoscalingType') - return ( - !!getValue(model, '/resources/autoscalingKubedbComZooKeeperAutoscaler/spec/databaseRef/name') && - !!getValue(discriminator, '/autoscalingType') - ) -} + function setValueFrom() { + if (isConfigMapTypeValueFrom()) { + return 'configMap' + } else if (isSecretTypeValueFrom()) { + return 'secret' + } else { + return 'input' + } + } -async function getNamespaces({ axios, storeGet }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function isConfigMapTypeValueFrom() { + const valueFrom = getValue(discriminator, '/valueFrom') + return !!(valueFrom && valueFrom.configMapKeyRef) + } - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + function isSecretTypeValueFrom() { + const valueFrom = getValue(discriminator, '/valueFrom') + return !!(valueFrom && valueFrom.secretKeyRef) + } - const resources = (resp && resp.data && resp.data.items) || [] + 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, + }) + } + } - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, + // 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) + }) } - }) -} -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - watchDependency('model#/resources/autoscalingKubedbComZooKeeperAutoscaler/metadata/namespace') - const namespace = getValue( - model, - '/resources/autoscalingKubedbComZooKeeperAutoscaler/metadata/namespace', - ) - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + async function getNamespacedResourceList( + axios, + storeGet, + { namespace, group, version, resource }, + ) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - const resources = (resp && resp.data && resp.data.items) || [] + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, + 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) } - }) -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + return ans + } + + 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/kubedbComZooKeeper/spec/monitor/prometheus/exporter/env/${index}/valueFrom/configMapKeyRef/name`, + ) + + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/configMapKeyRef/name') + + if (!configMapName) return [] -async function getDbDetails({ commit, setDiscriminatorValue, axios, storeGet, getValue, model }) { - const owner = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - const namespace = - storeGet('/route/query/namespace') || - getValue(model, '/resources/autoscalingKubedbComZooKeeperAutoscaler/metadata/namespace') || - '' - const name = - storeGet('/route/params/name') || - getValue(model, '/resources/autoscalingKubedbComZooKeeperAutoscaler/spec/databaseRef/name') || - '' - - if (namespace && name) { try { const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/zookeepers/${name}`, + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/configmaps/${configMapName}`, ) - dbDetails = resp.data || {} - setDiscriminatorValue('/dbDetails', true) + + 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 [] } } - commit('wizard/model$update', { - path: `/metadata/release/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/metadata/release/namespace`, - value: namespace, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComZooKeeperAutoscaler/spec/databaseRef/name`, - value: name, - force: true, - }) - commit('wizard/model$update', { - path: `/resources/autoscalingKubedbComZooKeeperAutoscaler/metadata/labels`, - value: dbDetails.metadata.labels, - force: true, - }) -} + 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') -function initMetadata({ getValue, discriminator, model, commit, storeGet }) { - const dbName = - getValue(model, '/resources/autoscalingKubedbComZooKeeperAutoscaler/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/autoscalingKubedbComZooKeeperAutoscaler/metadata/name', - value: modifiedName, - force: true, - }) + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }, + ) - // delete the other type object from model - if (type === 'compute') - commit('wizard/model$delete', '/resources/autoscalingKubedbComZooKeeperAutoscaler/spec/storage') - if (type === 'storage') - commit('wizard/model$delete', '/resources/autoscalingKubedbComZooKeeperAutoscaler/spec/compute') -} + const secrets = (resp && resp.data && resp.data.items) || [] -function onNamespaceChange({ model, getValue, commit }) { - const namespace = getValue( - model, - '/resources/autoscalingKubedbComZooKeeperAutoscaler/metadata/namespace', - ) - if (!namespace) { - commit( - 'wizard/model$delete', - '/resources/autoscalingKubedbComZooKeeperAutoscaler/spec/databaseRef/name', - ) - } -} + const filteredSecrets = secrets.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) -async function fetchNodeTopology({ axios, storeGet }) { - 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) + 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 [] + } } - return [] -} -function isNodeTopologySelected({ watchDependency, model, getValue }) { - watchDependency( - 'model#/resources/autoscalingKubedbComZooKeeperAutoscaler/spec/compute/nodeTopology/name', - ) - const nodeTopologyName = - getValue( + 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/autoscalingKubedbComZooKeeperAutoscaler/spec/compute/nodeTopology/name', - ) || '' - return !!nodeTopologyName.length -} + `/resources/kubedbComZooKeeper/spec/monitor/prometheus/exporter/env/${index}/valueFrom/secretKeyRef/name`, + ) -function setControlledResources({ commit }, type) { - const list = ['cpu', 'memory'] - const path = `/resources/autoscalingKubedbComZooKeeperAutoscaler/spec/compute/${type}/controlledResources` - commit('wizard/model$update', { - path: path, - value: list, - force: true, - }) - return list -} + // watchDependency('data#/namespace') + // watchDependency('rootModel#/valueFrom/secretKeyRef/name') -function setTrigger({ model, getValue }, path) { - let value = getValue(model, `/resources/${path}`) - if (value) return value - return 'On' -} + if (!secretName) return [] -function setApplyToIfReady() { - return 'IfReady' -} + 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 [] + } + } -async function fetchTopologyMachines({ axios, getValue, storeGet, model, setDiscriminatorValue }) { - const instance = hasAnnotations({ model, getValue }) + async function getResources(group, version, resource) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - 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 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) || [] - const nodeGroups = resp.data?.spec?.nodeGroups || [] - setDiscriminatorValue('/topologyMachines', nodeGroups) - return nodeGroups + 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 setAllowedMachine({ model, getValue }, minmax) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComZooKeeperAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] - const mx = instance?.includes(',') ? instance.split(',')[1] : '' - const mn = instance?.includes(',') ? instance.split(',')[0] : '' + // Autoscaler functions - if (minmax === 'min') return mn - else return mx -} + let autoscaleType = '' + let dbDetails = {} -async function getMachines({ getValue, watchDependency, discriminator }, minmax) { - watchDependency('discriminator#/topologyMachines') - const depends = minmax === 'min' ? 'max' : 'min' - const dependantPath = `/allowedMachine-${depends}` + function isConsole() { + const isKube = isKubedb() - watchDependency(`discriminator#${dependantPath}`) - const dependantMachine = getValue(discriminator, dependantPath) + if (isKube) { + const dbName = storeGet('/route/params/name') || '' + commit('wizard/model$update', { + path: '/resources/autoscalingKubedbComZooKeeperAutoscaler/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: '/metadata/name', + value: modifiedName, + force: true, + }) + const namespace = storeGet('/route/query/namespace') || '' + if (namespace) { + commit('wizard/model$update', { + path: '/metadata/namespace', + value: namespace, + force: true, + }) + } + } - const nodeGroups = getValue(discriminator, '/topologyMachines') || [] + return !isKube + } - const dependantIndex = nodeGroups?.findIndex((item) => item.topologyValue === dependantMachine) + function isKubedb() { + return !!storeGet('/route/params/actions') + } - const machines = nodeGroups?.map((item) => { - const subText = `CPU: ${item.allocatable.cpu}, Memory: ${item.allocatable.memory}` - const text = item.topologyValue - return { text, subText, value: item.topologyValue } - }) + function showOpsRequestOptions() { + if (isKubedb() === true) return true + const dbRefName = getValue( + model, + '/resources/autoscalingKubedbComZooKeeperAutoscaler/spec/databaseRef/name', + ) + const autoscalingType = getValue(discriminator, '/autoscalingType') + return !!dbRefName && !!autoscalingType + } - const filteredMachine = machines?.filter((item, ind) => - minmax === 'min' ? ind <= dependantIndex : ind >= dependantIndex, - ) + async function getNamespaces() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - return dependantIndex === -1 ? machines : filteredMachine -} + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, + }) -function hasAnnotations({ model, getValue }) { - const annotations = getValue( - model, - '/resources/autoscalingKubedbComZooKeeperAutoscaler/metadata/annotations', - ) - const instance = annotations['kubernetes.io/instance-type'] + const resources = (resp && resp.data && resp.data.items) || [] - return !!instance -} + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -function hasNoAnnotations({ model, getValue }) { - return !hasAnnotations({ model, getValue }) -} + async function getDbs() { + const namespace = getValue(model, '/metadata/namespace') + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function onMachineChange({ model, getValue, discriminator, commit }, type) { - const annoPath = '/resources/autoscalingKubedbComZooKeeperAutoscaler/metadata/annotations' - const annotations = getValue(model, annoPath) - const instance = annotations['kubernetes.io/instance-type'] + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/zookeepers`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) + + const resources = (resp && resp.data && resp.data.items) || [] - const minMachine = getValue(discriminator, '/allowedMachine-min') - const maxMachine = getValue(discriminator, '/allowedMachine-max') - const minMaxMachine = `${minMachine},${maxMachine}` - annotations['kubernetes.io/instance-type'] = minMaxMachine + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } - const machines = getValue(discriminator, `/topologyMachines`) || [] - const minMachineObj = machines.find((item) => item.topologyValue === minMachine) - const maxMachineObj = machines.find((item) => item.topologyValue === maxMachine) - const minMachineAllocatable = minMachineObj?.allocatable - const maxMachineAllocatable = maxMachineObj?.allocatable - const allowedPath = `/resources/autoscalingKubedbComZooKeeperAutoscaler/spec/compute/${type}` + async function getDbDetails() { + const annotations = getValue( + model, + '/resources/autoscalingKubedbComZooKeeperAutoscaler/metadata/annotations', + ) + instance = annotations?.['kubernetes.io/instance-type'] + 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, '/resources/autoscalingKubedbComZooKeeperAutoscaler/spec/databaseRef/name') || + '' + + if (namespace && name) { + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/zookeepers/${name}`, + ) + dbDetails = resp.data || {} + setDiscriminatorValue('/dbDetails', true) + } catch (e) { + console.log(e) + } + } - if (minMachine && maxMachine && instance !== minMaxMachine) { commit('wizard/model$update', { - path: `${allowedPath}/maxAllowed`, - value: maxMachineAllocatable, + path: `/metadata/release/name`, + value: name, force: true, }) commit('wizard/model$update', { - path: `${allowedPath}/minAllowed`, - value: minMachineAllocatable, + path: `/metadata/release/namespace`, + value: namespace, force: true, }) commit('wizard/model$update', { - path: annoPath, - value: { ...annotations }, + path: `/resources/autoscalingKubedbComZooKeeperAutoscaler/spec/databaseRef/name`, + value: name, + force: true, + }) + commit('wizard/model$update', { + path: `/resources/autoscalingKubedbComZooKeeperAutoscaler/metadata/labels`, + value: dbDetails.metadata?.labels, force: true, }) } -} -return { - getOpsRequestUrl, - onAgentChange, - fetchJsons, - setMetadata, - isEqualToModelPathValue, - isValueExistInModel, - showMonitoringSection, - onEnableMonitoringChange, - showCustomizeExporterSection, - onCustomizeExporterChange, - initBackupData, - isBackupDataLoadedTrue, - setBackupType, - getTypes, - isBackupType, - getContext, - onContextChange, - getConfigList, - onConfigChange, - showPause, - showSchedule, - showConfigList, - setBlueprintSwitch, - onBlueprintChange, - setArchiverSwitch, - onArchiverChange, - onBackupTypeChange, - returnFalse, - onInputChangeSchedule, - getDefaultSchedule, - isConsole, - isKubedb, - showOpsRequestOptions, - getNamespaces, - getDbs, - isRancherManaged, - getDbDetails, - initMetadata, - onNamespaceChange, - fetchNodeTopology, - isNodeTopologySelected, - setControlledResources, - setTrigger, - setApplyToIfReady, - - getMachines, - setAllowedMachine, - hasAnnotations, - hasNoAnnotations, - fetchTopologyMachines, - onMachineChange, + function initMetadata() { + const dbName = + getValue(model, '/resources/autoscalingKubedbComZooKeeperAutoscaler/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: '/metadata/name', + value: modifiedName, + force: true, + }) + + // delete the other type object from model + if (type === 'compute') + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComZooKeeperAutoscaler/spec/storage', + ) + if (type === 'storage') + commit( + 'wizard/model$delete', + '/resources/autoscalingKubedbComZooKeeperAutoscaler/spec/compute', + ) + } + + 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() { + const nodeTopologyName = + getValue( + model, + '/resources/autoscalingKubedbComZooKeeperAutoscaler/spec/compute/nodeTopology/name', + ) || '' + return !!nodeTopologyName.length + } + + function setControlledResources(type) { + const list = ['cpu', 'memory'] + const path = `/resources/autoscalingKubedbComZooKeeperAutoscaler/spec/compute/${type}/controlledResources` + commit('wizard/model$update', { + path: path, + value: list, + force: true, + }) + return list + } + + function setTrigger(path) { + let value = getValue(model, `/resources/${path}`) + if (value) return value + return 'On' + } + + function setApplyToIfReady() { + return 'IfReady' + } + + async function fetchTopologyMachines() { + const instance = hasAnnotations() + + 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 setAllowedMachine(type, minmax) { + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = {} + } + + const machine = parsedInstance[type] || '' + const mx = machine?.includes(',') ? machine.split(',')[1] : '' + const mn = machine?.includes(',') ? machine.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(type, minmax) { + const depends = minmax === 'min' ? 'max' : 'min' + const dependantPath = `/allowedMachine-${type}-${depends}` + + 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 hasAnnotations() { + const annotations = getValue( + model, + '/resources/autoscalingKubedbComZooKeeperAutoscaler/metadata/annotations', + ) + const instance = annotations?.['kubernetes.io/instance-type'] + + return !!instance + } + + function hasNoAnnotations() { + return !hasAnnotations() + } + + function onMachineChange(type) { + const annoPath = '/resources/autoscalingKubedbComZooKeeperAutoscaler/metadata/annotations' + const annotations = getValue(model, annoPath) || {} + const instance = annotations['kubernetes.io/instance-type'] + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = {} + } + + // Now discriminator values are objects with { machine, cpu, memory } + const minMachineObj = getValue(discriminator, `/allowedMachine-${type}-min`) + const maxMachineObj = getValue(discriminator, `/allowedMachine-${type}-max`) + const minMachine = minMachineObj?.machine || '' + const maxMachine = maxMachineObj?.machine || '' + const minMaxMachine = `${minMachine},${maxMachine}` + + parsedInstance[type] = minMaxMachine + const instanceString = JSON.stringify(parsedInstance) + annotations['kubernetes.io/instance-type'] = instanceString + + // 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/autoscalingKubedbComZooKeeperAutoscaler/spec/compute/${type}` + + if (minMachine && maxMachine && instance !== instanceString) { + 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 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 isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers?.find((item) => item === 'Rancher') + return !!found + } + + function onTriggerChange(type) { + const trigger = getValue(discriminator, `/${type}/trigger`) + const commitPath = `/resources/autoscalingKubedbComZooKeeperAutoscaler/spec/${type}/trigger` + + commit('wizard/model$update', { + path: commitPath, + value: trigger ? 'On' : 'Off', + force: true, + }) + } + + function returnFalse() { + return false + } + + 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/kubedbComZooKeeper/spec/monitor/prometheus/exporter/env', + value: filteredEnv, + force: true, + }) + } + + function initEnvArray() { + const env = getValue( + model, + '/resources/kubedbComZooKeeper/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/kubedbComZooKeeper/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 { + returnFalse, + initScheduleBackup, + initScheduleBackupForEdit, + showBackupForm, + initBackupData, + isBackupDataLoadedTrue, + setBackupType, + getTypes, + onBackupTypeChange, + isBackupType, + setBlueprintSwitch, + onBlueprintChange, + setArchiverSwitch, + onArchiverChange, + getContext, + onContextChange, + getConfigList, + onConfigChange, + showPause, + setPausedValue, + showConfigList, + showSchedule, + showScheduleBackup, + getDefaultSchedule, + onInputChangeSchedule, + resourceNames, + getNamespacedResourceList, + getConfigMapKeys, + getSecrets, + getSecretKeys, + getResources, + isValueExistInModel, + showMonitoringSection, + onEnableMonitoringChange, + showCustomizeExporterSection, + onCustomizeExporterChange, + isEqualToModelPathValue, + onAgentChange, + onLabelChange, + getOpsRequestUrl, + setValueFrom, + isConfigMapTypeValueFrom, + isSecretTypeValueFrom, + onValueFromChange, + onNamespaceChange, + // Autoscaler functions + isConsole, + isKubedb, + showOpsRequestOptions, + getNamespaces, + getDbs, + getDbDetails, + initMetadata, + fetchNodeTopology, + isNodeTopologySelected, + setControlledResources, + setTrigger, + setApplyToIfReady, + fetchTopologyMachines, + setAllowedMachine, + getMachines, + hasAnnotations, + hasNoAnnotations, + onMachineChange, + handleUnit, + setValueFromDbDetails, + isRancherManaged, + onTriggerChange, + onEnvArrayChange, + initEnvArray, + isEqualToTemp, + initMonitoring, + } } diff --git a/charts/opskubedbcom-druidopsrequest-editor/ui/create-ui.yaml b/charts/opskubedbcom-druidopsrequest-editor/ui/create-ui.yaml index deee2eb04f..e20b8792dd 100644 --- a/charts/opskubedbcom-druidopsrequest-editor/ui/create-ui.yaml +++ b/charts/opskubedbcom-druidopsrequest-editor/ui/create-ui.yaml @@ -1,672 +1,833 @@ -steps: -- form: - discriminator: - dbDetails: - type: object +type: multi-step-form +step: + - type: single-step-form + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - schema: - $ref: discriminator#/properties/dbDetails - type: input - - if: showAndInitName - label: - text: labels.op_req_name - required: true - schema: - $ref: schema#/properties/metadata/properties/name - type: input - - computed: initNamespace - disabled: isNamespaceDisabled - fetch: getNamespaces - hasGroup: isRancherManaged - if: showAndInitNamespace - label: - text: labels.namespace - onChange: onNamespaceChange - required: true - schema: - $ref: schema#/properties/metadata/properties/namespace - type: select - - computed: initDatabaseRef - disabled: isDatabaseRefDisabled - fetch: getDbs - if: showAndInitDatabaseRef - label: - text: labels.databaseRef - onChange: onDbChange - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/databaseRef/properties/name - type: select - - if: showConfigureOpsrequestLabel - label: - text: labels.config_ops_request - type: label-element - - computed: getRequestTypeFromRoute - disabled: isDbDetailsLoading - hasDescription: true - if: showAndInitOpsRequestType - individualItemDisabilityCheck: disableOpsRequest - label: - text: labels.ops_request_type - onChange: onRequestTypeChange - options: - - description: options.UpdateVersion.description - text: options.UpdateVersion.text - value: UpdateVersion - - description: options.HorizontalScaling.description - text: options.HorizontalScaling.text - value: HorizontalScaling - - description: options.VerticalScaling.description - text: options.VerticalScaling.text - value: VerticalScaling - - description: options.VolumeExpansion.description - text: options.VolumeExpansion.text - value: VolumeExpansion - - description: options.Restart.description - text: options.Restart.text - value: Restart - - description: options.Reconfigure.description - text: options.Reconfigure.text - value: Reconfigure - - description: options.ReconfigureTLS.description - text: options.ReconfigureTLS.text - value: ReconfigureTLS - schema: - $ref: schema#/properties/spec/properties/type - type: radio - - elements: - - computed: setValueFromDbDetails|/spec/version - fetch: getDbVersions - label: - text: labels.targetVersion - schema: - $ref: schema#/properties/spec/properties/updateVersion/properties/targetVersion - type: select - if: ifRequestTypeEqualsTo|UpdateVersion - type: single-step-form - - elements: - - discriminator: - machine-middleManagers: - default: "" - type: string - elements: - - computed: setMachine|middleManagers - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|middleManagers|/spec/topology/middleManagers/podTemplate/spec/containers - schema: - $ref: discriminator#/machine-middleManagers - type: select - - if: isMachineCustom|/machine-middleManagers - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/middleManagers/properties/resources - type: resource-input-form - - label: - text: Node Selection Policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/middleManagers/properties/nodeSelectionPolicy - type: select - - elements: - - label: - text: key - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/middleManagers/properties/topology/properties/key - type: input - - label: - text: value - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/middleManagers/properties/topology/properties/value - type: input - label: - text: Topology - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/middleManagers/properties/topology - show_label: true - type: single-step-form - label: - text: Middle Managers - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/middleManagers - show_label: true - type: single-step-form - - discriminator: - machine-historicals: - default: "" - type: string - elements: - - computed: setMachine|historicals - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|historicals|/spec/topology/historicals/podTemplate/spec/containers - schema: - $ref: discriminator#/machine-historicals - type: select - - if: isMachineCustom|/machine-historicals - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/historicals/properties/resources - type: resource-input-form - - label: - text: Node Selection Policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/historicals/properties/nodeSelectionPolicy - type: select - - elements: - - label: - text: key - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/historicals/properties/topology/properties/key - type: input - - label: - text: value - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/historicals/properties/topology/properties/value - type: input - label: - text: Topology - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/historicals/properties/topology - show_label: true - type: single-step-form - label: - text: Historicals - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/historicals - show_label: true - type: single-step-form - - discriminator: - machine-brokers: - default: "" - type: string - elements: - - computed: setMachine|brokers - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|brokers|/spec/topology/brokers/podTemplate/spec/containers - schema: - $ref: discriminator#/machine-brokers - type: select - - if: isMachineCustom|/machine-brokers - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/brokers/properties/resources - type: resource-input-form - - label: - text: Node Selection Policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/brokers/properties/nodeSelectionPolicy - type: select - - elements: - - label: - text: key - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/brokers/properties/topology/properties/key - type: input - - label: - text: value - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/brokers/properties/topology/properties/value - type: input - label: - text: Topology - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/brokers/properties/topology - show_label: true - type: single-step-form - label: - text: Broker - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/brokers - show_label: true - type: single-step-form - - discriminator: - machine-coordinators: - default: "" - type: string +# common + - type: input + label: op_req_name + if: + type: function + name: showAndInitName + validation: + type: required + schema: schema/properties/metadata/properties/name + - type: select + label: Namespace + if: + type: function + name: showAndInitNamespace + init: + type: func + value: initNamespace + disable: isNamespaceDisabled + loader: getNamespaces + validation: + type: required + hasGroup: isRancherManaged + schema: schema/properties/metadata/properties/namespace + - type: select + label: Database Ref + if: + type: function + name: showAndInitDatabaseRef + loader: + name: getDbs + watchPaths: + - schema/properties/metadata/properties/namespace + init: + type: func + value: initDatabaseRef + validation: + type: required + disable: isDatabaseRefDisabled + refresh: true + watcher: + func: onDbChange + paths: + - schema/properties/spec/properties/databaseRef/properties/name + schema: schema/properties/spec/properties/databaseRef/properties/name + - type: label-element + label: config_ops_request + if: + type: function + name: showConfigureOpsrequestLabel + - type: radio + label: Type of Ops Request + if: + type: function + name: showAndInitOpsRequestType + options: + - description: Manage your CPU resources + text: Vertical Scaling + value: VerticalScaling + - description: Expand your database volume + text: Volume Expansion + value: VolumeExpansion + - description: Restart your database + text: Restart + value: Restart + - description: Reconfigure your database + text: Reconfigure + value: Reconfigure + init: + type: func + value: getRequestTypeFromRoute + disable: isDbDetailsLoading + watcher: + func: isDbDetailsLoading + paths: + - temp/dbDetails + - schema/properties/spec/properties/databaseRef/properties/name + isHorizontal: true + schema: schema/properties/spec/properties/type +# Vertical Scale + - type: block-layout + if: + type: function + name: ifRequestTypeEqualsTo|VerticalScaling elements: - - computed: setMachine|coordinators - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|coordinators|/spec/topology/coordinators/podTemplate/spec/containers - schema: - $ref: discriminator#/machine-coordinators - type: select - - if: isMachineCustom|/machine-coordinators - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/coordinators/properties/resources - type: resource-input-form - - label: - text: Node Selection Policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/coordinators/properties/nodeSelectionPolicy - type: select - - elements: - - label: - text: key - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/coordinators/properties/topology/properties/key - type: input - - label: - text: value - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/coordinators/properties/topology/properties/value - type: input - label: - text: Topology - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/coordinators/properties/topology - show_label: true - type: single-step-form - label: - text: Coordinators - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/coordinators - show_label: true - type: single-step-form - - discriminator: - machine-overlords: - default: "" - type: string + - type: block-layout + label: Middle Managers + showLabels: true + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines|middleManagers + init: + type: func + value: setMachine|middleManagers + watcher: + func: onMachineChange|middleManagers|/spec/topology/middleManagers/podTemplate/spec/containers + paths: + - temp/properties/machine-middleManagers + schema: temp/properties/machine-middleManagers + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + schema: schema/properties/spec/properties/verticalScaling/properties/middleManagers/properties/nodeSelectionPolicy + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + schema: schema/properties/spec/properties/verticalScaling/properties/middleManagers/properties/topology/properties/key + - type: input + label: Value + schema: schema/properties/spec/properties/verticalScaling/properties/middleManagers/properties/topology/properties/value + - type: block-layout + label: Historicals + showLabels: true + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines|historicals + init: + type: func + value: setMachine|historicals + watcher: + func: onMachineChange|historicals|/spec/topology/historicals/podTemplate/spec/containers + paths: + - temp/properties/machine-historicals + schema: temp/properties/machine-historicals + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + schema: schema/properties/spec/properties/verticalScaling/properties/historicals/properties/nodeSelectionPolicy + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + schema: schema/properties/spec/properties/verticalScaling/properties/historicals/properties/topology/properties/key + - type: input + label: Value + schema: schema/properties/spec/properties/verticalScaling/properties/historicals/properties/topology/properties/value + - type: block-layout + label: Broker + showLabels: true + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines|brokers + init: + type: func + value: setMachine|brokers + watcher: + func: onMachineChange|brokers|/spec/topology/brokers/podTemplate/spec/containers + paths: + - temp/properties/machine-brokers + schema: temp/properties/machine-brokers + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + schema: schema/properties/spec/properties/verticalScaling/properties/brokers/properties/nodeSelectionPolicy + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + schema: schema/properties/spec/properties/verticalScaling/properties/brokers/properties/topology/properties/key + - type: input + label: Value + schema: schema/properties/spec/properties/verticalScaling/properties/brokers/properties/topology/properties/value + - type: block-layout + label: Coordinators + showLabels: true + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines|coordinators + init: + type: func + value: setMachine|coordinators + watcher: + func: onMachineChange|coordinators|/spec/topology/coordinators/podTemplate/spec/containers + paths: + - temp/properties/machine-coordinators + schema: temp/properties/machine-coordinators + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + schema: schema/properties/spec/properties/verticalScaling/properties/coordinators/properties/nodeSelectionPolicy + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + schema: schema/properties/spec/properties/verticalScaling/properties/coordinators/properties/topology/properties/key + - type: input + label: Value + schema: schema/properties/spec/properties/verticalScaling/properties/coordinators/properties/topology/properties/value + - type: block-layout + label: Overlords + showLabels: true + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines|overlords + init: + type: func + value: setMachine|overlords + watcher: + func: onMachineChange|overlords|/spec/topology/overlords/podTemplate/spec/containers + paths: + - temp/properties/machine-overlords + schema: temp/properties/machine-overlords + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + schema: schema/properties/spec/properties/verticalScaling/properties/overlords/properties/nodeSelectionPolicy + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + schema: schema/properties/spec/properties/verticalScaling/properties/overlords/properties/topology/properties/key + - type: input + label: Value + schema: schema/properties/spec/properties/verticalScaling/properties/overlords/properties/topology/properties/value + - type: block-layout + label: Routers + showLabels: true + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines|routers + init: + type: func + value: setMachine|routers + watcher: + func: onMachineChange|routers|/spec/topology/routers/podTemplate/spec/containers + paths: + - temp/properties/machine-routers + schema: temp/properties/machine-routers + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + schema: schema/properties/spec/properties/verticalScaling/properties/routers/properties/nodeSelectionPolicy + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + schema: schema/properties/spec/properties/verticalScaling/properties/routers/properties/topology/properties/key + - type: input + label: Value + schema: schema/properties/spec/properties/verticalScaling/properties/routers/properties/topology/properties/value + - type: block-layout + label: Exporter + showLabels: true + hideBlock: true + elements: + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setExporter|cpu + type: input + 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 + watcher: + func: onExporterResourceChange|memory + paths: + - schema/properties/spec/properties/verticalScaling/properties/exporter/properties/resources/properties/limits/properties/memory +# Volume Expansion + - type: block-layout + label: Volume Expansion Form + if: + type: function + name: ifRequestTypeEqualsTo|VolumeExpansion elements: - - computed: setMachine|overlords - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|overlords|/spec/topology/overlords/podTemplate/spec/containers - schema: - $ref: discriminator#/machine-overlords - type: select - - if: isMachineCustom|/machine-overlords - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/overlords/properties/resources - type: resource-input-form - - label: - text: Node Selection Policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/overlords/properties/nodeSelectionPolicy - type: select - - elements: - - label: - text: key - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/overlords/properties/topology/properties/key - type: input - - label: - text: value - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/overlords/properties/topology/properties/value - type: input - label: - text: Topology - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/overlords/properties/topology - show_label: true - type: single-step-form - label: - text: Overlords - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/overlords - show_label: true - type: single-step-form - - discriminator: - machine-routers: - default: "" - type: string + - type: horizontal-layout + elements: + - type: block-layout + elements: + - type: label-element + 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: select + label: Mode + options: + - text: Offline + value: Offline + - text: Online + value: Online + validation: + type: required + schema: schema/properties/spec/properties/volumeExpansion/properties/mode + - type: block-layout + label: Historicals + showLabels: true + fixedBlock: true + elements: + - type: horizontal-layout + elements: + - type: input-compare + label: Storage Size + subtitle: How much extra storage does your database need? Specify the size(e.g., 2Gi for 2 gigabytes) so we can allocate it correctly + init: + type: func + value: setValueFromDbDetails|/spec/topology/historicals/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/topology/historicals/storage/resources/requests/storage|/spec/volumeExpansion/historicals + schema: schema/properties/spec/properties/volumeExpansion/properties/historicals + - type: info + hasIcon: true + label: Historicals nodes store historical data segments. Increasing storage allows for more historical data retention. + - type: block-layout + label: Middle Managers + showLabels: true + fixedBlock: true + elements: + - type: horizontal-layout + elements: + - type: input-compare + label: Storage Size + subtitle: How much extra storage does your database need? Specify the size(e.g., 2Gi for 2 gigabytes) so we can allocate it correctly + init: + type: func + value: setValueFromDbDetails|/spec/topology/middleManagers/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/topology/middleManagers/storage/resources/requests/storage|/spec/volumeExpansion/middleManagers + schema: schema/properties/spec/properties/volumeExpansion/properties/middleManagers + - type: info + hasIcon: true + label: Middle Managers handle real-time ingestion tasks. More storage enables larger batch processing capabilities. +# Reconfigure + - type: block-layout + label: Reconfigure Form + if: + name: ifRequestTypeEqualsTo|Reconfigure + type: function + loader: + name: fetchConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace elements: - - computed: setMachine|routers - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|routers|/spec/topology/routers/podTemplate/spec/containers - schema: - $ref: discriminator#/machine-routers - type: select - - if: isMachineCustom|/machine-routers - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/routers/properties/resources - type: resource-input-form - - label: - text: Node Selection Policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/routers/properties/nodeSelectionPolicy - type: select - - elements: - - label: - text: key - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/routers/properties/topology/properties/key - type: input - - label: - text: value - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/routers/properties/topology/properties/value - type: input - label: - text: Topology - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/routers/properties/topology - show_label: true - type: single-step-form - label: - text: Routers - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/routers - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|VerticalScaling - type: single-step-form - - elements: - - elements: - - computed: setValueFromDbDetails|/spec/topology/historicals/storage/resources/requests/storage - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/historicals - type: input - validationRuleObject: - func: checkVolume|/spec/topology/historicals/storage/resources/requests/storage|/spec/volumeExpansion/historicals - label: - text: Historicals - show_label: true - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/topology/middleManagers/storage/resources/requests/storage - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/middleManagers - type: input - validationRuleObject: - func: checkVolume|/spec/topology/middleManagers/storage/resources/requests/storage|/spec/volumeExpansion/middleManagers - label: - text: Middle Managers - show_label: true - type: single-step-form - - label: - text: Mode - options: - - text: Offline - value: Offline - - text: Online - value: Online - required: true - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/mode - type: select - if: ifRequestTypeEqualsTo|VolumeExpansion - label: - text: Volume Expansion Form - type: single-step-form - - elements: - - discriminator: - reconfigurationType: - type: string + - type: block-layout + label: Configuration + elements: + - type: label-element + label: '' + subtitle: Select a new configuration secret, apply a custom configuration, or remove an existing setup to update your database settings + - type: tab-layout + label: New Config Secret + schema: temp/properties/reconfigurationType + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + elements: + - type: block-layout + label: Config Secret + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret + type: function + elements: + - type: label-element + label: Config Secret + subtitle: Select a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: schema/properties/spec/properties/configuration/properties/configSecret/properties/name + refresh: true + label: Config Secret + loader: + name: getConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/createSecret/properties/status + init: + type: func + value: setValueFromDbDetails|/spec/configSecret/name + watcher: + func: onCreateSecretChange + paths: + - temp/properties/createSecret/properties/status + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|create + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + - type: block-layout + label: Create a New Config Secret + showLabels: true + if: + type: function + name: isCreateSecret + hasButton: + text: Save + hasCancel: cancelCreateSecret + action: createNewConfigSecret + elements: + - type: input + label: Secret Name + schema: temp/properties/createSecret/properties/name + validation: + type: required + - type: array-object-form + label: String Data + schema: temp/properties/createSecret/properties/data + buttonClass: is-light is-outlined + validation: + type: required + elements: + - type: select + label: Key + schema: key + loader: + name: onSelectedSecretChange + watchPaths: + - temp/properties/createSecret/properties/data + validation: + type: required + - type: textarea + label: Value + schema: value + - type: multi-file-editor + editorHeight: 500px + readonly: true + if: + type: function + name: isNotCreateSecret + loader: + name: onNewConfigSecretChange + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + schema: temp/properties/newConfigSecret + - type: block-layout + label: ApplyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig + type: function + elements: + - type: label-element + 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). + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfiguration + refresh: true + label: Configuration + loader: getConfigSecretsforAppyConfig + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|apply + watchPaths: + - temp/properties/selectedConfiguration + - type: multi-file-editor + editorHeight: 500px + schema: temp/properties/applyConfig + loader: + name: setApplyConfig + watchPaths: + - temp/properties/selectedConfiguration + watcher: + func: onApplyconfigChange + paths: + - temp/properties/applyConfig + - type: block-layout + label: Remove + if: + name: ifReconfigurationTypeEqualsTo|remove + type: function + elements: + - type: label-element + label: Remove + subtitle: Selected a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfigurationRemove + refresh: true + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|remove + watchPaths: + - temp/properties/selectedConfigurationRemove + - type: multi-file-editor + editorHeight: 500px + readonly: true + init: + type: func + value: onRemoveConfigChange + watcher: + func: onRemoveConfigChange + paths: + - temp/properties/selectedConfigurationRemove + schema: temp/properties/removeConfig +# Restart + - type: block-layout + label: TLS + if: + type: function + name: ifRequestTypeEqualsTo|ReconfigureTLS elements: - - label: - text: labels.reconfigurationType - onChange: onReconfigurationTypeChange - options: - - text: Select New Config Secret - value: selectNewConfigSecret - - text: Apply Config - value: applyConfig - - text: Remove - value: remove - required: true - schema: - $ref: discriminator#/properties/reconfigurationType - type: radio - - elements: - - add_new_button: - label: labels.createConfig - target: _blank - url: - function: createSecretUrl - computed: setValueFromDbDetails|/spec/configSecret/name - fetch: getConfigSecrets - label: - text: labels.configSecret - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret/properties/name - type: select - if: ifReconfigurationTypeEqualsTo|selectNewConfigSecret - label: - text: Configuration config secret - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret - type: single-step-form - - addFormLabel: labels.applyConfig.label - element: - discriminator: - configArray: - emitAs: applyConfig - type: array + - type: radio + label: TLS Operation + if: + type: function + name: hasTlsField + init: + type: func + value: initTlsOperation + watcher: + func: onTlsOperationChange + paths: + - temp/tlsOperation + options: + - text: Update + value: update + - text: Rotate + value: rotate + - text: Remove + value: remove + schema: temp/tlsOperation + - type: switch + label: Remove TLS + fullwidth: true + if: + type: function + name: isTlsEnabled + schema: schema/properties/spec/properties/tls/properties/remove + - type: switch + label: Rotate Certificates + fullwidth: true + if: + type: function + name: isTlsEnabled + schema: schema/properties/spec/properties/tls/properties/rotateCertificates + - type: block-layout + if: + type: function + name: showIssuerRefAndCertificates elements: - - label: - text: labels.applyConfig.key - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/key - type: input - - label: - text: labels.applyConfig.value - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/value - type: editor - type: single-step-form - if: ifReconfigurationTypeEqualsTo|applyConfig - label: - text: labels.applyConfig.label - onChange: onApplyconfigChange - required: true - schema: - $ref: discriminator#/properties/applyConfig - tableContents: - - inTableColumn: true - label: - text: labels.applyConfig.key - path: key - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.applyConfig.value - path: value - type: value - typeOfValue: code - type: single-step-form-array - - if: returnFalse - label: - text: labels.removeCustomConfig - schema: - $ref: schema#/properties/spec/properties/configuration/properties/removeCustomConfig - type: switch - label: - text: labels.configuration - schema: - $ref: schema#/properties/spec/properties/configuration - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|Reconfigure - label: - text: Reconfigure Form - type: single-step-form - - discriminator: - tlsOperation: - default: update - type: string - elements: - - computed: initTlsOperation - if: hasTlsField - label: - text: labels.tlsOperation - onChange: onTlsOperationChange - options: - - text: Update - value: update - - text: Rotate - value: rotate - - text: Remove - value: remove - schema: - $ref: discriminator#/properties/tlsOperation - type: radio - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/remove - type: switch - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/rotateCertificates - type: switch - - elements: - - computed: initIssuerRefApiGroup - disabled: true - label: - text: labels.api_group - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup - type: input - - computed: setValueFromDbDetails|/spec/tls/issuerRef/kind - label: - text: labels.kind - options: - - text: Issuer - value: Issuer - - text: ClusterIssuer - value: ClusterIssuer - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/kind - sortable: true - type: select - - allowUserDefinedOption: true - computed: setValueFromDbDetails|/spec/tls/issuerRef/name - fetch: getIssuerRefsName - label: - text: labels.name - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/name - sortable: true - type: select - if: showIssuerRefAndCertificates - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef - type: single-step-form - - alias: reusable_certificates - chart: - name: uibytebuildersdev-component-certificates - version: v0.29.0 - computed: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates - functionCallbacks: - getAliasOptions: - $ref: functions#/getAliasOptions - if: showIssuerRefAndCertificates - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/spec/properties/tls/properties/certificates - type: reusable-element - if: ifRequestTypeEqualsTo|ReconfigureTLS - label: - text: labels.tls - schema: - $ref: schema#/properties/spec/properties/tls - type: single-step-form - - label: - text: labels.timeout - options: - - text: 5 minutes - value: 5m - - text: 10 minutes - value: 10m - - text: 30 minutes - value: 30m - - text: 1 hour - value: 1h - - text: 2 hours - value: 2h - - text: 5 hours - value: 5h - - text: 10 hours - value: 10h - schema: - $ref: schema#/properties/spec/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: labels.apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/spec/properties/apply - type: radio - type: single-step-form - id: basic - title: steps.0.label -type: multi-step-form + - type: input + label: API Group + init: + type: func + value: initIssuerRefApiGroup + disable: true + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup + - type: select + label: Kind + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/kind + options: + - text: Issuer + value: Issuer + - text: ClusterIssuer + value: ClusterIssuer + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - type: select + label: Name + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/name + loader: + name: getIssuerRefsName + watchPaths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - schema/properties/metadata/properties/namespace + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/name + - type: block-layout + label: Certificates + showLabels: false + if: + type: function + name: showIssuerRefAndCertificates + init: + type: func + value: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates + elements: + - type: array-object-form + label: Certificates + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/tls/properties/certificates + elements: + - type: select + label: Alias + loader: fetchAliasOptions + disable: disableAlias + schema: alias + validation: + type: required + - type: input + label: Secret Name + schema: secretName + - type: input + label: Duration + schema: duration + - type: input + label: Renew Before + schema: renewBefore + - type: array-item-form + label: Organizations + buttonClass: is-light is-outlined + schema: subject/properties/organizations + element: + type: input + label: Organization + - type: array-item-form + label: Countries + buttonClass: is-light is-outlined + schema: subject/properties/countries + element: + type: input + label: Country + - type: array-item-form + label: Organizational Units + buttonClass: is-light is-outlined + schema: subject/properties/organizationalUnits + element: + type: input + label: Organizational Unit + - type: array-item-form + label: Provinces + buttonClass: is-light is-outlined + schema: subject/properties/provinces + element: + type: input + label: Province + - type: array-item-form + label: DNS Names + buttonClass: is-light is-outlined + schema: dnsNames + element: + type: input + label: DNS Name + - type: array-item-form + label: IP Addresses + buttonClass: is-light is-outlined + schema: ipAddresses + element: + type: input + label: IP Address +# common + - type: block-layout + label: OpsRequest Options + showLabels: true + elements: + - type: time-picker + label: Timeout + subtitle: Specify the maximum time allowed for the scaling operation to complete. Use formats like 30sec, 1min(1 minute) or 2h(2 hours). + schema: 'schema/properties/spec/properties/timeout' + - type: radio + label: Apply + schema: 'schema/properties/spec/properties/apply' + init: + type: func + value: setApplyToIfReady + options: + - text: IfReady (OpsRequest will be applied if database is ready) + value: IfReady + - text: Always (OpsRequest will always be applied) + value: Always diff --git a/charts/opskubedbcom-druidopsrequest-editor/ui/functions.js b/charts/opskubedbcom-druidopsrequest-editor/ui/functions.js index 4157aca089..1eaf1a73ca 100644 --- a/charts/opskubedbcom-druidopsrequest-editor/ui/functions.js +++ b/charts/opskubedbcom-druidopsrequest-editor/ui/functions.js @@ -1,3 +1,8 @@ +const { axios, useOperator, store, useToast } = window.vueHelpers || {} + +// ============================================================ +// MACHINE PROFILES - Predefined Resource Configurations +// ============================================================ const machines = { 'db.t.micro': { resources: { @@ -304,1018 +309,1873 @@ const machineList = [ 'db.r.24xlarge', ] -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) - } +// ============================================================ +// DRUID NODE TYPES +// ============================================================ +const druidNodeTypes = [ + 'coordinators', + 'overlords', + 'brokers', + 'routers', + 'historicals', + 'middleManagers', +] - return { - ui: ui.data || {}, - language: language.data || {}, - functions, - } -} +let machinesFromPreset = [] +let secretArray = [] +const configSecretKeys = ['.properties'] -function returnFalse() { - return false -} +export const useFunc = (model) => { + const route = store.state?.route + const toast = useToast() -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + const { getValue, storeGet, discriminator, setDiscriminatorValue, commit } = useOperator( + model, + store.state, + ) -async function getNamespaces({ axios, storeGet }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + // Initialize on load + showAndInitOpsRequestType() - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + // ============================================================ + // CORE UTILITY FUNCTIONS + // ============================================================ - const resources = (resp && resp.data && resp.data.items) || [] + async function fetchJsons({ axios, itemCtx }) { + let ui = {} + let language = {} + let functions = {} + const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, + 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}`, + ) + const evalFunc = new Function(functionString.data || '') + functions = evalFunc() + } catch (e) { + console.log(e) } - }) -} - -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - 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}/druids`, - { - 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, + ui: ui.data || {}, + language: language.data || {}, + functions, } - }) -} + } -async function getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) { - 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') + function returnFalse() { + return false + } + + function isEqualToModelPathValue(value, path) { + const modelValue = getValue(model, path) + // watchDependency(`model#${path}`) + return modelValue === value + } - if (namespace && name) { - const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/druids/${name}` - const resp = await axios.get(url) + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } - setDiscriminatorValue('/dbDetails', resp.data || {}) + // ============================================================ + // NAMESPACE & DATABASE RESOURCE FUNCTIONS + // ============================================================ - return resp.data || {} - } else return {} -} + async function getNamespaces() { + if (storeGet('/route/params/actions')) return [] + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -async function getDbVersions({ axios, storeGet, getValue, discriminator }) { - 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 url = `/clusters/${owner}/${cluster}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/kubedb-ui-presets` + const resources = (resp && resp.data && resp.data.items) || [] - 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) - } + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) } - try { - const presetVersions = presets.admin?.databases?.Druid?.versions?.available || [] - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null, updateConstraints: null }, - }, - }, - } + 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') const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/catalog.kubedb.com/v1alpha1/druidversions`, + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/druids`, { - params: queryParams, + params: { filter: { items: { metadata: { name: null } } } }, }, ) 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 allowed = found?.spec?.updateConstraints?.allowlist || [] - 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 filteredDruidDbVersions = 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.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.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.includes(item.metadata?.name)) && - isVersionWithinConstraints(item.spec?.version, limit) - ) - }) - - return filteredDruidDbVersions.map((item) => { + return resources.map((item) => { const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' return { - text: `${name} (${specVersion})`, + text: name, value: name, } }) - } catch (e) { - console.log(e) - return [] } -} -function versionCompare(v1, v2) { - const arr1 = v1.split('.').map(Number) - const arr2 = v2.split('.').map(Number) + 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') - for (let i = 0; i < Math.max(arr1.length, arr2.length); i++) { - const num1 = arr1[i] || 0 - const num2 = arr2[i] || 0 + if (namespace && name) { + const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/druids/${name}` + try { + const resp = await axios.get(url) + setDiscriminatorValue('/dbDetails', resp.data || {}) + return resp.data || {} + } catch (e) { + console.log(e) + return {} + } + } else return {} + } - if (num1 > num2) return 1 // v1 is higher - if (num1 < num2) return -1 // v2 is higher + function isTlsEnabled() { + const dbDetails = getValue(discriminator, '/dbDetails') + return ( + (dbDetails?.spec?.sslMode && + dbDetails?.spec?.sslMode !== 'disabled' && + dbDetails?.spec?.sslMode !== 'disable') || + dbDetails?.spec?.tls + ) + } + + 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 { + const presetVersions = presets.admin?.databases?.Druid?.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/druidversions`, + { + 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 allowed = found?.spec?.updateConstraints?.allowlist || [] + const limit = allowed.length ? allowed[0] : '0.0' + + const filteredDruidVersions = sortedVersions.filter((item) => { + if (limit === '0.0') + return ( + !item.spec?.deprecated && + (presets.status === '404' || presetVersions.includes(item.metadata?.name)) && + versionCompare(item.spec?.version, ver) >= 0 + ) + else if (!limit.match(/^(>=|<=|>|<)/)) + return ( + !item.spec?.deprecated && + (presets.status === '404' || presetVersions.includes(item.metadata?.name)) && + item.spec?.version === limit + ) + else + return ( + !item.spec?.deprecated && + (presets.status === '404' || presetVersions.includes(item.metadata?.name)) && + isVersionWithinConstraints(item.spec?.version, limit) + ) + }) + return filteredDruidVersions.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 [] + } } - return 0 // versions are equal -} -function isVersionWithinConstraints(version, constraints) { - let constraintsArr = [] - if (constraints.includes(',')) constraintsArr = constraints?.split(',')?.map((c) => c.trim()) - else constraintsArr = [constraints] + function versionCompare(v1, v2) { + const arr1 = v1.split('.').map(Number) + const arr2 = v2.split('.').map(Number) - for (let constraint of constraintsArr) { - let match = constraint.match(/^(>=|<=|>|<)/) - let operator = match ? match[0] : '' - let constraintVersion = constraint.replace(/^(>=|<=|>|<)/, '').trim() + for (let i = 0; i < Math.max(arr1.length, arr2.length); i++) { + const num1 = arr1[i] || 0 + const num2 = arr2[i] || 0 - let comparison = versionCompare(version, constraintVersion) - if ( - (operator === '>=' && comparison < 0) || - (operator === '<=' && comparison > 0) || - (operator === '>' && comparison <= 0) || - (operator === '<' && comparison >= 0) - ) - return false + if (num1 > num2) return 1 + if (num1 < num2) return -1 + } + return 0 } - return true -} -function ifRequestTypeEqualsTo({ model, getValue, watchDependency }, type) { - const selectedType = getValue(model, '/spec/type') - watchDependency('model#/spec/type') + 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 + } - return selectedType === type -} + function initNamespace() { + const { namespace } = route.query || {} + return namespace || null + } -function onRequestTypeChange({ model, getValue, commit }) { - 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 initDatabaseRef() { + // watchDependency('model#/metadata/namespace') + const { name } = route.params || {} + return name + } -function disableOpsRequest({ itemCtx, discriminator, getValue, watchDependency }) { - if (itemCtx.value === 'HorizontalScaling') { - const dbType = getDbType({ - discriminator, - getValue, - watchDependency, - }) + function onNamespaceChange() { + commit('wizard/model$delete', '/spec/type') + } - if (dbType === 'Standalone') return true - else return false - } else return false -} + function onDbChange() { + commit('wizard/model$delete', '/spec/type') + getDbDetails() + } -function getDbTls({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + // ============================================================ + // OPSREQUEST TYPE FUNCTIONS + // ============================================================ - const { spec } = dbDetails || {} - return spec?.tls || undefined -} + function getRequestTypeFromRoute() { + const isDbloading = isDbDetailsLoading() + const { query } = route || {} + const { requestType } = query || {} + return isDbloading ? '' : requestType || '' + } -function getDbType({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') - const { spec } = dbDetails || {} - const { topology } = spec || {} - if (topology) return 'Topology' - else return 'Combined' -} + 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', + } -function initNamespace({ route }) { - const { namespace } = route.query || {} - return namespace || null -} + Object.keys(reqTypeMapping).forEach((key) => { + if (key !== selectedType) commit('wizard/model$delete', `/spec/${reqTypeMapping[key]}`) + }) + } -function initDatabaseRef({ route, watchDependency }) { - watchDependency('model#/metadata/namespace') - const { name } = route.params || {} - return name -} + function ifRequestTypeEqualsTo(type) { + const selectedType = getValue(model, '/spec/type') + // watchDependency('model#/spec/type') + return selectedType === type + } -function asDatabaseOperation(route) { - return !!route.params.actions -} + function asDatabaseOperation() { + return !!route.params.actions + } -function generateOpsRequestNameForClusterUI(getValue, model, route) { - const dbName = getValue(model, '/spec/databaseRef/name') + function generateOpsRequestNameForClusterUI() { + 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 : ''}` + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + 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) { + commit('wizard/model$update', { + path: '/metadata/name', + value: `${route.params.name}-${Math.floor(Date.now() / 1000)}-${lowerType}`, + force: true, + }) + } else { + commit('wizard/model$update', { + path: '/metadata/name', + value: generateOpsRequestNameForClusterUI(), + force: true, + }) + } + return !ver + } - const resources = route.params.resource || '' - const resource = resources.slice(0, -1) + function showAndInitNamespace() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/metadata/namespace', + value: `${route.query.namespace}`, + force: true, + }) + } + return !ver + } - const opsName = dbName ? dbName : resource - return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` -} + function showAndInitDatabaseRef() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/spec/databaseRef/name', + value: `${route.params.name}`, + force: true, + }) + } + return !ver + } -function showAndInitName({ route, commit, getValue, model, watchDependency }) { - watchDependency('model#/spec/type') - watchDependency('model#/spec/databaseRef/name') - const ver = asDatabaseOperation(route) + 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) + const opstype = match ? match[2] : '' + commit('wizard/model$update', { + path: '/spec/type', + value: opMap[opstype], + force: true, + }) + } + return !ver + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + function showConfigureOpsrequestLabel() { + return !asDatabaseOperation() + } - 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, - }) + function isNamespaceDisabled() { + const { namespace } = route.query || {} + return !!namespace } - return !ver -} -function showAndInitNamespace({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/metadata/namespace', - value: `${route.query.namespace}`, - force: true, - }) + + function isDatabaseRefDisabled() { + const { name } = route.params || {} + return !!name } - return !ver -} -function showAndInitDatabaseRef({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/spec/databaseRef/name', - value: `${route.params.name}`, - force: true, - }) + 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 } - return !ver -} -function showConfigureOpsrequestLabel({ route }) { - return !asDatabaseOperation(route) -} -function showAndInitOpsRequestType({ route, commit }) { - const ver = asDatabaseOperation(route) - const opMap = { - upgrade: 'UpdateVersion', - updateVersion: 'UpdateVersion', - horizontalscaling: 'HorizontalScaling', - verticalscaling: 'VerticalScaling', - volumeexpansion: 'VolumeExpansion', - restart: 'Restart', - reconfiguretls: 'ReconfigureTLS', - reconfigure: 'Reconfigure', - } - if (ver) { - const operation = route.params.actions - const match = /^(.*)-opsrequest-(.*)$/.exec(operation) - const opstype = match[2] - commit('wizard/model$update', { - path: '/spec/type', - value: opMap[opstype], - force: true, - }) + // ============================================================ + // DATABASE TYPE FUNCTIONS (Druid-specific) + // ============================================================ + + function getDbType() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') + const { spec } = dbDetails || {} + const { topology } = spec || {} + + if (topology) { + return 'topology' + } else { + return 'combined' + } } - return !ver -} + function ifDbTypeEqualsTo(type, mode, section) { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') + const { spec } = dbDetails || {} + const { topology } = spec || {} -// vertical scaling -function ifDbTypeEqualsTo({ discriminator, getValue, watchDependency, commit }, value, opsReqType) { - const verd = getDbType({ - discriminator, - getValue, - watchDependency, - }) - return value === verd -} + if (mode === 'combined') { + // For combined mode, check if topology doesn't exist + const isCombined = !topology -// machine profile stuffs -let machinesFromPreset = [] -function hasMachine({ getValue, discriminator }) { - const dbDetails = getValue(discriminator, '/dbDetails') - const annotations = dbDetails?.metadata?.annotations || {} - return !!annotations['kubernetes.io/instance-type'] -} + // Clear unused topology configurations when in combined mode + if (isCombined && section) { + clearOpsReqSpec(getValue, commit, 'combined', section) + } -function getMachines({ storeGet }) { - const presets = storeGet('/kubedbuiPresets') || {} - const avlMachines = presets.admin?.machineProfiles?.available || [] - let arr = [] - if (avlMachines.length) { - arr = avlMachines.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - 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 } - } else return { text: machine, value: machine } + return isCombined + } else if (mode === 'topology') { + // For topology mode, check if the specific node type exists + const hasTopology = !!(topology && topology[type]) + + // Clear unused combined configurations when in topology mode + if (hasTopology && section) { + clearOpsReqSpec(getValue, commit, type, section) } - }) - } else { - arr = machineList - .map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } - }) - .filter((val) => !!val) + + return hasTopology + } + + return false } - return arr -} -function setMachine({ getValue, discriminator, storeGet }, type) { - const dbDetails = getValue(discriminator, '/dbDetails') - 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 = {} + function clearOpsReqSpec(getValue, commit, type, opsReqType) { + if ( + opsReqType === 'verticalScaling' || + opsReqType === 'horizontalScaling' || + opsReqType === 'volumeExpansion' || + opsReqType === 'configuration' + ) { + const dbType = getDbType() + + if (dbType === 'topology') { + // Clear combined mode configurations + commit('wizard/model$delete', `/spec/${opsReqType}/node`) + + // Clear other topology node types except the current one + druidNodeTypes.forEach((nodeType) => { + if (nodeType !== type) { + commit('wizard/model$delete', `/spec/${opsReqType}/${nodeType}`) + } + }) + } else if (dbType === 'combined') { + // Clear all topology-specific configurations + druidNodeTypes.forEach((nodeType) => { + commit('wizard/model$delete', `/spec/${opsReqType}/${nodeType}`) + }) + } + } } - const machine = parsedInstance[type] || 'custom' - machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] + // ============================================================ + // MACHINE PROFILE FUNCTIONS + // ============================================================ - const machinePresets = machinesFromPreset.find((item) => item.id === machine) - if (machinePresets) return machine - else return 'custom' -} + function getMachines(type) { + const presets = storeGet('/kubedbuiPresets') || {} + const dbDetails = getValue(discriminator, '/dbDetails') -function onMachineChange({ getValue, discriminator, commit, model }, type, valPath) { - let selectedMachine = '' - selectedMachine = getValue(discriminator, `/machine-${type}`) - const machine = machinesFromPreset.find((item) => item.id === selectedMachine) + let limits = {} + + if (type === 'node' || !type) { + // Combined mode + limits = dbDetails?.spec?.podTemplate?.spec?.resources?.requests || { cpu: '', memory: '' } + } else { + // Topology mode - specific node type + limits = dbDetails?.spec?.topology?.[type]?.podTemplate?.spec?.resources?.requests || { + cpu: '', + memory: '', + } + } - let obj = {} - if (selectedMachine !== 'custom') { - if (machine) obj = { limits: { ...machine?.limits }, requests: { ...machine?.limits } } - else obj = machines[selectedMachine]?.resources - } else { - const val = getValue(discriminator, `/dbDetails${valPath}`) || {} - obj = Array.isArray(val) ? val[0]?.resources : { ...val } + 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 text = machineData.name ? machineData.name : machineData.id + return { + text, + 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 text = machine + return { + text, + value: { + machine: text, + cpu: machines[machine].resources.limits.cpu, + memory: machines[machine].resources.limits.memory, + }, + } + }) + .filter((val) => !!val) + } + return arr } - const path = `/spec/verticalScaling/${type}/resources` - if (obj && Object.keys(obj).length) - commit('wizard/model$update', { - path: path, - value: obj, - force: true, - }) + function setMachine(type) { + const dbDetails = getValue(discriminator, '/dbDetails') - // update metadata.annotations - const annotations = getValue(model, '/metadata/annotations') || {} - const instance = annotations['kubernetes.io/instance-type'] - let parsedInstance = {} - try { - if (instance) parsedInstance = JSON.parse(instance) - } catch (e) { - console.log(e) - parsedInstance = {} - } - if (selectedMachine === 'custom') delete parsedInstance[type] - else parsedInstance[type] = selectedMachine - annotations['kubernetes.io/instance-type'] = JSON.stringify(parsedInstance) - - if (machinesFromPreset.length) - commit('wizard/model$update', { - path: '/metadata/annotations', - value: annotations, - force: true, - }) + let limits = {} - if (parsedInstance && Object.keys(parsedInstance).length === 0) - commit('wizard/model$delete', '/metadata/annotations') -} + if (type === 'node' || !type) { + // Combined mode + limits = dbDetails?.spec?.podTemplate?.spec?.resources?.requests || { cpu: '', memory: '' } + } else { + // Topology mode - specific node type + limits = dbDetails?.spec?.topology?.[type]?.podTemplate?.spec?.resources?.requests || { + cpu: '', + memory: '', + } + } -function isMachineCustom({ watchDependency, getValue, discriminator }, path) { - watchDependency(`discriminator#${path}`) - const machine = getValue(discriminator, `${path}`) - return machine === 'custom' -} + 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 = {} + } + const machine = parsedInstance[type] || 'custom' -// for config secret -async function getConfigSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + 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 } + } - const secrets = (resp && resp.data && resp.data.items) || [] + function onMachineChange(type, path) { + let selectedMachine = {} + selectedMachine = getValue(discriminator, `/machine-${type}`) + 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 filteredSecrets = secrets + const specPath = `/spec/verticalScaling/${type}/resources` - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return filteredSecrets -} + if (obj && Object.keys(obj).length) + commit('wizard/model$update', { + path: specPath, + value: obj, + force: true, + }) -function createSecretUrl({ storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + // Update metadata.annotations + const annotations = getValue(model, '/metadata/annotations') || {} + const instance = annotations['kubernetes.io/instance-type'] + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = {} + } + parsedInstance[type] = selectedMachine.machine + annotations['kubernetes.io/instance-type'] = JSON.stringify(parsedInstance) + + if (machinesFromPreset.length) + commit('wizard/model$update', { + path: '/metadata/annotations', + value: annotations, + force: true, + }) - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/secrets/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/secrets/create` + if (parsedInstance && Object.keys(parsedInstance).length === 0) + commit('wizard/model$delete', '/metadata/annotations') } -} - -function isEqualToValueFromType({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/valueFromType') - const valueFrom = getValue(discriminator, '/valueFromType') - return valueFrom === value -} -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function isMachineCustom(path) { + // watchDependency(`discriminator#${path}`) + const machine = getValue(discriminator, `${path}`) + return machine === 'custom' + } - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + function setValueFromDbDetails(watchPath, commitPath) { + // watchDependency(`discriminator#${watchPath}`) + const retValue = getValue(discriminator, `/dbDetails${watchPath}`) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }) + if (commitPath) { + const tlsOperation = getValue(discriminator, '/tlsOperation') + if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + commit('wizard/model$update', { + path: commitPath, + value: retValue, + force: true, + }) + } + return retValue || undefined } - return ans -} -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + // ============================================================ + // VERTICAL SCALING FUNCTIONS + // ============================================================ - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` + function isVerticalScaleTopologyRequired(type) { + // watchDependency(`discriminator#/topologyKey-${type}`) + // watchDependency(`discriminator#/topologyValue-${type}`) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }) + const key = getValue(discriminator, `/topologyKey-${type}`) + const value = getValue(discriminator, `/topologyValue-${type}`) + const path = `/spec/verticalScaling/${type}/topology` - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + if (key || value) { + commit('wizard/model$update', { + path: path, + value: { key, value }, + force: true, + }) + return '' + } else { + commit('wizard/model$delete', path) + return false + } } - return ans -} -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - group, - version, - resource, -) { - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/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) - }) - } + // ============================================================ + // VOLUME EXPANSION FUNCTIONS + // ============================================================ - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + function checkVolume(currentVolPath, newVolPath) { + // watchDependency(`discriminator#${currentVolPath}`) + // watchDependency(`model#${newVolPath}`) + + const volume = getValue(discriminator, `/dbDetails${currentVolPath}`) + const input = getValue(model, newVolPath) + + 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' } - }) -} -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - 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, + 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, } - }) -} -// reconfiguration type -function ifReconfigurationTypeEqualsTo({ discriminator, getValue, watchDependency }, value) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - watchDependency('discriminator#/reconfigurationType') + const match = String(sizeStr).match(/^([0-9]+(?:\.[0-9]*)?)\s*([A-Za-z]*)$/) + if (!match) throw new Error('Invalid size format') - return reconfigurationType === value -} + const value = parseFloat(match[1]) + const unit = match[2] -function onApplyconfigChange({ discriminator, getValue, commit }) { - const applyconfig = getValue(discriminator, '/applyConfig') + if (!(unit in units)) + throw new Error('Unrecognized unit. Available units are K, Ki, M, Mi, G, Gi etc') - const configObj = {} - if (applyconfig) { - applyconfig.forEach((item) => { - const { key, value } = item - configObj[key] = value - }) + return value * units[unit] } - commit('wizard/model$update', { - path: '/spec/configuration/applyConfig', - value: configObj, - force: true, - }) -} + // ============================================================ + // CONFIGURATION FUNCTIONS + // ============================================================ -function onReconfigurationTypeChange({ commit, discriminator, getValue, setDiscriminatorValue }) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - setDiscriminatorValue('/applyConfig', []) - if (reconfigurationType === 'remove') { - commit('wizard/model$delete', `/spec/configuration`) + // Fetch and store database Infos + // for secret configurations in reconfigure + let configSecrets = [] + let secretConfigData = [] - commit('wizard/model$update', { - path: `/spec/configuration/removeCustomConfig`, - value: true, - force: true, + 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: ['.properties'], + }, + }, + ) + configSecrets = resp?.data?.response?.availableSecrets || [] + secretConfigData = resp?.data?.response?.configurations || [] + } 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 } }) - } else { - commit('wizard/model$delete', `/spec/configuration/configSecret`) - commit('wizard/model$delete', `/spec/configuration/applyConfig`) - commit('wizard/model$delete', `/spec/configuration/removeCustomConfig`) + mappedSecrets.push({ text: '+ Create a new Secret', value: 'Create' }) + return mappedSecrets } -} -// for tls -function hasTlsField({ discriminator, getValue, watchDependency }) { - const tls = getDbTls({ - discriminator, - getValue, - watchDependency, - }) + async function getConfigSecretsforAppyConfig() { + const secrets = secretConfigData.map((item) => { + return { text: item.componentName, value: item.componentName } + }) + return secrets + } - return !!tls -} + function getSelectedConfigurationData(type) { + type = type ? type + '/' : '' + const path = `/${type}selectedConfiguration` + const selectedConfiguration = getValue(discriminator, path) -function initIssuerRefApiGroup({ getValue, model, watchDependency, discriminator }) { - const kind = getValue(model, '/spec/tls/issuerRef/kind') - watchDependency('model#/spec/tls/issuerRef/kind') + if (!selectedConfiguration) { + return [] + } - if (kind) { - const apiGroup = getValue(discriminator, '/dbDetails/spec/tls/issuerRef/apiGroup') - if (apiGroup) return apiGroup - return 'cert-manager.io' - } else return undefined -} + const configuration = secretConfigData.find( + (item) => item.componentName === selectedConfiguration, + ) -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - 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` + if (!configuration) { + return [] + } - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + const result = [] + // Decode base64 and format as array of objects with name and content + Object.keys(configuration.data).forEach((fileName) => { try { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + // Decode base64 string + const decodedContent = atob(configuration.data[fileName]) + result.push({ + name: fileName, + content: decodedContent, + }) } catch (e) { - console.log(e) - presets.status = String(e.status) + 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 '' } - let clusterIssuers = presets.admin?.clusterIssuers?.available || [] - if (presets.status === '404') { - const url = `/clusters/${owner}/${cluster}/proxy/cert-manager.io/v1/clusterissuers` - return getIssuer(url) + + const configuration = secretConfigData.find( + (item) => item.componentName === selectedConfiguration, + ) + + if (!configuration) { + return '' } - return clusterIssuers + + 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 getIssuer(url) { + 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])) + try { - const resp = await axios.get(url) - const resources = (resp && resp.data && resp.data.items) || [] + 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() + } + } - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - 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 resources - } catch (e) { - console.log(e) - return [] } + return res } -} -function initTlsOperation() { - return 'update' -} -function onTlsOperationChange({ discriminator, getValue, commit }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + function isNotCreateSecret(type) { + return !isCreateSecret(type) + } - commit('wizard/model$delete', '/spec/tls') + 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`) - if (tlsOperation === 'rotate') { + 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) { + 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/tls/rotateCertificates', - value: true, - force: true, + 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 + } }) - commit('wizard/model$delete', '/spec/tls/certificates') - commit('wizard/model$delete', '/spec/tls/remove') - } else if (tlsOperation === 'remove') { + const { applyConfig } = applyconfigData + const configObj = [] + + if (applyConfig) { + Object.keys(applyConfig).forEach((fileName) => { + configObj.push({ + name: fileName, + content: applyConfig[fileName], + }) + }) + } else { + configObj.push({ name: '', 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/tls/remove', + path: `/spec/configuration/${type}removeCustomConfig`, value: true, - force: true, }) - commit('wizard/model$delete', '/spec/tls/certificates') - commit('wizard/model$delete', '/spec/tls/rotateCertificates') + + 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 } -} -function showIssuerRefAndCertificates({ discriminator, getValue, watchDependency }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') - watchDependency('discriminator#/tlsOperation') - const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' + async function onNewConfigSecretChange(type) { + type = type ? type + '/' : '' + const path = `/spec/configuration/${type}configSecret/name` + const selectedSecret = getValue(model, path) - return verd -} + if (!selectedSecret) { + commit('wizard/model$delete', `/spec/configuration/${type}configSecret`) + return [{ name: '', content: '' }] + } + if (selectedSecret === 'Create') return [{ name: '', content: '' }] -function isIssuerRefRequired({ discriminator, getValue, watchDependency }) { - const hasTls = hasTlsField({ - discriminator, - getValue, - watchDependency, - }) + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = storeGet('/route/query/namespace') || getValue(model, '/metadata/namespace') - return !hasTls -} + 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 + }) + } + }) -function getRequestTypeFromRoute({ route, model, discriminator, getValue, watchDependency }) { - const isDbloading = isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) - const { query } = route || {} - const { requestType } = query || {} - return isDbloading ? '' : requestType || '' -} + return configObj + } catch (e) { + console.error('Error fetching secret:', e) + return [{ name: '', content: '' }] + } + } -// ************************************** Set db details ***************************************** + function onSelectedSecretChange(index) { + const secretData = getValue(discriminator, 'createSecret/data') || [] + const selfSecrets = secretData.map((item) => item.key) -function isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - watchDependency('model#/spec/databaseRef/name') - const dbDetails = getValue(discriminator, '/dbDetails') - const dbName = getValue(model, '/spec/databaseRef/name') + const remainingSecrets = configSecretKeys.filter((item) => !selfSecrets.includes(item)) - return !dbDetails || !dbName -} + 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 + } -function setValueFromDbDetails( - { discriminator, getValue, watchDependency, commit }, - path, - commitPath, -) { - watchDependency('discriminator#/dbDetails') + /** + * Generate URL for creating a new secret in the console + * @returns {String} URL to secret creation page + */ + 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` + } + } - const retValue = getValue(discriminator, `/dbDetails${path}`) + /** + * Display the name of the currently selected config secret + * @param {Object} params - Function parameters + * @param {String} type - Node type (optional, Druid doesn't use it) + * @returns {String} Message indicating selected secret + */ + function getSelectedConfigSecret(type) { + // Druid doesn't use type-specific paths, just /spec/configuration/configSecret/name + const path = type + ? `/spec/configuration/${type}/configSecret/name` + : `/spec/configuration/configSecret/name` + const selectedSecret = getValue(model, path) + // watchDependency(`model#${path}`) + return `You have selected ${selectedSecret} secret` || 'No secret selected' + } - if (commitPath && retValue) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + /** + * Get the YAML representation of the selected config secret's data + * @param {Object} params - Function parameters + * @param {String} type - Node type (optional, Druid doesn't use it) + * @returns {String} YAML formatted secret data + */ + function getSelectedConfigSecretValue(type) { + // Druid doesn't use type-specific paths, just /spec/configuration/configSecret/name + const path = type + ? `/spec/configuration/${type}/configSecret/name` + : `/spec/configuration/configSecret/name` + // watchDependency(`model#${path}`) + 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' + } + + /** + * Convert a JavaScript object to YAML format string + * @param {Object|Array|*} obj - Object to convert + * @param {Number} indent - Current indentation level + * @returns {String} YAML formatted string + */ + 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}:` - // computed called when tls fields is not visible - if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined + if (value === null || value === undefined) { + return `${keyLine} null` + } - // direct model update required for reusable element. - // computed property is not applicable for reusable element + 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') + } + + /** + * Set the selected config secret name in the model + * @param {Object} params - Function parameters + * @param {String} value - Secret name to set + * @param {String} type - Node type (e.g., 'brokers', 'historicals') + */ + function setSelectedConfigSecret(value, type) { + const path = `/spec/configuration/${type}/configSecret/name` commit('wizard/model$update', { - path: commitPath, - value: retValue, + path: path, + value: value, force: true, }) } - return retValue || undefined -} + /** + * Alternative function to get config secret data (MongoDB pattern) + * Similar to getSelectedConfigSecretValue but with different naming + * @param {Object} params - Function parameters + * @param {String} type - Node type + * @returns {String} YAML formatted secret data + */ + function getSelectedConfigSecretData(type) { + const path = `/spec/configuration/${type}/configSecret/name` + // watchDependency(`model#${path}`) + 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 setResource({ discriminator, getValue, watchDependency }, path) { - watchDependency('discriminator#/dbDetails') - const containers = getValue(discriminator, `/dbDetails${path}`) || [] - const kind = getValue(discriminator, '/dbDetails/kind') - const resource = containers.filter((ele) => ele.name === kind.toLowerCase()) - return resource[0]?.resources -} + // ============================================================ + // RECONFIGURATION FUNCTIONS + // ============================================================ + + function ifReconfigurationTypeEqualsTo(value, property) { + let path = '/reconfigurationType' + if (property) path += `-${property}` + const reconfigurationType = getValue(discriminator, path) + const watchPath = `discriminator#${path}` + // watchDependency(watchPath) + return reconfigurationType === value + } -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} + function onReconfigurationTypeChange(property) { + setDiscriminatorValue(`/${property}/applyConfig`, []) + let path = '/reconfigurationType' + if (property) path += `-${property}` + const reconfigurationType = getValue(discriminator, path) + + if (reconfigurationType === 'remove') { + commit('wizard/model$delete', `/spec/configuration/${property}`) + commit('wizard/model$update', { + path: `/spec/configuration/${property}/removeCustomConfig`, + value: true, + force: true, + }) + } else { + commit('wizard/model$delete', `/spec/configuration/${property}/configSecret`) + commit('wizard/model$delete', `/spec/configuration/${property}/applyConfig`) + commit('wizard/model$delete', `/spec/configuration/${property}/removeCustomConfig`) + } + } -function isNamespaceDisabled({ route }) { - const { namespace } = route.query || {} - return !!namespace -} + // ============================================================ + // TLS FUNCTIONS + // ============================================================ -function isDatabaseRefDisabled({ route }) { - const { name } = route.params || {} - return !!name -} + function getDbTls() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') + const { spec } = dbDetails || {} + return spec?.tls || undefined + } -function onNamespaceChange({ commit }) { - commit('wizard/model$delete', '/spec/type') -} + function hasTlsField() { + const tls = getDbTls() + return !!tls + } -function onDbChange({ commit, axios, storeGet, model, getValue, setDiscriminatorValue }) { - commit('wizard/model$delete', '/spec/type') - getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) -} + function setApiGroup() { + return commit('wizard/model$update', { + path: '/spec/tls/issuerRef/apiGroup', + value: 'cert-manager.io', + force: true, + }) + } -function setApplyToIfReady() { - return 'IfReady' -} + function onSetAliasChange() { + const alias = itemCtx.alias + if (alias) { + commit('wizard/model$update', { + path: '/alias', + value: alias, + force: true, + }) + } + } -function isVerticalScaleTopologyRequired({ watchDependency, getValue, discriminator, commit }) { - watchDependency('discriminator#/topologyKey') - watchDependency('discriminator#/topologyValue') + function getAliasOptions() { + return ['server', 'client', 'metrics-exporter'] + } - const key = getValue(discriminator, '/topologyKey') - const value = getValue(discriminator, '/topologyValue') - const path = `/spec/verticalScaling/druid/topology` + function showIssuerRefAndCertificates() { + // watchDependency('discriminator#/tlsOperation') + const tlsOperation = getValue(discriminator, '/tlsOperation') + const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' + return verd + } - if (key || value) { - commit('wizard/model$update', { - path: path, - value: { key, value }, - force: true, + function onIssuerRefChange() { + setApiGroup() + } + + function hasIssuerRefName() { + // watchDependency('model#/spec/tls/issuerRef/name') + const name = getValue(model, '/spec/tls/issuerRef/name') + return !!name + } + + function hasNoIssuerRefName() { + // watchDependency('model#/spec/tls/issuerRef/name') + const name = getValue(model, '/spec/tls/issuerRef/name') + return !name + } + + function showTlsConfigureSection() { + // watchDependency('discriminator#/tlsOperation') + const tlsOperation = getValue(discriminator, '/tlsOperation') + return tlsOperation === 'update' + } + + function initIssuerRefApiGroup() { + const kind = getValue(model, '/spec/tls/issuerRef/kind') + // watchDependency('model#/spec/tls/issuerRef/kind') + if (kind) { + 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, + }) + } else if (tlsOperation === 'remove') { + commit('wizard/model$update', { + path: '/spec/tls/remove', + value: true, + force: true, + }) + } + } + + function isIssuerRefRequired() { + const hasTls = hasTlsField() + return hasTls ? false : '' + } + + function fetchAliasOptions() { + return getAliasOptions ? getAliasOptions() : [] + } + + function validateNewCertificates() { + 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) + } + + // ============================================================ + // HELPER FUNCTIONS + // ============================================================ + + // ============================================================ + // RESOURCE MANAGEMENT FUNCTIONS + // ============================================================ + + function isToggleOn(path) { + // watchDependency(`discriminator#${path}`) + const val = getValue(discriminator, path) + return !!val + } + + async function getResources(group, version, resource) { + const namespace = getValue(model, '/metadata/namespace') + + let resources = await getNamespacedResourceList({ + namespace, + group, + version, + resource, }) - return true - } else { - commit('wizard/model$delete', path) + + 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 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, + } + }) + } + + function unsets(path) { + const val = getValue(discriminator, path) + if (val) { + commit('wizard/model$delete', path) + } + } + + function setApplyToIfReady() { + return 'IfReady' + } + + function isEqualToValueFromType(value) { + // watchDependency('discriminator#/valueFromType') + const valueFrom = getValue(discriminator, '/valueFromType') + return valueFrom === value + } + + function disableOpsRequest() { return false } -} -function checkVolume({ model, discriminator, getValue }, initpath, path) { - const volume = getValue(discriminator, `/dbDetails${initpath}`) - const input = getValue(model, path) + // ============================================================ + // ADDITIONAL HELPER FUNCTIONS (from MongoDB patterns) + // ============================================================ + + /** + * Utility function to safely get nested values from objects + * @param {Object} obj - The object to traverse + * @param {String} path - Dot notation path (e.g., 'spec.topology.brokers') + * @param {*} defaultValue - Default value if path not found + * @returns {*} The value at the path or default value + */ + function getNestedValue(obj, path, defaultValue = undefined) { + if (!obj || !path) return defaultValue + const keys = path.split('.') + let result = obj + for (const key of keys) { + if (result === null || result === undefined) return defaultValue + result = result[key] + } + return result !== undefined ? result : defaultValue + } - try { - const sizeInBytes = parseSize(volume) - const inputSizeInBytes = parseSize(input) + /** + * Check if the current database has specific topology configuration + * @param {String} topologyType - The topology type to check + * @returns {Boolean} Whether the topology exists + */ + function hasTopologyType(topologyType) { + const dbDetails = getValue(discriminator, '/dbDetails') + return !!dbDetails?.spec?.topology?.[topologyType] + } - if (inputSizeInBytes >= sizeInBytes) return true - else return 'Cannot expand to lower volume!' - } catch (err) { - return err.message || 'Invalid' + /** + * Get resource limits or requests from database details + * @param {String} type - Node type (e.g., 'brokers', 'historicals') + * @param {String} resourceType - 'limits' or 'requests' + * @returns {Object} Resource configuration + */ + function getResourceConfig(type, resourceType = 'requests') { + const dbDetails = getValue(discriminator, '/dbDetails') + if (type === 'node' || !type) { + return ( + dbDetails?.spec?.podTemplate?.spec?.resources?.[resourceType] || { cpu: '', memory: '' } + ) + } else { + return ( + dbDetails?.spec?.topology?.[type]?.podTemplate?.spec?.resources?.[resourceType] || { + cpu: '', + memory: '', + } + ) + } } -} -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 setExporter(type) { + let path = `/dbDetails/spec/monitor/prometheus/exporter/resources/limits/${type}` + const limitVal = getValue(discriminator, path) -return { - isRancherManaged, - setResource, - fetchJsons, - returnFalse, - getNamespaces, - getDbs, - getDbDetails, - getDbVersions, - ifRequestTypeEqualsTo, - onRequestTypeChange, - getDbTls, - getDbType, - initNamespace, - initDatabaseRef, - - showAndInitName, - showAndInitNamespace, - showAndInitDatabaseRef, - showConfigureOpsrequestLabel, - showAndInitOpsRequestType, - - ifDbTypeEqualsTo, - getConfigSecrets, - createSecretUrl, - isEqualToValueFromType, - disableOpsRequest, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - ifReconfigurationTypeEqualsTo, - onReconfigurationTypeChange, - onApplyconfigChange, - hasTlsField, - initIssuerRefApiGroup, - getIssuerRefsName, - initTlsOperation, - onTlsOperationChange, - showIssuerRefAndCertificates, - isIssuerRefRequired, - getRequestTypeFromRoute, - isDbDetailsLoading, - setValueFromDbDetails, - getAliasOptions, - isNamespaceDisabled, - isDatabaseRefDisabled, - onNamespaceChange, - onDbChange, - setApplyToIfReady, - isVerticalScaleTopologyRequired, - getMachines, - setMachine, - onMachineChange, - isMachineCustom, - checkVolume, + 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, + }) + } + + // ============================================================ + // RETURN ALL EXPORTED FUNCTIONS + // ============================================================ + + return { + // Core utility functions + fetchJsons, + returnFalse, + isEqualToModelPathValue, + isRancherManaged, + + // Namespace & database resource functions + getNamespaces, + getDbs, + getDbDetails, + getDbVersions, + initNamespace, + initDatabaseRef, + onNamespaceChange, + onDbChange, + + // OpsRequest type functions + getRequestTypeFromRoute, + onRequestTypeChange, + ifRequestTypeEqualsTo, + showAndInitName, + showAndInitNamespace, + showAndInitDatabaseRef, + showAndInitOpsRequestType, + showConfigureOpsrequestLabel, + isNamespaceDisabled, + isDatabaseRefDisabled, + isDbDetailsLoading, + + // Database type functions + getDbType, + getDbTls, + ifDbTypeEqualsTo, + clearOpsReqSpec, + disableOpsRequest, + + // Machine profile functions + getMachines, + setMachine, + onMachineChange, + isMachineCustom, + setValueFromDbDetails, + + // Vertical scaling functions + isVerticalScaleTopologyRequired, + setExporter, + onExporterResourceChange, + + // Volume expansion functions + checkVolume, + parseSize, + + // Configuration functions + getConfigSecrets, + createSecretUrl, + getSelectedConfigSecret, + getSelectedConfigSecretValue, + getSelectedConfigSecretData, + setSelectedConfigSecret, + onApplyconfigChange, + fetchConfigSecrets, + getConfigSecretsforAppyConfig, + getSelectedConfigurationData, + getSelectedConfigurationName, + getSelectedConfigurationValueForRemove, + createNewConfigSecret, + decodeError, + isCreateSecret, + isNotCreateSecret, + onCreateSecretChange, + cancelCreateSecret, + setApplyConfig, + onRemoveConfigChange, + onNewConfigSecretChange, + onSelectedSecretChange, + + // Reconfiguration functions + ifReconfigurationTypeEqualsTo, + onReconfigurationTypeChange, + + // TLS functions + hasTlsField, + setApiGroup, + onSetAliasChange, + getAliasOptions, + showIssuerRefAndCertificates, + onIssuerRefChange, + hasIssuerRefName, + hasNoIssuerRefName, + showTlsConfigureSection, + initIssuerRefApiGroup, + getIssuerRefsName, + initTlsOperation, + onTlsOperationChange, + isIssuerRefRequired, + fetchAliasOptions, + validateNewCertificates, + disableAlias, + + // Helper functions + isToggleOn, + getResources, + resourceNames, + unNamespacedResourceNames, + getNamespacedResourceList, + getResourceList, + unsets, + setApplyToIfReady, + isEqualToValueFromType, + objectToYaml, + + // Additional helper functions + getNestedValue, + hasTopologyType, + getResourceConfig, + isTlsEnabled, + } } diff --git a/charts/opskubedbcom-elasticsearchopsrequest-editor/ui/create-ui.yaml b/charts/opskubedbcom-elasticsearchopsrequest-editor/ui/create-ui.yaml index bed458f422..07fdda0d9d 100644 --- a/charts/opskubedbcom-elasticsearchopsrequest-editor/ui/create-ui.yaml +++ b/charts/opskubedbcom-elasticsearchopsrequest-editor/ui/create-ui.yaml @@ -1,1203 +1,1496 @@ -steps: -- form: - discriminator: - dbDetails: - type: object +type: multi-step-form +step: + - type: single-step-form + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - schema: - $ref: discriminator#/properties/dbDetails - type: input - - if: showAndInitName - label: - text: labels.op_req_name - required: true - schema: - $ref: schema#/properties/metadata/properties/name - type: input - - computed: initNamespace - disabled: isNamespaceDisabled - fetch: getNamespaces - hasGroup: isRancherManaged - if: showAndInitNamespace - label: - text: labels.namespace - onChange: onNamespaceChange - required: true - schema: - $ref: schema#/properties/metadata/properties/namespace - type: select - - computed: initDatabaseRef - disabled: isDatabaseRefDisabled - fetch: getDbs - if: showAndInitDatabaseRef - label: - text: labels.databaseRef - onChange: onDbChange - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/databaseRef/properties/name - type: select - - if: showConfigureOpsrequestLabel - label: - text: labels.config_ops_request - type: label-element - - disabled: isDbDetailsLoading - hasDescription: true - if: showAndInitOpsRequestType - individualItemDisabilityCheck: disableOpsRequest - label: - text: labels.ops_request_type - onChange: onRequestTypeChange - options: - - description: options.UpdateVersion.description - text: options.UpdateVersion.text - value: UpdateVersion - - description: options.HorizontalScaling.description - text: options.HorizontalScaling.text - value: HorizontalScaling - - description: options.VerticalScaling.description - text: options.VerticalScaling.text - value: VerticalScaling - - description: options.VolumeExpansion.description - text: options.VolumeExpansion.text - value: VolumeExpansion - - description: options.Restart.description - text: options.Restart.text - value: Restart - - description: options.ReconfigureTLS.description - text: options.ReconfigureTLS.text - value: ReconfigureTLS - schema: - $ref: schema#/properties/spec/properties/type - type: radio - - elements: - - computed: setValueFromDbDetails|/spec/version - fetch: getDbVersions - label: - text: labels.targetVersion - schema: - $ref: schema#/properties/spec/properties/updateVersion/properties/targetVersion - type: select - if: ifRequestTypeEqualsTo|UpdateVersion - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/replicas - if: ifDbTypeEqualsTo|combined|horizontalScaling - label: - text: labels.replicas - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/node - type: input - - elements: - - computed: setValueFromDbDetails|/spec/topology/master/replicas - label: - text: labels.master_node - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/topology/properties/master - type: input - - computed: setValueFromDbDetails|/spec/topology/data/replicas - label: - text: labels.data_node - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/topology/properties/data - type: input - - computed: setValueFromDbDetails|/spec/topology/ingest/replicas - label: - text: labels.ingest_node - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/topology/properties/ingest - type: input - - computed: setValueFromDbDetails|/spec/topology/ml/replicas - if: isAuthPluginEqualTo|X-Pack - label: - text: labels.ml_node - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/topology/properties/ml - type: input - - computed: setValueFromDbDetails|/spec/topology/transform/replicas - if: isAuthPluginEqualTo|X-Pack - label: - text: labels.transform_node - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/topology/properties/transform - type: input - - computed: setValueFromDbDetails|/spec/topology/dataCold/replicas - if: isAuthPluginEqualTo|X-Pack - label: - text: labels.data_cold_node - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/topology/properties/dataCold - type: input - - computed: setValueFromDbDetails|/spec/topology/dataContent/replicas - if: isAuthPluginEqualTo|X-Pack - label: - text: labels.data_content_node - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/topology/properties/dataContent - type: input - - computed: setValueFromDbDetails|/spec/topology/dataFrozen/replicas - if: isAuthPluginEqualTo|X-Pack - label: - text: labels.data_frozen_node - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/topology/properties/dataFrozen - type: input - - computed: setValueFromDbDetails|/spec/topology/dataHot/replicas - if: isAuthPluginNotEqualTo|SearchGuard - label: - text: labels.data_hot_node - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/topology/properties/dataHot - type: input - - computed: setValueFromDbDetails|/spec/topology/dataWarm/replicas - if: isAuthPluginNotEqualTo|SearchGuard - label: - text: labels.data_warm_node - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/topology/properties/dataWarm - type: input - if: ifDbTypeEqualsTo|topology|horizontalScaling - label: - text: labels.replicas - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/topology - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|HorizontalScaling - label: - text: Horizontal Scaling Form - type: single-step-form - - elements: - - elements: - - discriminator: - machine-master: - default: "" - type: string - elements: - - computed: setMachine|master - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|master|/spec/topology/master/resources - schema: - $ref: discriminator#/machine-master - type: select - - if: isMachineCustom|/machine-master - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/master/properties/resources - type: resource-input-form - - label: - text: labels.node_selection_policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/master/properties/nodeSelectionPolicy - type: select - - discriminator: - topologyKey-master: - default: "" - type: string - topologyValue-master: - default: "" - type: string +# common + - type: input + label: op_req_name + if: + type: function + name: showAndInitName + validation: + type: required + schema: schema/properties/metadata/properties/name + - type: select + label: Namespace + if: + type: function + name: showAndInitNamespace + init: + type: func + value: initNamespace + disable: isNamespaceDisabled + loader: getNamespaces + validation: + type: required + hasGroup: isRancherManaged + schema: schema/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/metadata/properties/namespace + - type: select + label: Database Ref + if: + type: function + name: showAndInitDatabaseRef + loader: + name: getDbs + watchPaths: + - schema/properties/metadata/properties/namespace + init: + type: func + value: initDatabaseRef + validation: + type: required + disable: isDatabaseRefDisabled + refresh: true + watcher: + paths: + - schema/properties/spec/properties/databaseRef/properties/name + func: onDbChange + schema: schema/properties/spec/properties/databaseRef/properties/name + - type: label-element + label: config_ops_request + if: + type: function + name: showConfigureOpsrequestLabel + - type: radio + label: Type of Ops Request + if: + type: function + name: showAndInitOpsRequestType + 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 tls configuration + text: Reconfigure TLS + value: ReconfigureTLS + init: + type: func + value: getRequestTypeFromRoute + disable: isDbDetailsLoading + watcher: + func: onRequestTypeChange + paths: + - schema/properties/spec/properties/type + isHorizontal: true + schema: schema/properties/spec/properties/type +# UpdateVersion + - type: block-layout + showLabels: true + label: Version + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|UpdateVersion + elements: + - type: select-compare + label: Target Version + subtitle: Select the desired Elasticsearch version to which you want to update your database. + init: + type: func + value: setValueFromDbDetails|/spec/version + loader: getDbVersions + schema: schema/properties/spec/properties/updateVersion/properties/targetVersion + - type: info + label: '' + loader: + name: getVersionInfo + watchPaths: + - temp/properties/filteredVersion + if: + type: function + name: isVersionEmpty +# Horizontal Scale + - type: block-layout + label: Horizontal Scaling Form + showLabels: true + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|HorizontalScaling + elements: + - type: horizontal-layout elements: - - label: - text: labels.key - required: isVerticalScaleTopologyRequired|master - schema: - $ref: discriminator#/topologyKey-master - type: input - - label: - text: labels.value - required: isVerticalScaleTopologyRequired|master - schema: - $ref: discriminator#/topologyValue-master - type: input - label: - text: labels.topology - show_label: true - type: single-step-form - if: hasResourceValue|master - label: - text: labels.master_node - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/master - show_label: true - type: single-step-form - - discriminator: - machine-data: - default: "" - type: string - elements: - - computed: setMachine|data - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|data|/spec/topology/data/resources - schema: - $ref: discriminator#/machine-data - type: select - - if: isMachineCustom|/machine-data - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/data/properties/resources - type: resource-input-form - - label: - text: labels.node_selection_policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/data/properties/nodeSelectionPolicy - type: select - - discriminator: - topologyKey-data: - default: "" - type: string - topologyValue-data: - default: "" - type: string + - type: input-compare + label: Replicas + header: Replicas + subtitle: Define the total number of replicas for the database. Increasing replicas improves fault tolerance and load distribution, while reducing replicas conserves resources + if: + type: function + name: ifDbTypeEqualsTo|Combined|horizontalScaling + init: + type: func + value: setValueFromDbDetails|/spec/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/node + - type: info + hasIcon: true + label: Each replica represents an independent copy of your database node. For example, setting this to 3 creates three copies of the database for better availability. + if: + type: function + name: ifDbTypeEqualsTo|Combined|horizontalScaling + - type: block-layout + label: Topology horizontal scaling + if: + type: function + name: ifDbTypeEqualsTo|Topology|horizontalScaling elements: - - label: - text: labels.key - required: isVerticalScaleTopologyRequired|data - schema: - $ref: discriminator#/topologyKey-data - type: input - - label: - text: labels.value - required: isVerticalScaleTopologyRequired|data - schema: - $ref: discriminator#/topologyValue-data - type: input - label: - text: labels.topology - show_label: true - type: single-step-form - if: hasResourceValue|data - label: - text: labels.data_node - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/data - show_label: true - type: single-step-form - - discriminator: - machine-ingest: - default: "" - type: string - elements: - - computed: setMachine|ingest - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|ingest|/spec/topology/ingest/resources - schema: - $ref: discriminator#/machine-ingest - type: select - - if: isMachineCustom|/machine-ingest - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/ingest/properties/resources - type: resource-input-form - - label: - text: labels.node_selection_policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/ingest/properties/nodeSelectionPolicy - type: select - - discriminator: - topologyKey-ingest: - default: "" - type: string - topologyValue-ingest: - default: "" - type: string + - type: block-layout + label: Master Node horizontal Scaling + elements: + - type: horizontal-layout + elements: + - type: input-compare + label: Master Node + header: Master Replicas + subtitle: Define the total number of master node replicas. Increasing replicas improves fault tolerance and load distribution, while reducing replicas conserves resources + init: + type: func + value: setValueFromDbDetails|/spec/topology/master/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/topology/properties/master + - type: info + hasIcon: true + label: Master nodes are responsible for cluster management operations. It's recommended to have an odd number of master nodes (e.g., 3, 5) for proper quorum. + - type: block-layout + label: Data Node horizontal Scaling + elements: + - type: horizontal-layout + elements: + - type: input-compare + label: Data Node + header: Data Replicas + subtitle: Define the total number of data node replicas. Increasing replicas improves fault tolerance and load distribution, while reducing replicas conserves resources + init: + type: func + value: setValueFromDbDetails|/spec/topology/data/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/topology/properties/data + - type: info + hasIcon: true + label: Data nodes store the actual documents and handle data-related operations like search and aggregation. More data nodes provide better storage capacity and query performance. + - type: block-layout + label: Ingest Node horizontal Scaling + elements: + - type: horizontal-layout + elements: + - type: input-compare + label: Ingest Node + header: Ingest Replicas + subtitle: Define the total number of ingest node replicas. Increasing replicas improves fault tolerance and load distribution, while reducing replicas conserves resources + init: + type: func + value: setValueFromDbDetails|/spec/topology/ingest/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/topology/properties/ingest + - type: info + hasIcon: true + label: Ingest nodes pre-process documents before they are indexed. They can apply transformations and enrichments to your data pipeline. +# vertical Scale + - type: block-layout + if: + type: function + name: ifRequestTypeEqualsTo|VerticalScaling + elements: + - type: block-layout + label: Node + showLabels: true + if: + type: function + name: ifDbTypeEqualsTo|Combined|verticalScaling elements: - - label: - text: labels.key - required: isVerticalScaleTopologyRequired|ingest - schema: - $ref: discriminator#/topologyKey-ingest - type: input - - label: - text: labels.value - required: isVerticalScaleTopologyRequired|ingest - schema: - $ref: discriminator#/topologyValue-ingest - type: input - label: - text: labels.topology - show_label: true - type: single-step-form - if: hasResourceValue|ingest - label: - text: labels.ingest_node - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/ingest - show_label: true - type: single-step-form - - discriminator: - machine-ml: - default: "" - type: string - elements: - - computed: setMachine|ml - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|ml|/spec/topology/ml/resources - schema: - $ref: discriminator#/machine-ml - type: select - - if: isMachineCustom|/machine-ml - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/ml/properties/resources - type: resource-input-form - - label: - text: labels.node_selection_policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/ml/properties/nodeSelectionPolicy - type: select - - discriminator: - topologyKey-ml: - default: "" - type: string - topologyValue-ml: - default: "" - type: string + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed resource adjustments and make informed decisions for your database setup + loader: getMachines|node + init: + type: func + value: setMachine|node + watcher: + func: onMachineChange|node|/spec/podTemplate/spec/resources + paths: + - temp/properties/machine-node + schema: temp/properties/machine-node + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/node/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|node + schema: temp/topologyKey-node + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|node + schema: temp/topologyValue-node + - type: block-layout + if: + type: function + name: ifDbTypeEqualsTo|Topology|verticalScaling elements: - - label: - text: labels.key - required: isVerticalScaleTopologyRequired|ml - schema: - $ref: discriminator#/topologyKey-ml - type: input - - label: - text: labels.value - required: isVerticalScaleTopologyRequired|ml - schema: - $ref: discriminator#/topologyValue-ml - type: input - label: - text: labels.topology - show_label: true - type: single-step-form - if: hasResourceValue|ml - label: - text: labels.ml_mode - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/ml - show_label: true - type: single-step-form - - discriminator: - machine-transform: - default: "" - type: string - elements: - - computed: setMachine|transform - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|transform|/spec/topology/transform/resources - schema: - $ref: discriminator#/machine-transform - type: select - - if: isMachineCustom|/machine-transform - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/transform/properties/resources - type: resource-input-form - - label: - text: labels.node_selection_policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/transform/properties/nodeSelectionPolicy - type: select - - discriminator: - topologyKey-transform: - default: "" - type: string - topologyValue-transform: - default: "" - type: string + - type: block-layout + label: Master Node + showLabels: true + if: + type: function + name: hasResourceValue|master + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed resource adjustments and make informed decisions for your database setup + loader: getMachines|master + init: + type: func + value: setMachine|master + watcher: + func: onMachineChange|master|/spec/topology/master/resources + paths: + - temp/properties/machine-master + schema: temp/properties/machine-master + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/master/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|master + schema: temp/topologyKey-master + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|master + schema: temp/topologyValue-master + - type: block-layout + label: Data Node + showLabels: true + if: + type: function + name: hasResourceValue|data + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed resource adjustments and make informed decisions for your database setup + loader: getMachines|data + init: + type: func + value: setMachine|data + watcher: + func: onMachineChange|data|/spec/topology/data/resources + paths: + - temp/properties/machine-data + schema: temp/properties/machine-data + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/data/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|data + schema: temp/topologyKey-data + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|data + schema: temp/topologyValue-data + - type: block-layout + label: Ingest Node + showLabels: true + if: + type: function + name: hasResourceValue|ingest + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed resource adjustments and make informed decisions for your database setup + loader: getMachines|ingest + init: + type: func + value: setMachine|ingest + watcher: + func: onMachineChange|ingest|/spec/topology/ingest/resources + paths: + - temp/properties/machine-ingest + schema: temp/properties/machine-ingest + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/ingest/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|ingest + schema: temp/topologyKey-ingest + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|ingest + schema: temp/topologyValue-ingest + - type: block-layout + label: ML Node + showLabels: true + if: + type: function + name: hasResourceValue|ml + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed resource adjustments and make informed decisions for your database setup + loader: getMachines|ml + init: + type: func + value: setMachine|ml + watcher: + func: onMachineChange|ml|/spec/topology/ml/resources + paths: + - temp/properties/machine-ml + schema: temp/properties/machine-ml + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/ml/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|ml + schema: temp/topologyKey-ml + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|ml + schema: temp/topologyValue-ml + - type: block-layout + label: Transform Node + showLabels: true + if: + type: function + name: hasResourceValue|transform + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed resource adjustments and make informed decisions for your database setup + loader: getMachines|transform + init: + type: func + value: setMachine|transform + watcher: + func: onMachineChange|transform|/spec/topology/transform/resources + paths: + - temp/properties/machine-transform + schema: temp/properties/machine-transform + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/transform/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|transform + schema: temp/topologyKey-transform + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|transform + schema: temp/topologyValue-transform + - type: block-layout + label: Data Cold Node + showLabels: true + if: + type: function + name: hasResourceValue|dataCold + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed resource adjustments and make informed decisions for your database setup + loader: getMachines|dataCold + init: + type: func + value: setMachine|dataCold + watcher: + func: onMachineChange|dataCold|/spec/topology/dataCold/resources + paths: + - temp/properties/machine-dataCold + schema: temp/properties/machine-dataCold + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/dataCold/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|dataCold + schema: temp/topologyKey-dataCold + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|dataCold + schema: temp/topologyValue-dataCold + - type: block-layout + label: Data Content Node + showLabels: true + if: + type: function + name: hasResourceValue|dataContent + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed resource adjustments and make informed decisions for your database setup + loader: getMachines|dataContent + init: + type: func + value: setMachine|dataContent + watcher: + func: onMachineChange|dataContent|/spec/topology/dataContent/resources + paths: + - temp/properties/machine-dataContent + schema: temp/properties/machine-dataContent + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/dataContent/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|dataContent + schema: temp/topologyKey-dataContent + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|dataContent + schema: temp/topologyValue-dataContent + - type: block-layout + label: Data Frozen Node + showLabels: true + if: + type: function + name: hasResourceValue|dataFrozen + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed resource adjustments and make informed decisions for your database setup + loader: getMachines|dataFrozen + init: + type: func + value: setMachine|dataFrozen + watcher: + func: onMachineChange|dataFrozen|/spec/topology/dataFrozen/resources + paths: + - temp/properties/machine-dataFrozen + schema: temp/properties/machine-dataFrozen + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/dataFrozen/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|dataFrozen + schema: temp/topologyKey-dataFrozen + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|dataFrozen + schema: temp/topologyValue-dataFrozen + - type: block-layout + label: Data Hot Node + showLabels: true + if: + type: function + name: hasResourceValue|dataHot + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed resource adjustments and make informed decisions for your database setup + loader: getMachines|dataHot + init: + type: func + value: setMachine|dataHot + watcher: + func: onMachineChange|dataHot|/spec/topology/dataHot/resources + paths: + - temp/properties/machine-dataHot + schema: temp/properties/machine-dataHot + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/dataHot/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|dataHot + schema: temp/topologyKey-dataHot + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|dataHot + schema: temp/topologyValue-dataHot + - type: block-layout + label: Data Warm Node + showLabels: true + if: + type: function + name: hasResourceValue|dataWarm + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed resource adjustments and make informed decisions for your database setup + loader: getMachines|dataWarm + init: + type: func + value: setMachine|dataWarm + watcher: + func: onMachineChange|dataWarm|/spec/topology/dataWarm/resources + paths: + - temp/properties/machine-dataWarm + schema: temp/properties/machine-dataWarm + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/dataWarm/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|dataWarm + schema: temp/topologyKey-dataWarm + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|dataWarm + schema: temp/topologyValue-dataWarm + - type: block-layout + label: Exporter + showLabels: true + hideBlock: true elements: - - label: - text: labels.key - required: isVerticalScaleTopologyRequired|transform - schema: - $ref: discriminator#/topologyKey-transform - type: input - - label: - text: labels.value - required: isVerticalScaleTopologyRequired|transform - schema: - $ref: discriminator#/topologyValue-transform - type: input - label: - text: labels.topology - show_label: true - type: single-step-form - if: hasResourceValue|transform - label: - text: labels.transform_node - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/transform - show_label: true - type: single-step-form - - discriminator: - machine-dataCold: - default: "" - type: string - elements: - - computed: setMachine|dataCold - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|dataCold|/spec/topology/dataCold/resources - schema: - $ref: discriminator#/machine-dataCold - type: select - - if: isMachineCustom|/machine-dataCold - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/dataCold/properties/resources - type: resource-input-form - - label: - text: labels.node_selection_policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/dataCold/properties/nodeSelectionPolicy - type: select - - discriminator: - topologyKey-dataCold: - default: "" - type: string - topologyValue-dataCold: - default: "" - type: string + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setExporter|cpu + type: input + 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 + watcher: + func: onExporterResourceChange|memory + paths: + - schema/properties/spec/properties/verticalScaling/properties/exporter/properties/resources/properties/limits/properties/memory +# Volume Expansion + + - type: block-layout + label: Volume Expansion Form + if: + type: function + name: ifRequestTypeEqualsTo|VolumeExpansion + elements: + - type: horizontal-layout elements: - - label: - text: labels.key - required: isVerticalScaleTopologyRequired|dataCold - schema: - $ref: discriminator#/topologyKey-dataCold - type: input - - label: - text: labels.value - required: isVerticalScaleTopologyRequired|dataCold - schema: - $ref: discriminator#/topologyValue-dataCold - type: input - label: - text: labels.topology - show_label: true - type: single-step-form - if: hasResourceValue|dataCold - label: - text: labels.data_cold_node - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/dataCold - show_label: true - type: single-step-form - - discriminator: - machine-dataContent: - default: "" - type: string - elements: - - computed: setMachine|dataContent - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|dataContent|/spec/topology/dataContent/resources - schema: - $ref: discriminator#/machine-dataContent - type: select - - if: isMachineCustom|/machine-dataContent - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/dataContent/properties/resources - type: resource-input-form - - label: - text: labels.node_selection_policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/dataContent/properties/nodeSelectionPolicy - type: select - - discriminator: - topologyKey-dataContent: - default: "" - type: string - topologyValue-dataContent: - default: "" - type: string + - type: block-layout + elements: + - type: label-element + 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: select + label: Mode + options: + - text: Offline + value: Offline + - text: Online + value: Online + validation: + type: required + schema: schema/properties/spec/properties/volumeExpansion/properties/mode + - type: block-layout + label: Combined volume expansion + showLabels: true + fixedBlock: true + if: + type: function + name: ifDbTypeEqualsTo|Combined|VolumeExpansion elements: - - label: - text: labels.key - required: isVerticalScaleTopologyRequired|dataContent - schema: - $ref: discriminator#/topologyKey-dataContent - type: input - - label: - text: labels.value - required: isVerticalScaleTopologyRequired|dataContent - schema: - $ref: discriminator#/topologyValue-dataContent - type: input - label: - text: labels.topology - show_label: true - type: single-step-form - if: hasResourceValue|dataContent - label: - text: labels.data_content_node - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/dataCold - show_label: true - type: single-step-form - - discriminator: - machine-dataFrozen: - default: "" - type: string - elements: - - computed: setMachine|dataFrozen - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|dataFrozen|/spec/topology/dataFrozen/resources - schema: - $ref: discriminator#/machine-dataFrozen - type: select - - if: isMachineCustom|/machine-dataFrozen - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/dataFrozen/properties/resources - type: resource-input-form - - label: - text: labels.node_selection_policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/dataFrozen/properties/nodeSelectionPolicy - type: select - - discriminator: - topologyKey-dataFrozen: - default: "" - type: string - topologyValue-dataFrozen: - default: "" - type: string + - type: horizontal-layout + elements: + - type: input-compare + header: Node + subtitle: How much extra storage does your database need? Specify the size (e.g., 2Gi for 2 gigabytes) so we can allocate it correctly + label: Storage Size + init: + type: func + value: setValueFromDbDetails|/spec/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/node + schema: schema/properties/spec/properties/volumeExpansion/properties/node + - type: info + hasIcon: true + label: Volume expansion increases the storage capacity of your database. Ensure your storage class supports volume expansion before proceeding. + - type: block-layout + label: Topology volume expansion + showLabels: true + fixedBlock: true + if: + type: function + name: ifDbTypeEqualsTo|Topology|VolumeExpansion elements: - - label: - text: labels.key - required: isVerticalScaleTopologyRequired|dataFrozen - schema: - $ref: discriminator#/topologyKey-dataFrozen - type: input - - label: - text: labels.value - required: isVerticalScaleTopologyRequired|dataFrozen - schema: - $ref: discriminator#/topologyValue-dataFrozen - type: input - label: - text: labels.topology - show_label: true - type: single-step-form - if: hasResourceValue|dataFrozen - label: - text: labels.data_frozen_node - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/dataFrozen - show_label: true - type: single-step-form - - discriminator: - machine-dataHot: - default: "" - type: string - elements: - - computed: setMachine|dataHot - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|dataHot|/spec/topology/dataHot/resources - schema: - $ref: discriminator#/machine-dataHot - type: select - - if: isMachineCustom|/machine-dataHot - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/dataHot/properties/resources - type: resource-input-form - - label: - text: labels.node_selection_policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/dataHot/properties/nodeSelectionPolicy - type: select - - discriminator: - topologyKey-dataHot: - default: "" - type: string - topologyValue-dataHot: - default: "" - type: string + - type: horizontal-layout + if: + type: function + name: hasVolumeExpansion|master + elements: + - type: input-compare + header: Master + label: Master Size + subtitle: How much extra storage does your master nodes need? Specify the size (e.g., 2Gi for 2 gigabytes) so we can allocate it correctly + init: + type: func + value: setValueFromDbDetails|/spec/topology/master/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/topology/master/storage/resources/requests/storage|/spec/volumeExpansion/master + schema: schema/properties/spec/properties/volumeExpansion/properties/master + - type: info + hasIcon: true + label: Master nodes store cluster metadata and configuration. Proper storage allocation ensures reliable cluster management operations. + - type: horizontal-layout + if: + type: function + name: hasVolumeExpansion|data + elements: + - type: input-compare + header: Data + label: Data Size + subtitle: How much extra storage does your data nodes need? Specify the size (e.g., 2Gi for 2 gigabytes) so we can allocate it correctly + init: + type: func + value: setValueFromDbDetails|/spec/topology/data/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/topology/data/storage/resources/requests/storage|/spec/volumeExpansion/data + schema: schema/properties/spec/properties/volumeExpansion/properties/data + - type: info + hasIcon: true + label: Data nodes store your actual documents and indices. Adequate storage ensures smooth data operations and prevents disk space issues. + - type: horizontal-layout + if: + type: function + name: hasVolumeExpansion|ingest + elements: + - type: input-compare + header: Ingest + label: Ingest Size + subtitle: How much extra storage does your ingest nodes need? Specify the size (e.g., 2Gi for 2 gigabytes) so we can allocate it correctly + init: + type: func + value: setValueFromDbDetails|/spec/topology/ingest/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/topology/ingest/storage/resources/requests/storage|/spec/volumeExpansion/ingest + schema: schema/properties/spec/properties/volumeExpansion/properties/ingest + - type: info + hasIcon: true + label: Ingest nodes handle data pre-processing tasks. Sufficient storage ensures smooth pipeline operations. + - type: horizontal-layout + if: + type: function + name: hasVolumeExpansion|ml + elements: + - type: input-compare + header: ML + label: ML Size + subtitle: How much extra storage does your ML nodes need? Specify the size (e.g., 2Gi for 2 gigabytes) so we can allocate it correctly + init: + type: func + value: setValueFromDbDetails|/spec/topology/ml/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/topology/ml/storage/resources/requests/storage|/spec/volumeExpansion/ml + schema: schema/properties/spec/properties/volumeExpansion/properties/ml + - type: info + hasIcon: true + label: ML nodes store machine learning models and job data. Adequate storage supports complex ML operations. + - type: horizontal-layout + if: + type: function + name: hasVolumeExpansion|transform + elements: + - type: input-compare + header: Transform + label: Transform Size + subtitle: How much extra storage does your transform nodes need? Specify the size (e.g., 2Gi for 2 gigabytes) so we can allocate it correctly + init: + type: func + value: setValueFromDbDetails|/spec/topology/transform/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/topology/transform/storage/resources/requests/storage|/spec/volumeExpansion/transform + schema: schema/properties/spec/properties/volumeExpansion/properties/transform + - type: info + hasIcon: true + label: Transform nodes handle continuous data transformation operations. Sufficient storage ensures smooth processing. + - type: horizontal-layout + if: + type: function + name: hasVolumeExpansion|dataCold + elements: + - type: input-compare + header: Data Cold + label: Data Cold Size + subtitle: How much extra storage does your data cold nodes need? Specify the size (e.g., 2Gi for 2 gigabytes) so we can allocate it correctly + init: + type: func + value: setValueFromDbDetails|/spec/topology/dataCold/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/topology/dataCold/storage/resources/requests/storage|/spec/volumeExpansion/dataCold + schema: schema/properties/spec/properties/volumeExpansion/properties/dataCold + - type: info + hasIcon: true + label: Data cold tier stores infrequently accessed data. Cost-effective storage allocation is important for this tier. + - type: horizontal-layout + if: + type: function + name: hasVolumeExpansion|dataContent + elements: + - type: input-compare + header: Data Content + label: Data Content Size + subtitle: How much extra storage does your data content nodes need? Specify the size (e.g., 2Gi for 2 gigabytes) so we can allocate it correctly + init: + type: func + value: setValueFromDbDetails|/spec/topology/dataContent/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/topology/dataContent/storage/resources/requests/storage|/spec/volumeExpansion/dataContent + schema: schema/properties/spec/properties/volumeExpansion/properties/dataContent + - type: info + hasIcon: true + label: Data content tier stores regular content data. Proper storage allocation ensures optimal performance for standard workloads. + - type: horizontal-layout + if: + type: function + name: hasVolumeExpansion|dataFrozen + elements: + - type: input-compare + header: Data Frozen + label: Data Frozen Size + subtitle: How much extra storage does your data frozen nodes need? Specify the size (e.g., 2Gi for 2 gigabytes) so we can allocate it correctly + init: + type: func + value: setValueFromDbDetails|/spec/topology/dataFrozen/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/topology/dataFrozen/storage/resources/requests/storage|/spec/volumeExpansion/dataFrozen + schema: schema/properties/spec/properties/volumeExpansion/properties/dataFrozen + - type: info + hasIcon: true + label: Data frozen tier stores searchable snapshot data with minimal storage costs. This tier optimizes long-term data retention. + - type: horizontal-layout + if: + type: function + name: hasVolumeExpansion|dataHot + elements: + - type: input-compare + header: Data Hot + label: Data Hot Size + subtitle: How much extra storage does your data hot nodes need? Specify the size (e.g., 2Gi for 2 gigabytes) so we can allocate it correctly + init: + type: func + value: setValueFromDbDetails|/spec/topology/dataHot/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/topology/dataHot/storage/resources/requests/storage|/spec/volumeExpansion/dataHot + schema: schema/properties/spec/properties/volumeExpansion/properties/dataHot + - type: info + hasIcon: true + label: Data hot tier stores frequently accessed data requiring fast performance. Adequate storage and fast I/O are crucial for this tier. + - type: horizontal-layout + if: + type: function + name: hasVolumeExpansion|dataWarm + elements: + - type: input-compare + header: Data Warm + label: Data Warm Size + subtitle: How much extra storage does your data warm nodes need? Specify the size (e.g., 2Gi for 2 gigabytes) so we can allocate it correctly + init: + type: func + value: setValueFromDbDetails|/spec/topology/dataWarm/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/topology/dataWarm/storage/resources/requests/storage|/spec/volumeExpansion/dataWarm + schema: schema/properties/spec/properties/volumeExpansion/properties/dataWarm + - type: info + hasIcon: true + label: Data warm tier stores less frequently accessed data. Balanced storage allocation provides cost-effective performance. +# Reconfigure + - type: block-layout + label: Reconfigure Form + if: + name: ifRequestTypeEqualsTo|Reconfigure + type: function + loader: + name: fetchConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + elements: + - type: block-layout + label: Configuration elements: - - label: - text: labels.key - required: isVerticalScaleTopologyRequired|dataHot - schema: - $ref: discriminator#/topologyKey-dataHot - type: input - - label: - text: labels.value - required: isVerticalScaleTopologyRequired|dataHot - schema: - $ref: discriminator#/topologyValue-dataHot - type: input - label: - text: labels.topology - show_label: true - type: single-step-form - if: hasResourceValue|dataHot - label: - text: labels.dataHot_node - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/dataHot - show_label: true - type: single-step-form - - discriminator: - machine-dataWarm: - default: "" - type: string - elements: - - computed: setMachine|dataWarm - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|dataWarm|/spec/topology/dataWarm/resources - schema: - $ref: discriminator#/machine-dataWarm - type: select - - if: isMachineCustom|/machine-dataWarm - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/dataWarm/properties/resources - type: resource-input-form - - label: - text: labels.node_selection_policy + - type: label-element + label: '' + subtitle: Select a new configuration secret, apply a custom configuration, or remove an existing setup to update your database settings + - type: tab-layout + label: New Config Secret + schema: temp/properties/reconfigurationType + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + elements: + - type: block-layout + label: Config Secret + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret + type: function + elements: + - type: label-element + label: Config Secret + subtitle: Select a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: schema/properties/spec/properties/configuration/properties/configSecret/properties/name + refresh: true + label: Config Secret + loader: + name: getConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/createSecret/properties/status + init: + type: func + value: setValueFromDbDetails|/spec/configSecret/name + watcher: + func: onCreateSecretChange + paths: + - temp/properties/createSecret/properties/status + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|create + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + - type: block-layout + label: Create a New Config Secret + showLabels: true + if: + type: function + name: isCreateSecret + hasButton: + text: Save + hasCancel: cancelCreateSecret + action: createNewConfigSecret + elements: + - type: input + label: Secret Name + schema: temp/properties/createSecret/properties/name + validation: + type: required + - type: array-object-form + label: String Data + schema: temp/properties/createSecret/properties/data + buttonClass: is-light is-outlined + validation: + type: required + elements: + - type: select + label: Key + schema: key + loader: + name: onSelectedSecretChange + watchPaths: + - temp/properties/createSecret/properties/data + validation: + type: required + - type: textarea + label: Value + schema: value + - type: multi-file-editor + editorHeight: 500px + readonly: true + if: + type: function + name: isNotCreateSecret + loader: + name: onNewConfigSecretChange + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + schema: temp/properties/newConfigSecret + - type: block-layout + label: ApplyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig + type: function + elements: + - type: label-element + 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). + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfiguration + refresh: true + label: Configuration + loader: getConfigSecretsforAppyConfig + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|apply + watchPaths: + - temp/properties/selectedConfiguration + - type: multi-file-editor + editorHeight: 500px + schema: temp/properties/applyConfig + loader: + name: setApplyConfig + watchPaths: + - temp/properties/selectedConfiguration + watcher: + func: onApplyconfigChange + paths: + - temp/properties/applyConfig + - type: block-layout + label: Remove + if: + name: ifReconfigurationTypeEqualsTo|remove + type: function + elements: + - type: label-element + label: Remove + subtitle: Selected a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfigurationRemove + refresh: true + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|remove + watchPaths: + - temp/properties/selectedConfigurationRemove + - type: multi-file-editor + editorHeight: 500px + readonly: true + init: + type: func + value: onRemoveConfigChange + watcher: + func: onRemoveConfigChange + paths: + - temp/properties/selectedConfigurationRemove + schema: temp/properties/removeConfig +# Reconfigure TLS + - type: block-layout + label: TLS + if: + type: function + name: ifRequestTypeEqualsTo|ReconfigureTLS + elements: + - type: radio + label: TLS Operation + if: + type: function + name: hasTlsField + init: + type: func + value: initTlsOperation options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/dataWarm/properties/nodeSelectionPolicy - type: select - - discriminator: - topologyKey-dataWarm: - default: "" - type: string - topologyValue-dataWarm: - default: "" - type: string + - text: Update + value: update + - text: Rotate + value: rotate + - text: Remove + value: remove + watcher: + func: onTlsOperationChange + paths: + - temp/tlsOperation + schema: temp/tlsOperation + - type: switch + label: Remove TLS + fullwidth: true + if: + type: function + name: isTlsEnabled + schema: schema/properties/spec/properties/tls/properties/remove + - type: switch + label: Rotate Certificates + fullwidth: true + if: + type: function + name: isTlsEnabled + schema: schema/properties/spec/properties/tls/properties/rotateCertificates + - type: block-layout + label: Issuer Reference + showLabels: true + if: + type: function + name: showIssuerRefAndCertificates elements: - - label: - text: labels.key - required: isVerticalScaleTopologyRequired|dataWarm - schema: - $ref: discriminator#/topologyKey-dataWarm - type: input - - label: - text: labels.value - required: isVerticalScaleTopologyRequired|dataWarm - schema: - $ref: discriminator#/topologyValue-dataWarm - type: input - label: - text: labels.topology - show_label: true - type: single-step-form - if: hasResourceValue|dataWarm - label: - text: labels.data_warm_node - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/dataWarm - show_label: true - type: single-step-form - if: ifDbTypeEqualsTo|topology|verticalScaling - schema: - $ref: schema#/properties/spec/properties/verticalScaling - type: single-step-form - - discriminator: - machine-node: - default: "" - type: string - elements: - - computed: setMachine|node - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|node|/spec/podTemplate/spec/resources - schema: - $ref: discriminator#/machine-node - type: select - - if: isMachineCustom|/machine-node - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/resources - type: resource-input-form - - label: - text: labels.node_selection_policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/nodeSelectionPolicy - type: select - - discriminator: - topologyKey-node: - default: "" - type: string - topologyValue-node: - default: "" - type: string - elements: - - label: - text: labels.key - required: isVerticalScaleTopologyRequired|node - schema: - $ref: discriminator#/topologyKey-node - type: input - - label: - text: labels.value - required: isVerticalScaleTopologyRequired|node - schema: - $ref: discriminator#/topologyValue-node - type: input - label: - text: labels.topology - show_label: true - type: single-step-form - if: ifDbTypeEqualsTo|combined|verticalScaling - label: - text: labels.node - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node - show_label: true - type: single-step-form - - computed: setValueFromDbDetails|/spec/monitor/prometheus/exporter/resources|/spec/verticalScaling/exporter/resources - label: - text: labels.exporter - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/exporter/properties/resources - type: resource-input-form - if: ifRequestTypeEqualsTo|VerticalScaling - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/storage/resources/requests/storage - if: ifDbTypeEqualsTo|combined|VolumeExpansion - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/node - type: input - validationRuleObject: - func: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/node - - label: - text: Mode - options: - - text: Offline - value: Offline - - text: Online - value: Online - required: true - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/mode - type: select - - elements: - - computed: setValueFromDbDetails|/spec/topology/master/storage/resources/requests/storage - if: hasVolumeExpansion|master - label: - text: labels.storage.master_size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/master - type: input - validationRuleObject: - func: checkVolume|/spec/topology/master/storage/resources/requests/storage|/spec/volumeExpansion/master - - computed: setValueFromDbDetails|/spec/topology/data/storage/resources/requests/storage - if: hasVolumeExpansion|data - label: - text: labels.storage.data_size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/data - type: input - validationRuleObject: - func: checkVolume|/spec/topology/data/storage/resources/requests/storage|/spec/volumeExpansion/data - - computed: setValueFromDbDetails|/spec/topology/ingest/storage/resources/requests/storage - if: hasVolumeExpansion|ingest - label: - text: labels.storage.ingest_size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/ingest - type: input - validationRuleObject: - func: checkVolume|/spec/topology/ingest/storage/resources/requests/storage|/spec/volumeExpansion/ingest - - computed: setValueFromDbDetails|/spec/topology/ml/storage/resources/requests/storage - if: hasVolumeExpansion|ml - label: - text: labels.storage.ml_size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/ml - type: input - validationRuleObject: - func: checkVolume|/spec/topology/ml/storage/resources/requests/storage|/spec/volumeExpansion/ml - - computed: setValueFromDbDetails|/spec/topology/transform/storage/resources/requests/storage - if: hasVolumeExpansion|transform - label: - text: labels.storage.transform_size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/transform - type: input - validationRuleObject: - func: checkVolume|/spec/topology/transform/storage/resources/requests/storage|/spec/volumeExpansion/transform - - computed: setValueFromDbDetails|/spec/topology/dataCold/storage/resources/requests/storage - if: hasVolumeExpansion|dataCold - label: - text: labels.storage.data_cold_size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/dataCold - type: input - validationRuleObject: - func: checkVolume|/spec/topology/dataCold/storage/resources/requests/storage|/spec/volumeExpansion/dataCold - - computed: setValueFromDbDetails|/spec/topology/dataContent/storage/resources/requests/storage - if: hasVolumeExpansion|dataContent - label: - text: labels.storage.data_content_size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/dataContent - type: input - validationRuleObject: - func: checkVolume|/spec/topology/dataContent/storage/resources/requests/storage|/spec/volumeExpansion/dataContent - - computed: setValueFromDbDetails|/spec/topology/dataFrozen/storage/resources/requests/storage - if: hasVolumeExpansion|dataFrozen - label: - text: labels.storage.data_frozen_size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/dataFrozen - type: input - validationRuleObject: - func: checkVolume|/spec/topology/dataFrozen/storage/resources/requests/storage|/spec/volumeExpansion/dataFrozen - - computed: setValueFromDbDetails|/spec/topology/dataHot/storage/resources/requests/storage - if: hasVolumeExpansion|dataHot - label: - text: labels.storage.data_hot_size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/dataHot - type: input - validationRuleObject: - func: checkVolume|/spec/topology/dataHot/storage/resources/requests/storage|/spec/volumeExpansion/dataHot - - computed: setValueFromDbDetails|/spec/topology/dataWarm/storage/resources/requests/storage - if: hasVolumeExpansion|dataWarm - label: - text: labels.storage.data_warm_size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/dataWarm - type: input - validationRuleObject: - func: checkVolume|/spec/topology/dataWarm/storage/resources/requests/storage|/spec/volumeExpansion/dataWarm - if: ifDbTypeEqualsTo|topology|VolumeExpansion - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|VolumeExpansion - label: - text: Volume Expansion Form - type: single-step-form - - elements: - - discriminator: - reconfigurationType: - type: string - elements: - - label: - text: labels.reconfigurationType - onChange: onReconfigurationTypeChange - options: - - text: Select New Config Secret - value: selectNewConfigSecret - - text: Apply Config - value: applyConfig - - text: Remove - value: remove - required: true - schema: - $ref: discriminator#/properties/reconfigurationType - type: radio - - elements: - - add_new_button: - label: labels.createConfig - target: _blank - url: - function: createSecretUrl - computed: setValueFromDbDetails|/spec/configSecret/name - fetch: getConfigSecrets - label: - text: labels.configSecret - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret/properties/name - type: select - if: ifReconfigurationTypeEqualsTo|selectNewConfigSecret - label: - text: Configuration config secret - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret - type: single-step-form - - addFormLabel: labels.applyConfig.label - element: - discriminator: - configArray: - emitAs: applyConfig - type: array + - type: input + label: API Group + init: + type: func + value: initIssuerRefApiGroup + watcher: + func: initIssuerRefApiGroup + paths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + disable: true + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup + - type: select + label: Kind + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/kind + validation: + type: custom + name: isIssuerRefRequired + options: + - text: Issuer + value: Issuer + - text: ClusterIssuer + value: ClusterIssuer + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - type: select + label: Name + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/name + loader: + name: getIssuerRefsName + watchPaths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - schema/properties/metadata/properties/namespace + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/name + - type: block-layout + label: Certificates + showLabels: false + if: + type: function + name: showIssuerRefAndCertificates + loader: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates elements: - - label: - text: labels.applyConfig.key - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/key - type: input - - label: - text: labels.applyConfig.value - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/value - type: editor - type: single-step-form - if: ifReconfigurationTypeEqualsTo|applyConfig - label: - text: labels.applyConfig.label - onChange: onApplyconfigChange - required: true - schema: - $ref: discriminator#/properties/applyConfig - tableContents: - - inTableColumn: true - label: - text: labels.applyConfig.key - path: key - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.applyConfig.value - path: value - type: value - typeOfValue: code - type: single-step-form-array - - if: returnFalse - label: - text: labels.removeCustomConfig - schema: - $ref: schema#/properties/spec/properties/configuration/properties/removeCustomConfig - type: switch - label: - text: labels.configuration - schema: - $ref: schema#/properties/spec/properties/configuration - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|Reconfigure - label: - text: Reconfigure Form - type: single-step-form - - discriminator: - tlsOperation: - default: update - type: string - elements: - - computed: initTlsOperation - if: hasTlsField - label: - text: labels.tlsOperation - onChange: onTlsOperationChange - options: - - text: Update - value: update - - text: Rotate - value: rotate - - text: Remove - value: remove - schema: - $ref: discriminator#/properties/tlsOperation - type: radio - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/remove - type: switch - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/rotateCertificates - type: switch - - elements: - - computed: initIssuerRefApiGroup - disabled: true - label: - text: labels.api_group - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup - type: input - - computed: setValueFromDbDetails|/spec/tls/issuerRef/kind - label: - text: labels.kind - options: - - text: Issuer - value: Issuer - - text: ClusterIssuer - value: ClusterIssuer - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/kind - type: select - - allowUserDefinedOption: true - computed: setValueFromDbDetails|/spec/tls/issuerRef/name - fetch: getIssuerRefsName - label: - text: labels.name - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/name - type: select - if: showIssuerRefAndCertificates - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef - type: single-step-form - - alias: reusable_certificates - chart: - name: uibytebuildersdev-component-certificates - version: v0.29.0 - computed: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates - functionCallbacks: - getAliasOptions: - $ref: functions#/getAliasOptions - if: showIssuerRefAndCertificates - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/spec/properties/tls/properties/certificates - type: reusable-element - if: ifRequestTypeEqualsTo|ReconfigureTLS - label: - text: labels.tls - schema: - $ref: schema#/properties/spec/properties/tls - type: single-step-form - - label: - text: labels.timeout - options: - - text: 5 minutes - value: 5m - - text: 10 minutes - value: 10m - - text: 30 minutes - value: 30m - - text: 1 hour - value: 1h - - text: 2 hours - value: 2h - - text: 5 hours - value: 5h - - text: 10 hours - value: 10h - schema: - $ref: schema#/properties/spec/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: labels.apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/spec/properties/apply - type: radio - type: single-step-form - id: basic - title: steps.0.label -type: multi-step-form + - type: array-object-form + label: Certificates + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/tls/properties/certificates + elements: + - type: select + label: Alias + loader: fetchAliasOptions + disable: disableAlias + schema: alias + validation: + type: required + - type: input + label: Secret Name + schema: secretName + - type: input + label: Duration + schema: duration + - type: input + label: Renew Before + schema: renewBefore + - type: array-item-form + label: Organizations + buttonClass: is-light is-outlined + schema: subject/properties/organizations + element: + type: input + label: Organization + - type: array-item-form + label: Countries + buttonClass: is-light is-outlined + schema: subject/properties/countries + element: + type: input + label: Country + - type: array-item-form + label: Organizational Units + buttonClass: is-light is-outlined + schema: subject/properties/organizationalUnits + element: + type: input + label: Organizational Unit + - type: array-item-form + label: Provinces + buttonClass: is-light is-outlined + schema: subject/properties/provinces + element: + type: input + label: Province + - type: array-item-form + label: DNS Names + buttonClass: is-light is-outlined + schema: dnsNames + element: + type: input + label: DNS Name + - type: array-item-form + label: IP Addresses + buttonClass: is-light is-outlined + schema: ipAddresses + element: + type: input + label: IP Address +# common + - type: block-layout + label: OpsRequest Options + showLabels: true + elements: + - type: time-picker + label: Timeout + schema: 'schema/properties/spec/properties/timeout' + subtitle: Specify the maximum time allowed for the operation to complete. Use formats like 30sec, 1min (1 minute) or 2h (2 hours). + - type: radio + label: Apply + schema: 'schema/properties/spec/properties/apply' + init: + type: func + value: setApplyToIfReady + options: + - text: IfReady (OpsRequest will be applied if database is ready) + value: IfReady + - text: Always (OpsRequest will always be applied) + value: Always diff --git a/charts/opskubedbcom-elasticsearchopsrequest-editor/ui/functions.js b/charts/opskubedbcom-elasticsearchopsrequest-editor/ui/functions.js index b5e17ba8ab..a2007dc514 100644 --- a/charts/opskubedbcom-elasticsearchopsrequest-editor/ui/functions.js +++ b/charts/opskubedbcom-elasticsearchopsrequest-editor/ui/functions.js @@ -1,3 +1,8 @@ +const { axios, useOperator, store, useToast } = window.vueHelpers || {} + +// ===================================================== +// Machine Profiles Configuration +// ===================================================== const machines = { 'db.t.micro': { resources: { @@ -304,1078 +309,1817 @@ const machineList = [ 'db.r.24xlarge', ] -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) - } +// ===================================================== +// Global Variables +// ===================================================== +let machinesFromPreset = [] +let secretArray = [] +const configSecretKeys = ['elasticsearch.yml', 'data-elasticsearch.yml', 'ingest-elasticsearch.yml'] - return { - ui: ui.data || {}, - language: language.data || {}, - functions, - } -} +export const useFunc = (model) => { + const route = store.state?.route + const toast = useToast() -function returnFalse() { - return false -} + const { getValue, storeGet, discriminator, setDiscriminatorValue, commit } = useOperator( + model, + store.state, + ) -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + // Initialize on load + showAndInitOpsRequestType() -async function getNamespaces({ axios, storeGet }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + // ===================================================== + // Core Utility Functions + // ===================================================== - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + async function fetchJsons({ axios, itemCtx }) { + let ui = {} + let language = {} + let functions = {} + const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart - const resources = (resp && resp.data && resp.data.items) || [] + 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 resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' return { - text: name, - value: name, + ui: ui.data || {}, + language: language.data || {}, + functions, } - }) -} - -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - 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}/elasticsearches`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + function returnFalse() { + return false + } - const resources = (resp && resp.data && resp.data.items) || [] + function returnTrue() { + return true + } - 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 + } -let elasticVersions = [] + // ===================================================== + // Namespace Functions + // ===================================================== -async function getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) { - 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') + async function getNamespaces() { + if (storeGet('/route/params/actions')) return [] + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - if (namespace && name) { - const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/elasticsearches/${name}` - const resp = await axios.get(url) + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, + }) - const { version } = resp?.data?.spec || {} - const selectedVersion = elasticVersions?.find((item) => item?.metadata?.name === version) + const resources = (resp && resp.data && resp.data.items) || [] - if (resp?.data?.spec) { - resp.data.spec.authPlugin = selectedVersion?.spec?.authPlugin || '' - } + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } - setDiscriminatorValue('/dbDetails', resp.data || {}) + function initNamespace() { + const { namespace } = route.query || {} + return namespace || null + } - return resp.data || {} - } else return {} -} + function isNamespaceDisabled() { + const { namespace } = route.query || {} + return !!namespace + } -async function getDbVersions({ axios, storeGet, getValue, discriminator }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function onNamespaceChange() { + commit('wizard/model$delete', '/spec/type') + } - const url = `/clusters/${owner}/${cluster}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/kubedb-ui-presets` + // ===================================================== + // Database Functions + // ===================================================== - 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) - } - } + async function getDbs() { + if (storeGet('/route/params/actions')) return [] + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - try { - const presetVersions = presets.admin?.databases?.Elasticsearch?.versions?.available || [] - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null, updateConstraints: null }, - }, - }, - } + const namespace = getValue(model, '/metadata/namespace') + // watchDependency('model#/metadata/namespace') const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/catalog.kubedb.com/v1alpha1/elasticsearchversions`, + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/elasticsearches`, { - params: queryParams, + params: { filter: { items: { metadata: { name: null } } } }, }, ) 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 allowed = found?.spec?.updateConstraints?.allowlist || [] - 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 filteredElasticsearchVersions = 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.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.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.includes(item.metadata?.name)) && - isVersionWithinConstraints(item.spec?.version, limit) - ) - }) - - return filteredElasticsearchVersions.map((item) => { + return resources.map((item) => { const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' return { - text: `${name} (${specVersion})`, + text: name, value: name, } }) - } catch (e) { - console.log(e) - return [] } -} -function versionCompare(v1, v2) { - const arr1 = v1.split('.').map(Number) - const arr2 = v2.split('.').map(Number) + async function getDbDetails() { + machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] - for (let i = 0; i < Math.max(arr1.length, arr2.length); i++) { - const num1 = arr1[i] || 0 - const num2 = arr2[i] || 0 + 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 (num1 > num2) return 1 // v1 is higher - if (num1 < num2) return -1 // v2 is higher - } - return 0 // versions are equal -} + if (namespace && name) { + const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/elasticsearches/${name}` -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() + try { + const resp = await axios.get(url) + + // Fetch and inject auth plugin from version + const version = resp?.data?.spec?.version + if (version) { + const versionResp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/catalog.kubedb.com/v1alpha1/elasticsearchversions/${version}`, + ) + if (resp?.data?.spec && versionResp?.data?.spec?.authPlugin) { + resp.data.spec.authPlugin = versionResp.data.spec.authPlugin + } + } + + setDiscriminatorValue('/dbDetails', resp.data || {}) + + return resp.data || {} + } catch (e) { + console.log(e) + return {} + } + } else return {} + } - let comparison = versionCompare(version, constraintVersion) - if ( - (operator === '>=' && comparison < 0) || - (operator === '<=' && comparison > 0) || - (operator === '>' && comparison <= 0) || - (operator === '<' && comparison >= 0) + function isTlsEnabled() { + const dbDetails = getValue(discriminator, '/dbDetails') + return ( + (dbDetails?.spec?.sslMode && + dbDetails?.spec?.sslMode !== 'disabled' && + dbDetails?.spec?.sslMode !== 'disable') || + dbDetails?.spec?.tls ) - return false } - return true -} -function ifRequestTypeEqualsTo({ model, getValue, watchDependency }, type) { - const selectedType = getValue(model, '/spec/type') - watchDependency('model#/spec/type') - - return selectedType === type -} - -function onApplyconfigChange({ discriminator, getValue, commit }) { - const applyconfig = getValue(discriminator, '/applyConfig') - - const configObj = {} - if (applyconfig) { - applyconfig.forEach((item) => { - const { key, value } = item - configObj[key] = value - }) + function initDatabaseRef() { + // watchDependency('model#/metadata/namespace') + const { name } = route.params || {} + return name } - commit('wizard/model$update', { - path: '/spec/configuration/applyConfig', - value: configObj, - force: true, - }) -} - -function onRequestTypeChange({ model, getValue, commit }) { - 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 getDbTls({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') - - const { spec } = dbDetails || {} - return (spec && spec.tls) || undefined -} - -function getDbType({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + function isDatabaseRefDisabled() { + const { name } = route.params || {} + return !!name + } - const { spec } = dbDetails || {} - const { topology } = spec || {} - let verd = '' - if (topology) { - verd = 'topology' - } else { - verd = 'combined' + function onDbChange() { + commit('wizard/model$delete', '/spec/type') + getDbDetails() } - return verd -} + function isDbDetailsLoading() { + // watchDependency('discriminator#/dbDetails') + // watchDependency('model#/spec/databaseRef/name') + const dbDetails = getValue(discriminator, '/dbDetails') + const dbName = getValue(model, '/spec/databaseRef/name') -function initNamespace({ route }) { - const { namespace } = route.query || {} - return namespace || null -} + return !dbDetails || !dbName + } -function initDatabaseRef({ route, watchDependency }) { - watchDependency('model#/metadata/namespace') - const { name } = route.params || {} - return name -} + // ===================================================== + // Database Version Functions + // ===================================================== -function clearOpsReqSpec(verd, opsReqType, commit) { - if ( - opsReqType === 'verticalScaling' || - opsReqType === 'horizontalScaling' || - opsReqType === 'volumeExpansion' || - opsReqType === 'configuration' - ) { - if (verd === 'combined') { - commit('wizard/model$delete', `/spec/${opsReqType}/topology`) - } else { - commit('wizard/model$delete', `/spec/${opsReqType}/node`) + 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?.Elasticsearch?.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/elasticsearchversions`, + { + 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 allowed = found?.spec?.updateConstraints?.allowlist || [] + 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 filteredDbVersions = 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.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.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.includes(item.metadata?.name)) && + isVersionWithinConstraints(item.spec?.version, limit) + ) + }) + setDiscriminatorValue('/filteredVersion', filteredDbVersions) + return filteredDbVersions.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 asDatabaseOperation(route) { - return !!route.params.actions -} -function generateOpsRequestNameForClusterUI(getValue, model, route) { - const dbName = getValue(model, '/spec/databaseRef/name') + function versionCompare(v1, v2) { + const arr1 = v1.split('.').map(Number) + const arr2 = v2.split('.').map(Number) - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + for (let i = 0; i < Math.max(arr1.length, arr2.length); i++) { + const num1 = arr1[i] || 0 + const num2 = arr2[i] || 0 - const resources = route.params.resource || '' - const resource = resources.slice(0, -1) + if (num1 > num2) return 1 // v1 is higher + if (num1 < num2) return -1 // v2 is higher + } + return 0 // versions are equal + } - const opsName = dbName ? dbName : resource - return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` -} + 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 showAndInitName({ route, commit, getValue, model, watchDependency }) { - watchDependency('model#/spec/type') - watchDependency('model#/spec/databaseRef/name') - const ver = asDatabaseOperation(route) + function getVersionInfo() { + const filteredVersion = getValue(discriminator, '/filteredVersion') + if (filteredVersion.length) return '' - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + let txt = 'No versions from this list can be selected as the target version: [ ' - 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({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/metadata/namespace', - value: `${route.query.namespace}`, - force: true, + presetVersions.forEach((v, idx) => { + txt = `${txt}"${v}"` + if (idx !== presetVersions.length - 1) txt = txt + ', ' + else txt = txt + ' ]' }) + + return txt } - return !ver -} -function showAndInitDatabaseRef({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/spec/databaseRef/name', - value: `${route.params.name}`, - force: true, + 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, + } }) } - return !ver -} -function showConfigureOpsrequestLabel({ route }) { - return !asDatabaseOperation(route) -} -function showAndInitOpsRequestType({ route, commit }) { - const ver = asDatabaseOperation(route) - const opMap = { - upgrade: 'UpdateVersion', - updateVersion: 'UpdateVersion', - horizontalscaling: 'HorizontalScaling', - verticalscaling: 'VerticalScaling', - volumeexpansion: 'VolumeExpansion', - restart: 'Restart', - reconfiguretls: 'ReconfigureTLS', - reconfigure: 'Reconfigure', - } - if (ver) { - const operation = route.params.actions - const match = /^(.*)-opsrequest-(.*)$/.exec(operation) - const opstype = match[2] - commit('wizard/model$update', { - path: '/spec/type', - value: opMap[opstype], - force: true, - }) + function isVersionEmpty() { + const val = getValue(discriminator, '/filteredVersion') + return val.length === 0 } - return !ver -} + // ===================================================== + // OpsRequest Type Functions + // ===================================================== -// vertical scaling -function ifDbTypeEqualsTo({ discriminator, getValue, watchDependency, commit }, value, opsReqType) { - const verd = getDbType({ - discriminator, - getValue, - watchDependency, - }) + function ifRequestTypeEqualsTo(type) { + const selectedType = getValue(model, '/spec/type') + // watchDependency('model#/spec/type') - clearOpsReqSpec(verd, opsReqType, commit) - return value === verd -} + return selectedType === type + } -// machine profile stuffs -let machinesFromPreset = [] -function hasMachine({ getValue, discriminator }) { - const dbDetails = getValue(discriminator, '/dbDetails') - const annotations = dbDetails?.metadata?.annotations || {} - return !!annotations['kubernetes.io/instance-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', + } -function getMachines({ storeGet }) { - const presets = storeGet('/kubedbuiPresets') || {} - const avlMachines = presets.admin?.machineProfiles?.available || [] - let arr = [] - if (avlMachines.length) { - arr = avlMachines.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - 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 } - } else return { text: machine, value: machine } - } + Object.keys(reqTypeMapping).forEach((key) => { + if (key !== selectedType) commit('wizard/model$delete', `/spec/${reqTypeMapping[key]}`) }) - } else { - arr = machineList - .map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } - }) - .filter((val) => !!val) } - return arr -} -function setMachine({ getValue, discriminator, storeGet }, type) { - const dbDetails = getValue(discriminator, '/dbDetails') - 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 = {} + function getRequestTypeFromRoute() { + const isDbloading = isDbDetailsLoading() + const { query } = route || {} + const { requestType } = query || {} + return isDbloading ? '' : requestType || '' } - const machine = parsedInstance[type] || 'custom' - machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] + // ===================================================== + // Database Type Functions (Topology vs Combined) + // ===================================================== - const machinePresets = machinesFromPreset.find((item) => item.id === machine) - if (machinePresets) return machine - else return 'custom' -} + function getDbType() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') -function onMachineChange({ getValue, discriminator, commit, model }, type, valPath) { - let selectedMachine = '' - selectedMachine = getValue(discriminator, `/machine-${type}`) - const machine = machinesFromPreset.find((item) => item.id === selectedMachine) + const { spec } = dbDetails || {} + const { topology } = spec || {} - let obj = {} - if (selectedMachine !== 'custom') { - if (machine) obj = { limits: { ...machine?.limits }, requests: { ...machine?.limits } } - else obj = machines[selectedMachine]?.resources - } else { - const val = getValue(discriminator, `/dbDetails${valPath}`) || {} - obj = Array.isArray(val) ? val[0]?.resources : { ...val } + if (topology) { + return 'Topology' + } else { + return 'Combined' + } } - 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') || {} - const instance = annotations['kubernetes.io/instance-type'] - let parsedInstance = {} - try { - if (instance) parsedInstance = JSON.parse(instance) - } catch (e) { - console.log(e) - parsedInstance = {} - } - if (selectedMachine === 'custom') delete parsedInstance[type] - else parsedInstance[type] = selectedMachine - annotations['kubernetes.io/instance-type'] = JSON.stringify(parsedInstance) - - if (machinesFromPreset.length) - commit('wizard/model$update', { - path: '/metadata/annotations', - value: annotations, - force: true, - }) - - if (parsedInstance && Object.keys(parsedInstance).length === 0) - commit('wizard/model$delete', '/metadata/annotations') -} - -function isMachineCustom({ watchDependency, getValue, discriminator }, path) { - watchDependency(`discriminator#${path}`) - const machine = getValue(discriminator, `${path}`) - return machine === 'custom' -} + function ifDbTypeEqualsTo(value, opsReqType, mode, section) { + const verd = getDbType() -function isAuthPluginNotEqualTo({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + clearOpsReqSpec(verd, opsReqType) + return value === verd + } - const authPlugin = dbDetails?.spec?.authPlugin || '' + function clearOpsReqSpec(verd, opsReqType) { + if ( + opsReqType === 'verticalScaling' || + opsReqType === 'horizontalScaling' || + opsReqType === 'volumeExpansion' || + opsReqType === 'configuration' + ) { + if (verd === 'Topology') { + // Clear combined mode fields + commit('wizard/model$delete', `/spec/${opsReqType}/node`) + } else { + // Clear topology mode fields + commit('wizard/model$delete', `/spec/${opsReqType}/topology`) + } + } + } - return authPlugin && authPlugin !== value -} + // ===================================================== + // Auth Plugin Functions (Elasticsearch-specific) + // ===================================================== -function isAuthPluginEqualTo({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + function isAuthPluginEqualTo(value) { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') - const authPlugin = dbDetails?.spec?.authPlugin || '' + const authPlugin = dbDetails?.spec?.authPlugin || '' - return authPlugin === value -} + return authPlugin === value + } -// for config secret -async function getConfigSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + function isAuthPluginNotEqualTo(value) { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') - const secrets = (resp && resp.data && resp.data.items) || [] + const authPlugin = dbDetails?.spec?.authPlugin || '' - const filteredSecrets = secrets + return authPlugin && authPlugin !== value + } - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return filteredSecrets -} + // ===================================================== + // Available Roles Functions (Elasticsearch-specific) + // ===================================================== -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function getAvailableRoles() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') + const authPlugin = dbDetails?.spec?.authPlugin || '' + + // Base roles available for all auth plugins + const baseRoles = ['master', 'data', 'ingest'] + + // X-Pack specific roles (includes ML, Transform, and tier nodes) + if (authPlugin === 'X-Pack') { + return [ + ...baseRoles, + 'ml', + 'transform', + 'dataHot', + 'dataWarm', + 'dataCold', + 'dataFrozen', + 'dataContent', + ] + } - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + // SearchGuard and OpenDistro only support base roles + return baseRoles + } - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }) + // ===================================================== + // OpsRequest Name/Namespace Initialization + // ===================================================== - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + function asDatabaseOperation() { + return !!route.params.actions } - return ans -} -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function generateOpsRequestNameForClusterUI(getValue, model, route) { + const dbName = getValue(model, '/spec/databaseRef/name') - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }) + const resources = route.params.resource || '' + const resource = resources.slice(0, -1) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + const opsName = dbName ? dbName : resource + return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` } - return ans -} -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - group, - version, - resource, -) { - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/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) - }) - } + function showAndInitName() { + // watchDependency('model#/spec/type') + // watchDependency('model#/spec/databaseRef/name') + const ver = asDatabaseOperation() - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + 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, + }) } - }) -} -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) - - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) + return !ver } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + function showAndInitNamespace() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/metadata/namespace', + value: `${route.query.namespace}`, + force: true, + }) } - }) -} -// reconfiguration type -function ifReconfigurationTypeEqualsTo({ discriminator, getValue, watchDependency }, value) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - watchDependency('discriminator#/reconfigurationType') + return !ver + } - return reconfigurationType === value -} -function onReconfigurationTypeChange({ commit, discriminator, getValue }) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - if (reconfigurationType === 'remove') { - commit('wizard/model$delete', `/spec/configuration`) + function showAndInitDatabaseRef() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/spec/databaseRef/name', + value: `${route.params.name}`, + force: true, + }) + } - 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/inlineConfig`) - commit('wizard/model$delete', `/spec/configuration/removeCustomConfig`) + return !ver } -} -// for tls -function hasTlsField({ discriminator, getValue, watchDependency }) { - const tls = getDbTls({ - discriminator, - getValue, - watchDependency, - }) + function showConfigureOpsrequestLabel() { + return !asDatabaseOperation() + } - return !!tls -} + 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, + }) + } + } -function initIssuerRefApiGroup({ getValue, model, watchDependency, discriminator }) { - const kind = getValue(model, '/spec/tls/issuerRef/kind') - watchDependency('model#/spec/tls/issuerRef/kind') + return !ver + } - if (kind) { - const apiGroup = getValue(discriminator, '/dbDetails/spec/tls/issuerRef/apiGroup') - if (apiGroup) return apiGroup - return 'cert-manager.io' - } else return undefined -} + // ===================================================== + // Machine Profile Functions + // ===================================================== -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - 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` + function getMachines(type) { + const presets = storeGet('/kubedbuiPresets') || {} + const dbDetails = getValue(discriminator, '/dbDetails') - 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) - } + // Determine the resource path based on type + let limits = { cpu: '', memory: '' } + if (type === 'node' || !type) { + // Combined mode + limits = dbDetails?.spec?.podTemplate?.spec?.resources?.requests || limits + } else { + // Topology mode - specific node type + limits = dbDetails?.spec?.topology?.[type]?.resources?.requests || limits } - let clusterIssuers = presets.admin?.clusterIssuers?.available || [] - if (presets.status === '404') { - const url = `/clusters/${owner}/${cluster}/proxy/cert-manager.io/v1/clusterissuers` - return getIssuer(url) + + 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 clusterIssuers + return arr } - async function getIssuer(url) { - try { - const resp = await axios.get(url) - const resources = (resp && resp.data && resp.data.items) || [] + function setMachine(type) { + const dbDetails = getValue(discriminator, '/dbDetails') - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return resources - } catch (e) { + // Determine the resource path based on type + let limits = { cpu: '', memory: '' } + if (type === 'node' || !type) { + // Combined mode + limits = dbDetails?.spec?.podTemplate?.spec?.resources?.requests || limits + } else { + // Topology mode - specific node type + limits = dbDetails?.spec?.topology?.[type]?.resources?.requests || limits + } + + 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) - return [] + parsedInstance = {} } + const machine = parsedInstance[type] || '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 initTlsOperation() { - return 'update' -} -function onTlsOperationChange({ discriminator, getValue, commit }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + function onMachineChange(type, valPath) { + let selectedMachine = {} + selectedMachine = getValue(discriminator, `/machine-${type}`) + 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') || {} + const instance = annotations['kubernetes.io/instance-type'] + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = {} + } + parsedInstance[type] = selectedMachine.machine + annotations['kubernetes.io/instance-type'] = JSON.stringify(parsedInstance) + + if (machinesFromPreset.length) + commit('wizard/model$update', { + path: '/metadata/annotations', + value: annotations, + force: true, + }) + + if (parsedInstance && Object.keys(parsedInstance).length === 0) + commit('wizard/model$delete', '/metadata/annotations') + } + + function isMachineCustom(path) { + // watchDependency(`discriminator#${path}`) + const machine = getValue(discriminator, `${path}`) + return machine === 'custom' + } + + // ===================================================== + // Vertical Scaling Functions + // ===================================================== + + function isVerticalScaleTopologyRequired(type) { + // watchDependency(`discriminator#/topologyKey-${type}`) + // watchDependency(`discriminator#/topologyValue-${type}`) + + const key = getValue(discriminator, `/topologyKey-${type}`) + const value = getValue(discriminator, `/topologyValue-${type}`) + const path = `/spec/verticalScaling/${type}/topology` + + if (key || value) { + commit('wizard/model$update', { + path: path, + value: { key, value }, + force: true, + }) + return '' + } else { + commit('wizard/model$delete', path) + return false + } + } - commit('wizard/model$delete', '/spec/tls') + // ===================================================== + // Volume Expansion Functions + // ===================================================== + + 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] + } + + // ===================================================== + // Configuration/Reconfiguration Functions + // ===================================================== + + // Fetch and store database Infos + // for secret configurations in reconfigure + let configSecrets = [] + let secretConfigData = [] + + 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: ['elasticsearch.yml', 'data-elasticsearch.yml', 'ingest-elasticsearch.yml'], + }, + }, + ) + configSecrets = resp?.data?.response?.availableSecrets || [] + secretConfigData = resp?.data?.response?.configurations || [] + } 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 + }) + } + }) - if (tlsOperation === 'rotate') { + // Set the value to the model commit('wizard/model$update', { - path: '/spec/tls/rotateCertificates', - value: true, + path: `/temp/${type}applyConfig`, + value: result, force: true, }) - commit('wizard/model$delete', '/spec/tls/certificates') - commit('wizard/model$delete', '/spec/tls/remove') - } else if (tlsOperation === 'remove') { + + 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])) + + 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() + } + } + + 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) { + 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], + }) + }) + } else { + configObj.push({ name: '', 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/tls/remove', + path: `/spec/configuration/${type}removeCustomConfig`, value: true, - force: true, }) - commit('wizard/model$delete', '/spec/tls/certificates') - commit('wizard/model$delete', '/spec/tls/rotateCertificates') + + 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 } -} -function showIssuerRefAndCertificates({ discriminator, getValue, watchDependency }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') - watchDependency('discriminator#/tlsOperation') - const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' + async function onNewConfigSecretChange(type) { + type = type ? type + '/' : '' + const path = `/spec/configuration/${type}configSecret/name` + const selectedSecret = getValue(model, path) - return verd -} + if (!selectedSecret) { + commit('wizard/model$delete', `/spec/configuration/${type}configSecret`) + return [{ name: '', content: '' }] + } + if (selectedSecret === 'Create') return [{ name: '', content: '' }] -function isIssuerRefRequired({ discriminator, getValue, watchDependency }) { - const hasTls = hasTlsField({ - discriminator, - getValue, - watchDependency, - }) + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = storeGet('/route/query/namespace') || getValue(model, '/metadata/namespace') - return !hasTls -} + 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 + }) + } + }) -// ************************************** Set db details ***************************************** + return configObj + } catch (e) { + console.error('Error fetching secret:', e) + return [{ name: '', content: '' }] + } + } -function isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - watchDependency('model#/spec/databaseRef/name') - const dbDetails = getValue(discriminator, '/dbDetails') - const dbName = getValue(model, '/spec/databaseRef/name') + function onSelectedSecretChange(index) { + const secretData = getValue(discriminator, 'createSecret/data') || [] + const selfSecrets = secretData.map((item) => item.key) - return !dbDetails || !dbName -} + const remainingSecrets = configSecretKeys.filter((item) => !selfSecrets.includes(item)) -function setValueFromDbDetails( - { discriminator, getValue, watchDependency, commit }, - path, - commitPath, -) { - watchDependency('discriminator#/dbDetails') - const retValue = getValue(discriminator, `/dbDetails${path}`) + 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 + } - if (commitPath) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + function getSelectedConfigSecret(type) { + const path = `/spec/configuration/${type}/configSecret/name` + const selectedSecret = getValue(model, path) + // watchDependency(`model#${path}`) + return selectedSecret ? `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/${type}/configSecret/name` + const selectedSecret = getValue(model, path) + // watchDependency(`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 createSecretUrl() { + const user = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined + 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 isEqualToValueFromType(value) { + // watchDependency('discriminator#/valueFromType') + const valueFrom = getValue(discriminator, '/valueFromType') + return valueFrom === value + } + + function ifReconfigurationTypeEqualsTo(value, property, isShard) { + let path = '/reconfigurationType' + if (isShard) path += `-${property}` + const reconfigurationType = getValue(discriminator, path) + + const watchPath = `discriminator#${path}` + // watchDependency(watchPath) + return reconfigurationType === value + } + + function onReconfigurationTypeChange(property, isShard) { + setDiscriminatorValue(`/${property}/applyConfig`, []) + let path = '/reconfigurationType' + if (isShard) path += `-${property}` + const reconfigurationType = getValue(discriminator, path) + if (reconfigurationType === 'remove') { + commit('wizard/model$delete', `/spec/configuration/${property}`) - // direct model update required for reusable element. - // computed property is not applicable for reusable element - if (retValue) { commit('wizard/model$update', { - path: commitPath, - value: retValue, + path: `/spec/configuration/${property}/removeCustomConfig`, + value: true, force: true, }) + } else { + commit('wizard/model$delete', `/spec/configuration/${property}/configSecret`) + commit('wizard/model$delete', `/spec/configuration/${property}/applyConfig`) + commit('wizard/model$delete', `/spec/configuration/${property}/removeCustomConfig`) } } - return retValue || undefined -} + // ===================================================== + // TLS Functions + // ===================================================== -function disableOpsRequest({ itemCtx, discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - if (itemCtx.value === 'ReconfigureTLS') { + function getDbTls() { + // watchDependency('discriminator#/dbDetails') const dbDetails = getValue(discriminator, '/dbDetails') - const { issuerRef } = dbDetails?.spec?.tls || {} - return !issuerRef + + const { spec } = dbDetails || {} + return spec?.tls || undefined } - return false -} -function hasResourceValue({ discriminator, getValue, watchDependency }, node) { - watchDependency('discriminator#/dbDetails') - const nodeResource = getValue(discriminator, `/dbDetails/spec/topology/${node}/resources`) - return !!nodeResource -} + function hasTlsField() { + const tls = getDbTls() -function hasVolumeExpansion({ discriminator, getValue, watchDependency }, node) { - watchDependency('discriminator#/dbDetails') - const nodeStorage = getValue( - discriminator, - `/dbDetails/spec/topology/${node}/storage/resources/requests/storage`, - ) - return !!nodeStorage -} + return !!tls + } + + function initIssuerRefApiGroup() { + const kind = getValue(model, '/spec/tls/issuerRef/kind') + // watchDependency('model#/spec/tls/issuerRef/kind') + + if (kind) { + return 'cert-manager.io' + } else return undefined + } -function getAliasOptions({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') + 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') - const enableSSL = getValue(discriminator, '/dbDetails/spec/enableSSL') - const authPlugin = getValue(discriminator, '/dbDetails/spec/authPlugin') - const monitor = getValue(discriminator, '/dbDetails/spec/monitor') + 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 [] + } - // always include transport cert alias - const aliases = ['transport'] + 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 [] + } + } + } - if (authPlugin !== 'X-Pack') { - aliases.push('admin') + function initTlsOperation() { + return 'update' } - if (enableSSL) { - aliases.push('http') - aliases.push('archiver') - if (monitor) { - aliases.push('metrics-exporter') + 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, + }) + } else if (tlsOperation === 'remove') { + commit('wizard/model$update', { + path: '/spec/tls/remove', + value: true, + force: true, + }) } } - return aliases -} + function showIssuerRefAndCertificates() { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // watchDependency('discriminator#/tlsOperation') + const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' -function isNamespaceDisabled({ route }) { - const { namespace } = route.query || {} - return !!namespace -} + return verd + } -function isDatabaseRefDisabled({ route }) { - const { name } = route.params || {} - return !!name -} + function isIssuerRefRequired() { + const hasTls = hasTlsField() + return hasTls ? false : '' + } -function onNamespaceChange({ commit, route }) { - const { operation } = route.query - // if operation query parameter is present - // then the type is set by showAndInitOpsRequestType and can not be changed or deleted - // otherwise delete the type - if (!operation) { - // delete type - commit('wizard/model$delete', '/spec/type') + function getAliasOptions() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') + const enableSSL = dbDetails?.spec?.enableSSL + const authPlugin = dbDetails?.spec?.authPlugin + const monitor = dbDetails?.spec?.monitor + + // always include transport cert alias + const aliases = ['transport'] + + if (authPlugin !== 'X-Pack') { + aliases.push('admin') + } + + if (enableSSL) { + aliases.push('http') + aliases.push('archiver') + if (monitor) { + aliases.push('metrics-exporter') + } + } + + return aliases } -} -function onDbChange({ commit, axios, storeGet, model, getValue, setDiscriminatorValue }) { - // delete type - commit('wizard/model$delete', '/spec/type') - getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) -} + function fetchAliasOptions() { + return getAliasOptions ? getAliasOptions() : [] + } -function setApplyToIfReady() { - return 'IfReady' -} + function validateNewCertificates({ itemCtx }) { + const addedAliases = (model && model.map((item) => item.alias)) || [] -function isVerticalScaleTopologyRequired( - { watchDependency, getValue, discriminator, commit }, - type, -) { - watchDependency(`discriminator#/topologyKey-${type}`) - watchDependency(`discriminator#/topologyValue-${type}`) + if (addedAliases.includes(itemCtx.alias) && itemCtx.isCreate) { + return { isInvalid: true, message: 'Alias already exists' } + } + return {} + } - const key = getValue(discriminator, `/topologyKey-${type}`) - const value = getValue(discriminator, `/topologyValue-${type}`) - const path = `/spec/verticalScaling/${type}/topology` + function disableAlias() { + return !!(model && model.alias) + } - if (key || value) { - commit('wizard/model$update', { - path: path, - value: { key, value }, - force: true, + // ===================================================== + // Resource/Namespaced Resource Functions + // ===================================================== + + 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, + } }) - return true - } else { - commit('wizard/model$delete', path) - return false } -} -function checkVolume({ model, discriminator, getValue }, initpath, path) { - const volume = getValue(discriminator, `/dbDetails${initpath}`) - const input = getValue(model, path) + 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, + } + }) + } + + // ===================================================== + // Helper Functions + // ===================================================== + + function setValueFromDbDetails(path, commitPath) { + const retValue = getValue(discriminator, `/dbDetails${path}`) + + if (commitPath) { + 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 setApplyToIfReady() { + return 'IfReady' + } - try { - const sizeInBytes = parseSize(volume) - const inputSizeInBytes = parseSize(input) + function disableOpsRequest() { + // Elasticsearch in Combined mode with single replica cannot be scaled horizontally + if (ifRequestTypeEqualsTo('HorizontalScaling')) { + const dbType = getDbType() + const replicas = getValue(discriminator, '/dbDetails/spec/replicas') - if (inputSizeInBytes >= sizeInBytes) return true - else return 'Cannot expand to lower volume!' - } catch (err) { - return err.message || 'Invalid' + if (dbType === 'Combined' && replicas === 1) return true + else return false + } else return false } -} -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] -} + // ===================================================== + // Elasticsearch-specific helper functions + // ===================================================== + + function hasResourceValue(type) { + const dbDetails = getValue(discriminator, '/dbDetails') + const spec = dbDetails?.spec || {} + + if (type === 'node') { + return !!spec?.podTemplate?.spec?.resources + } -return { - fetchJsons, - returnFalse, - getNamespaces, - getDbs, - getDbDetails, - getDbVersions, - ifRequestTypeEqualsTo, - onRequestTypeChange, - getDbTls, - getDbType, - initNamespace, - initDatabaseRef, - clearOpsReqSpec, - isRancherManaged, - showAndInitName, - showAndInitNamespace, - showAndInitDatabaseRef, - showConfigureOpsrequestLabel, - showAndInitOpsRequestType, - - ifDbTypeEqualsTo, - isAuthPluginEqualTo, - isAuthPluginNotEqualTo, - getConfigSecrets, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - ifReconfigurationTypeEqualsTo, - onApplyconfigChange, - onReconfigurationTypeChange, - hasTlsField, - initIssuerRefApiGroup, - getIssuerRefsName, - initTlsOperation, - onTlsOperationChange, - showIssuerRefAndCertificates, - isIssuerRefRequired, - isDbDetailsLoading, - setValueFromDbDetails, - disableOpsRequest, - hasResourceValue, - hasVolumeExpansion, - getAliasOptions, - isNamespaceDisabled, - isDatabaseRefDisabled, - onNamespaceChange, - onDbChange, - setApplyToIfReady, - isVerticalScaleTopologyRequired, - getMachines, - setMachine, - onMachineChange, - isMachineCustom, - checkVolume, + const topology = spec?.topology || {} + return !!topology[type]?.resources + } + + function hasVolumeExpansion(type) { + const dbDetails = getValue(discriminator, '/dbDetails') + const spec = dbDetails?.spec || {} + + if (type === 'node') { + return !!spec?.storage + } + + const topology = spec?.topology || {} + return !!topology[type]?.storage + } + + 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, + }) + } + + // ===================================================== + // Return all exported functions + // ===================================================== + + return { + // Utility functions + fetchJsons, + returnFalse, + returnTrue, + isRancherManaged, + + // Namespace functions + getNamespaces, + initNamespace, + isNamespaceDisabled, + onNamespaceChange, + + // Database functions + getDbs, + getDbDetails, + initDatabaseRef, + isDatabaseRefDisabled, + onDbChange, + isDbDetailsLoading, + + // Database version functions + getDbVersions, + getVersionInfo, + isVersionEmpty, + getVersion, + + // OpsRequest type functions + ifRequestTypeEqualsTo, + onRequestTypeChange, + getRequestTypeFromRoute, + + // Database type functions + getDbType, + ifDbTypeEqualsTo, + clearOpsReqSpec, + + // Auth plugin functions (Elasticsearch-specific) + isAuthPluginEqualTo, + isAuthPluginNotEqualTo, + getAvailableRoles, + + // OpsRequest name/namespace initialization + showAndInitName, + showAndInitNamespace, + showAndInitDatabaseRef, + showConfigureOpsrequestLabel, + showAndInitOpsRequestType, + disableOpsRequest, + + // Machine profile functions + getMachines, + setMachine, + onMachineChange, + isMachineCustom, + + // Vertical scaling functions + isVerticalScaleTopologyRequired, + setExporter, + onExporterResourceChange, + + // Volume expansion functions + checkVolume, + + // Configuration/Reconfiguration functions + getConfigSecrets, + getSelectedConfigSecret, + getSelectedConfigSecretValue, + createSecretUrl, + isEqualToValueFromType, + ifReconfigurationTypeEqualsTo, + onReconfigurationTypeChange, + onApplyconfigChange, + fetchConfigSecrets, + getConfigSecretsforAppyConfig, + getSelectedConfigurationData, + getSelectedConfigurationName, + getSelectedConfigurationValueForRemove, + createNewConfigSecret, + decodeError, + isCreateSecret, + isNotCreateSecret, + onCreateSecretChange, + cancelCreateSecret, + setApplyConfig, + onRemoveConfigChange, + onNewConfigSecretChange, + onSelectedSecretChange, + + // TLS functions + getDbTls, + hasTlsField, + initIssuerRefApiGroup, + getIssuerRefsName, + initTlsOperation, + onTlsOperationChange, + showIssuerRefAndCertificates, + isIssuerRefRequired, + getAliasOptions, + fetchAliasOptions, + validateNewCertificates, + disableAlias, + + // Resource functions + getNamespacedResourceList, + getResourceList, + resourceNames, + unNamespacedResourceNames, + + // Helper functions + setValueFromDbDetails, + setApplyToIfReady, + hasResourceValue, + hasVolumeExpansion, + isTlsEnabled, + } } diff --git a/charts/opskubedbcom-ferretdbopsrequest-editor/ui/create-ui.yaml b/charts/opskubedbcom-ferretdbopsrequest-editor/ui/create-ui.yaml index dd70c9348a..d5f4b70263 100644 --- a/charts/opskubedbcom-ferretdbopsrequest-editor/ui/create-ui.yaml +++ b/charts/opskubedbcom-ferretdbopsrequest-editor/ui/create-ui.yaml @@ -1,330 +1,465 @@ -steps: -- form: - discriminator: - dbDetails: - type: object +type: multi-step-form +step: + - type: single-step-form + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - schema: - $ref: discriminator#/properties/dbDetails - type: input - - if: showAndInitName - label: - text: labels.op_req_name - required: true - schema: - $ref: schema#/properties/metadata/properties/name - type: input - - computed: initNamespace - disabled: isNamespaceDisabled - fetch: getNamespaces - hasGroup: isRancherManaged - if: showAndInitNamespace - label: - text: labels.namespace - onChange: onNamespaceChange - required: true - schema: - $ref: schema#/properties/metadata/properties/namespace - type: select - - computed: initDatabaseRef - disabled: isDatabaseRefDisabled - fetch: getDbs - if: showAndInitDatabaseRef - label: - text: labels.databaseRef - onChange: onDbChange - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/databaseRef/properties/name - type: select - - if: showConfigureOpsrequestLabel - label: - text: labels.config_ops_request - type: label-element - - computed: getRequestTypeFromRoute - disabled: isDbDetailsLoading - hasDescription: true - if: showAndInitOpsRequestType - individualItemDisabilityCheck: disableOpsRequest - label: - text: labels.ops_request_type - onChange: onRequestTypeChange - options: - - description: options.UpdateVersion.description - text: options.UpdateVersion.text - value: UpdateVersion - - description: options.HorizontalScaling.description - text: options.HorizontalScaling.text - value: HorizontalScaling - - description: options.VerticalScaling.description - text: options.VerticalScaling.text - value: VerticalScaling - - description: options.Restart.description - text: options.Restart.text - value: Restart - - description: options.ReconfigureTLS.description - text: options.ReconfigureTLS.text - value: ReconfigureTLS - schema: - $ref: schema#/properties/spec/properties/type - type: radio - - elements: - - computed: setValueFromDbDetails|/spec/version - fetch: getDbVersions - label: - text: labels.targetVersion - schema: - $ref: schema#/properties/spec/properties/updateVersion/properties/targetVersion - type: select - if: ifRequestTypeEqualsTo|UpdateVersion - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/server/primary/replicas - label: - text: Primary Replicas - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/primary/properties/replicas - type: input - - computed: setValueFromDbDetails|/spec/server/secondary/replicas - if: ferretTypeEqualsTo|secondary - label: - text: Secondary Replicas - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/secondary/properties/replicas - type: input - if: ifRequestTypeEqualsTo|HorizontalScaling - label: - text: Horizontal Scaling Form - type: single-step-form - - elements: - - discriminator: - machine-primary: - default: "" - type: string +# common + - type: input + label: op_req_name + if: + type: function + name: showAndInitName + validation: + type: required + schema: schema/properties/metadata/properties/name + - type: select + label: Namespace + if: + type: function + name: showAndInitNamespace + init: + type: func + value: initNamespace + disable: isNamespaceDisabled + loader: getNamespaces + validation: + type: required + hasGroup: isRancherManaged + schema: schema/properties/metadata/properties/namespace + - type: select + label: Database Ref + if: + type: function + name: showAndInitDatabaseRef + loader: + name: getDbs + watchPaths: + - schema/properties/metadata/properties/namespace + init: + type: func + value: initDatabaseRef + validation: + type: required + disable: isDatabaseRefDisabled + refresh: true + watcher: + func: onDbChange + paths: + - schema/properties/spec/properties/databaseRef/properties/name + schema: schema/properties/spec/properties/databaseRef/properties/name + - type: label-element + label: config_ops_request + if: + type: function + name: showConfigureOpsrequestLabel + - type: radio + label: Type of Ops Request + if: + type: function + name: showAndInitOpsRequestType + 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: Restart your database + text: Restart + value: Restart + - description: Reconfigure your database tls configuration + text: Reconfigure TLS + value: ReconfigureTLS + init: + type: func + value: getRequestTypeFromRoute + disable: isDbDetailsLoading + watcher: + func: isDbDetailsLoading + paths: + - temp/dbDetails + - schema/properties/spec/properties/databaseRef/properties/name + isHorizontal: true + schema: schema/properties/spec/properties/type +# UpdateVersion + - type: block-layout + showLabels: true + label: Version + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|UpdateVersion elements: - - computed: setMachine|primary - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|primary|/spec/server/primary/podTemplate/spec/containers - schema: - $ref: discriminator#/machine-primary - type: select - - if: isMachineCustom|/machine-primary - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/primary/properties/resources - type: resource-input-form - - label: - text: Node Selection Policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/primary/properties/nodeSelectionPolicy - type: select - - elements: - - label: - text: key - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/primary/properties/topology/properties/key - type: input - - label: - text: value - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/primary/properties/topology/properties/value - type: input - label: - text: Topology - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/primary/properties/topology - show_label: true - type: single-step-form - label: - text: Primary - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/primary - show_label: true - type: single-step-form - - discriminator: - machine-secondary: - default: "" - type: string + - type: select-compare + label: Target Version + subtitle: Select the desired FerretDB version to which you want to update your database. + init: + type: func + value: setValueFromDbDetails|/spec/version + loader: getDbVersions + schema: schema/properties/spec/properties/updateVersion/properties/targetVersion + - type: info + label: '' + loader: + name: getVersionInfo + watchPaths: + - temp/properties/filteredVersion + if: + type: function + name: isVersionEmpty +# Horizontal Scale + - type: block-layout + label: Horizontal Scaling Form + showLabels: true + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|HorizontalScaling elements: - - computed: setMachine|secondary - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|secondary|/spec/server/secondary/podTemplate/spec/containers - schema: - $ref: discriminator#/machine-secondary - type: select - - if: isMachineCustom|/machine-secondary - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/secondary/properties/resources - type: resource-input-form - - label: - text: Node Selection Policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/secondary/properties/nodeSelectionPolicy - type: select - - elements: - - label: - text: key - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/secondary/properties/topology/properties/key - type: input - - label: - text: value - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/secondary/properties/topology/properties/value - type: input - label: - text: Topology - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/secondary/properties/topology - show_label: true - type: single-step-form - if: ferretTypeEqualsTo|secondary - label: - text: Secondary - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/secondary - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|VerticalScaling - type: single-step-form - - discriminator: - tlsOperation: - default: update - type: string - elements: - - computed: initTlsOperation - if: hasTlsField - label: - text: labels.tlsOperation - onChange: onTlsOperationChange - options: - - text: Update - value: update - - text: Rotate - value: rotate - - text: Remove - value: remove - schema: - $ref: discriminator#/properties/tlsOperation - type: radio - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/remove - type: switch - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/rotateCertificates - type: switch - - elements: - - computed: initIssuerRefApiGroup - disabled: true - label: - text: labels.api_group - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup - type: input - - computed: setValueFromDbDetails|/spec/tls/issuerRef/kind - label: - text: labels.kind - options: - - text: Issuer - value: Issuer - - text: ClusterIssuer - value: ClusterIssuer - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/kind - sortable: true - type: select - - allowUserDefinedOption: true - computed: setValueFromDbDetails|/spec/tls/issuerRef/name - fetch: getIssuerRefsName - label: - text: labels.name - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/name - sortable: true - type: select - if: showIssuerRefAndCertificates - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef - type: single-step-form - - alias: reusable_certificates - chart: - name: uibytebuildersdev-component-certificates - version: v0.29.0 - computed: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates - functionCallbacks: - getAliasOptions: - $ref: functions#/getAliasOptions - if: showIssuerRefAndCertificates - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/spec/properties/tls/properties/certificates - type: reusable-element - if: ifRequestTypeEqualsTo|ReconfigureTLS - label: - text: labels.tls - schema: - $ref: schema#/properties/spec/properties/tls - type: single-step-form - - label: - text: labels.timeout - options: - - text: 5 minutes - value: 5m - - text: 10 minutes - value: 10m - - text: 30 minutes - value: 30m - - text: 1 hour - value: 1h - - text: 2 hours - value: 2h - - text: 5 hours - value: 5h - - text: 10 hours - value: 10h - schema: - $ref: schema#/properties/spec/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: labels.apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/spec/properties/apply - type: radio - type: single-step-form - id: basic - title: steps.0.label -type: multi-step-form + - type: horizontal-layout + elements: + - type: input-compare + label: Primary Replicas + subtitle: Define the total number of replicas for the database. Increasing replicas improves fault tolerance and load distribution, while reducing replicas conserves resources + init: + type: func + value: setValueFromDbDetails|/spec/server/primary/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/primary/properties/replicas + - type: info + 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: horizontal-layout + elements: + - type: input-compare + label: Secondary Replicas + if: + type: function + name: ferretTypeEqualsTo|secondary + init: + type: func + value: setValueFromDbDetails|/spec/server/secondary/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/secondary/properties/replicas +# vertical Scale + - type: block-layout + if: + type: function + name: ifRequestTypeEqualsTo|VerticalScaling + elements: + - type: block-layout + label: Primary + showLabels: true + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines|primary + init: + type: func + value: setMachine|primary + watcher: + func: onMachineChange|primary|/spec/server/primary/podTemplate/spec/containers + paths: + - temp/properties/machine-primary + schema: temp/properties/machine-primary + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/primary/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|primary + schema: temp/topologyKey-primary + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|primary + schema: temp/topologyValue-primary + - type: block-layout + label: Secondary + showLabels: true + if: + type: function + name: ferretTypeEqualsTo|secondary + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines|secondary + init: + type: func + value: setMachine|secondary + watcher: + func: onMachineChange|secondary|/spec/server/secondary/podTemplate/spec/containers + paths: + - temp/properties/machine-secondary + schema: temp/properties/machine-secondary + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/secondary/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|secondary + schema: temp/topologyKey-secondary + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|secondary + schema: temp/topologyValue-secondary + - type: block-layout + label: Exporter + showLabels: true + hideBlock: true + elements: + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setExporter|cpu + type: input + 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 + watcher: + func: onExporterResourceChange|memory + paths: + - schema/properties/spec/properties/verticalScaling/properties/exporter/properties/resources/properties/limits/properties/memory +# Reconfigure TLS + - type: block-layout + label: TLS + if: + name: ifRequestTypeEqualsTo|ReconfigureTLS + type: function + elements: + - type: radio + label: TLS Operation + if: + name: hasTlsField + type: function + options: + - text: Update + value: update + - text: Rotate + value: rotate + - text: Remove + value: remove + init: + type: func + value: initTlsOperation + schema: temp/properties/tlsOperation + - type: switch + label: Remove TLS + fullwidth: true + if: + name: isTlsEnabled + type: function + schema: schema/properties/spec/properties/tls/properties/remove + - type: switch + label: Rotate Certificates + fullwidth: true + schema: schema/properties/spec/properties/tls/properties/rotateCertificates + if: + name: isTlsEnabled + type: function + - type: block-layout + label: Issuer Reference + showLabels: true + if: + name: showIssuerRefAndCertificates + type: function + elements: + - type: input + label: API Group + init: + type: func + value: initIssuerRefApiGroup + watcher: + func: initIssuerRefApiGroup + paths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + disable: true + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup + - type: select + label: Kind + options: + - text: Issuer + value: Issuer + - text: ClusterIssuer + value: ClusterIssuer + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/kind + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - type: select + label: Name + loader: + name: getIssuerRefsName + watchPaths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - schema/properties/metadata/properties/namespace + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/name + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/name + - type: block-layout + label: Certificates + showLabels: false + if: + name: showIssuerRefAndCertificates + type: function + loader: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates + elements: + - type: array-object-form + label: Certificates + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/tls/properties/certificates + elements: + - type: select + label: Alias + loader: fetchAliasOptions + disable: disableAlias + schema: alias + validation: + type: required + - type: input + label: Secret Name + schema: secretName + - type: input + label: Duration + schema: duration + - type: input + label: Renew Before + schema: renewBefore + - type: array-item-form + label: Organizations + buttonClass: is-light is-outlined + schema: subject/properties/organizations + element: + type: input + label: Organization + - type: array-item-form + label: Countries + buttonClass: is-light is-outlined + schema: subject/properties/countries + element: + type: input + label: Country + - type: array-item-form + label: Organizational Units + buttonClass: is-light is-outlined + schema: subject/properties/organizationalUnits + element: + type: input + label: Organizational Unit + - type: array-item-form + label: Provinces + buttonClass: is-light is-outlined + schema: subject/properties/provinces + element: + type: input + label: Province + - type: array-item-form + label: DNS Names + buttonClass: is-light is-outlined + schema: dnsNames + element: + type: input + label: DNS Name + - type: array-item-form + label: IP Addresses + buttonClass: is-light is-outlined + schema: ipAddresses + element: + type: input + label: IP Address +# common + - type: block-layout + label: OpsRequest Options + showLabels: true + elements: + - type: time-picker + label: Timeout + schema: 'schema/properties/spec/properties/timeout' + subtitle: Specify the maximum time allowed for the scaling operation to complete. Use formats like 30sec, 1min(1 minute) or 2h(2 hours). + - type: radio + label: Apply + schema: 'schema/properties/spec/properties/apply' + init: + type: func + value: setApplyToIfReady + options: + - text: IfReady (OpsRequest will be applied if database is ready) + value: IfReady + - text: Always (OpsRequest will always be applied) + value: Always \ No newline at end of file diff --git a/charts/opskubedbcom-ferretdbopsrequest-editor/ui/functions.js b/charts/opskubedbcom-ferretdbopsrequest-editor/ui/functions.js index 69aa692fe3..86f0ec00c5 100644 --- a/charts/opskubedbcom-ferretdbopsrequest-editor/ui/functions.js +++ b/charts/opskubedbcom-ferretdbopsrequest-editor/ui/functions.js @@ -1,3 +1,4 @@ +const { axios, useOperator, store } = window.vueHelpers || {} const machines = { 'db.t.micro': { resources: { @@ -304,181 +305,265 @@ const machineList = [ 'db.r.24xlarge', ] -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) - } +let machinesFromPreset = [] - return { - ui: ui.data || {}, - language: language.data || {}, - functions, - } -} +export const useFunc = (model) => { + const route = store.state?.route -function returnFalse() { - return false -} - -async function getNamespaces({ axios, storeGet }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + const { getValue, storeGet, discriminator, setDiscriminatorValue, commit } = useOperator( + model, + store.state, + ) - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + showAndInitOpsRequestType() + async function fetchJsons({ axios, itemCtx }) { + let ui = {} + let language = {} + let functions = {} + const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart - const resources = (resp && resp.data && resp.data.items) || [] + 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 resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' return { - text: name, - value: name, + ui: ui.data || {}, + language: language.data || {}, + functions, } - }) -} + } -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + 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 + ) + } -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/namespace') + 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/kubedb.com/v1alpha2/namespaces/${namespace}/ferretdbs`, - { + 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) || [] + const resources = (resp && resp.data && resp.data.items) || [] - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -async function getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) { - 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') + async function getDbs() { + if (storeGet('/route/params/actions')) return [] + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - if (namespace && name) { - const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/ferretdbs/${name}` - const resp = await axios.get(url) + const namespace = getValue(model, '/metadata/namespace') + // watchDependency('model#/metadata/namespace') - setDiscriminatorValue('/dbDetails', resp.data || {}) + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/ferretdbs`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) - return resp.data || {} - } else return {} -} + const resources = (resp && resp.data && resp.data.items) || [] -async function getDbVersions({ axios, storeGet, getValue, discriminator }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 url = `/clusters/${owner}/${cluster}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/kubedb-ui-presets` + 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}/ferretdbs/${name}` + const resp = await axios.get(url) - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + 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 { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + presetVersions = presets.admin?.databases?.FerretDB?.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/ferretdbversions`, + { + 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 allowed = found?.spec?.updateConstraints?.allowlist || [] + 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 filteredDbVersions = 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.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.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.includes(item.metadata?.name)) && + isVersionWithinConstraints(item.spec?.version, limit) + ) + }) + setDiscriminatorValue('/filteredVersion', filteredDbVersions) + return filteredDbVersions.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) - presets.status = String(e.status) + return [] } } - try { - const presetVersions = presets.admin?.databases?.FerretDB?.versions?.available || [] - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null, updateConstraints: null }, - }, - }, + 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 + } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/catalog.kubedb.com/v1alpha1/ferretdbversions`, - { - params: queryParams, - }, - ) + 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 + } - const resources = (resp && resp.data && resp.data.items) || [] + 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: [ ' - 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 allowed = found?.spec?.updateConstraints?.allowlist || [] - 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 filteredFerretDBVersions = 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.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.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.includes(item.metadata?.name)) && - isVersionWithinConstraints(item.spec?.version, limit) - ) + presetVersions.forEach((v, idx) => { + txt = `${txt}"${v}"` + if (idx !== presetVersions.length - 1) txt = txt + ', ' + else txt = txt + ' ]' }) - return filteredFerretDBVersions.map((item) => { + return txt + } + + function getVersion() { + return filteredVersion.map((item) => { const name = (item.metadata && item.metadata.name) || '' const specVersion = (item.spec && item.spec.version) || '' return { @@ -486,747 +571,757 @@ async function getDbVersions({ axios, storeGet, getValue, discriminator }) { value: name, } }) - } catch (e) { - console.log(e) - return [] } -} -function versionCompare(v1, v2) { - const arr1 = v1.split('.').map(Number) - const arr2 = v2.split('.').map(Number) + function isVersionEmpty() { + const val = getValue(discriminator, '/filteredVersion') + return val.length === 0 + } - for (let i = 0; i < Math.max(arr1.length, arr2.length); i++) { - const num1 = arr1[i] || 0 - const num2 = arr2[i] || 0 + function ifRequestTypeEqualsTo(type) { + const selectedType = getValue(model, '/spec/type') + // watchDependency('model#/spec/type') - if (num1 > num2) return 1 // v1 is higher - if (num1 < num2) return -1 // v2 is higher + return selectedType === type } - 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 + 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]}`) + }) } - return true -} -function ifRequestTypeEqualsTo({ model, getValue, watchDependency }, type) { - const selectedType = getValue(model, '/spec/type') - watchDependency('model#/spec/type') + function getDbTls() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') - return selectedType === type -} + const { spec } = dbDetails || {} + return spec?.tls || undefined + } -function onRequestTypeChange({ model, getValue, commit }) { - const selectedType = getValue(model, '/spec/type') - const reqTypeMapping = { - Upgrade: 'updateVersion', - UpdateVersion: 'updateVersion', - HorizontalScaling: 'horizontalScaling', - VerticalScaling: 'verticalScaling', - VolumeExpansion: 'volumeExpansion', - Restart: 'restart', - Reconfigure: 'configuration', - ReconfigureTLS: 'tls', + function getDbType() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') + const { spec } = dbDetails || {} + const { topology } = spec || {} + if (topology) return 'Topology' + else return 'Combined' } - Object.keys(reqTypeMapping).forEach((key) => { - if (key !== selectedType) commit('wizard/model$delete', `/spec/${reqTypeMapping[key]}`) - }) -} + function disableOpsRequest() { + if (itemCtx.value === 'HorizontalScaling') { + const dbType = getDbType({ + discriminator, + getValue, + }) -function disableOpsRequest({ itemCtx, discriminator, getValue, watchDependency }) { - if (itemCtx.value === 'HorizontalScaling') { - const dbType = getDbType({ - discriminator, - getValue, - watchDependency, - }) + if (dbType === 'Standalone') return true + else return false + } else return false + } - if (dbType === 'Standalone') return true - else return false - } else return false -} + function initNamespace() { + const { namespace } = route.query || {} + return namespace || null + } -function getDbTls({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + function initDatabaseRef() { + // watchDependency('model#/metadata/namespace') + const { name } = route.params || {} + return name + } - const { spec } = dbDetails || {} - return spec?.tls || undefined -} + function asDatabaseOperation() { + return !!route.params.actions + } -function getDbType({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') - const { spec } = dbDetails || {} - const { topology } = spec || {} - if (topology) return 'Topology' - else return 'Combined' -} + function generateOpsRequestNameForClusterUI(getValue, model, route) { + const dbName = getValue(model, '/spec/databaseRef/name') -function initNamespace({ route }) { - const { namespace } = route.query || {} - return namespace || null -} + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' -function initDatabaseRef({ route, watchDependency }) { - watchDependency('model#/metadata/namespace') - const { name } = route.params || {} - return name -} + const resources = route.params.resource || '' + const resource = resources.slice(0, -1) -function asDatabaseOperation(route) { - return !!route.params.actions -} + const opsName = dbName ? dbName : resource + return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` + } -function generateOpsRequestNameForClusterUI(getValue, model, route) { - const dbName = getValue(model, '/spec/databaseRef/name') + 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() : '' + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' - const resources = route.params.resource || '' - const resource = resources.slice(0, -1) + 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 + } - const opsName = dbName ? dbName : resource - return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` -} + function showAndInitNamespace() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/metadata/namespace', + value: `${route.query.namespace}`, + force: true, + }) + } -function showAndInitName({ route, commit, getValue, model, watchDependency }) { - watchDependency('model#/spec/type') - watchDependency('model#/spec/databaseRef/name') - const ver = asDatabaseOperation(route) + return !ver + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + function showAndInitDatabaseRef() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/spec/databaseRef/name', + value: `${route.params.name}`, + force: true, + }) + } - 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({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/metadata/namespace', - value: `${route.query.namespace}`, - force: true, - }) + return !ver } - return !ver -} -function showAndInitDatabaseRef({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/spec/databaseRef/name', - value: `${route.params.name}`, - force: true, - }) + function showConfigureOpsrequestLabel() { + return !asDatabaseOperation() } - return !ver -} -function showConfigureOpsrequestLabel({ route }) { - return !asDatabaseOperation(route) -} -function showAndInitOpsRequestType({ route, commit }) { - const ver = asDatabaseOperation(route) - const opMap = { - upgrade: 'UpdateVersion', - updateVersion: 'UpdateVersion', - horizontalscaling: 'HorizontalScaling', - verticalscaling: 'VerticalScaling', - volumeexpansion: 'VolumeExpansion', - restart: 'Restart', - reconfiguretls: 'ReconfigureTLS', - reconfigure: 'Reconfigure', - } - if (ver) { - const operation = route.params.actions - const match = /^(.*)-opsrequest-(.*)$/.exec(operation) - const opstype = match[2] - commit('wizard/model$update', { - path: '/spec/type', - value: opMap[opstype], - force: true, - }) - } + 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 -} + return !ver + } -// vertical scaling -function ifDbTypeEqualsTo({ discriminator, getValue, watchDependency, commit }, value, opsReqType) { - const verd = getDbType({ - discriminator, - getValue, - watchDependency, - }) - return value === verd -} + // vertical scaling + function ifDbTypeEqualsTo(value, opsReqType) { + const verd = getDbType() -// machine profile stuffs -let machinesFromPreset = [] + return value === verd + } -function getMachines({ storeGet }) { - const presets = storeGet('/kubedbuiPresets') || {} - const avlMachines = presets.admin?.machineProfiles?.available || [] - let arr = [] - if (avlMachines.length) { - arr = avlMachines.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - 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 } - } else return { text: machine, value: machine } - } - }) - } else { - arr = machineList - .map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } - }) - .filter((val) => !!val) + function ferretTypeEqualsTo(param) { + const dbDetails = getValue(discriminator, '/dbDetails') + const type = dbDetails.spec?.server?.secondary ? 'secondary' : 'primary' + return param === type } - return arr -} -function setMachine({ getValue, discriminator, storeGet }, type) { - const dbDetails = getValue(discriminator, '/dbDetails') - 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 = {} + // machine profile stuffs + // let machinesFromPreset = [] + + function getMachines(type) { + const presets = storeGet('/kubedbuiPresets') || {} + const dbDetails = getValue(discriminator, '/dbDetails') + // const limits = dbDetails?.spec?.podTemplate?.spec?.resources?.limits || {} + const limits = + dbDetails?.spec?.server?.[type]?.podTemplate?.spec?.containers?.[0]?.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 } - const machine = parsedInstance[type] || 'custom' - machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] + function setMachine(type) { + const dbDetails = getValue(discriminator, '/dbDetails') + // const limits = dbDetails?.spec?.podTemplate?.spec?.resources?.limits || {} + const limits = + dbDetails?.spec?.server?.[type]?.podTemplate?.spec?.containers?.[0]?.resources?.requests - const machinePresets = machinesFromPreset.find((item) => item.id === machine) - if (machinePresets) return machine - else return 'custom' -} + 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 = {} + } + const machine = parsedInstance[type] || 'custom' -function onMachineChange({ getValue, discriminator, commit, model }, type, valPath) { - let selectedMachine = '' - selectedMachine = getValue(discriminator, `/machine-${type}`) - const machine = machinesFromPreset.find((item) => item.id === selectedMachine) - - let obj = {} - if (selectedMachine !== 'custom') { - if (machine) obj = { limits: { ...machine?.limits }, requests: { ...machine?.limits } } - else obj = machines[selectedMachine]?.resources - } else { - const val = getValue(discriminator, `/dbDetails${valPath}`) || {} - obj = Array.isArray(val) ? val[0]?.resources : { ...val } + 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 } } - const path = `/spec/verticalScaling/${type}/resources` + function onMachineChange(type, valPath) { + let selectedMachine = {} + selectedMachine = getValue(discriminator, `/machine-${type}`) + 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 }, + } + } - if (obj && Object.keys(obj).length) - commit('wizard/model$update', { - path: path, - value: obj, - force: true, - }) + 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') || {} + const instance = annotations['kubernetes.io/instance-type'] + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = {} + } + parsedInstance[type] = selectedMachine.machine + annotations['kubernetes.io/instance-type'] = JSON.stringify(parsedInstance) + + if (machinesFromPreset.length) + commit('wizard/model$update', { + path: '/metadata/annotations', + value: annotations, + force: true, + }) - // update metadata.annotations - const annotations = getValue(model, '/metadata/annotations') || {} - const instance = annotations['kubernetes.io/instance-type'] - let parsedInstance = {} - try { - if (instance) parsedInstance = JSON.parse(instance) - } catch (e) { - console.log(e) - parsedInstance = {} + if (parsedInstance && Object.keys(parsedInstance).length === 0) + commit('wizard/model$delete', '/metadata/annotations') } - if (selectedMachine === 'custom') delete parsedInstance[type] - else parsedInstance[type] = selectedMachine - annotations['kubernetes.io/instance-type'] = JSON.stringify(parsedInstance) - - if (machinesFromPreset.length) - commit('wizard/model$update', { - path: '/metadata/annotations', - value: annotations, - force: true, - }) - if (parsedInstance && Object.keys(parsedInstance).length === 0) - commit('wizard/model$delete', '/metadata/annotations') -} + function isMachineCustom(path) { + // watchDependency(`discriminator#${path}`) + const machine = getValue(discriminator, `${path}`) + return machine === 'custom' + } -function isMachineCustom({ watchDependency, getValue, discriminator }, path) { - watchDependency(`discriminator#${path}`) - const machine = getValue(discriminator, `${path}`) - return machine === 'custom' -} + // for config secret + async function getConfigSecrets() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/namespace') + // watchDependency('model#/metadata/namespace') -function ferretTypeEqualsTo({ getValue, discriminator }, param) { - const dbDetails = getValue(discriminator, '/dbDetails') - const type = dbDetails.spec?.server?.secondary ? 'secondary' : 'primary' - return param === type -} + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + ) -// for config secret -async function getConfigSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + const secrets = (resp && resp.data && resp.data.items) || [] - const secrets = (resp && resp.data && resp.data.items) || [] + const filteredSecrets = secrets - const filteredSecrets = secrets + filteredSecrets.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true + }) + return filteredSecrets + } - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return filteredSecrets -} + function createSecretUrl() { + const user = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function createSecretUrl({ storeGet }) { - 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` + } + } - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/secrets/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/secrets/create` + function isEqualToValueFromType(value) { + // watchDependency('discriminator#/valueFromType') + const valueFrom = getValue(discriminator, '/valueFromType') + return valueFrom === value } -} -function isEqualToValueFromType({ discriminator, getValue, watchDependency }, 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') -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}` - 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 } }, + }, + }) - 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) + } - 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') - return ans -} -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` - 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 } }, + }, + }) - 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) + } - 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, + }) - return ans -} -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - group, - version, - resource, -) { - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/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) + 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, + }) - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) } - }) -} -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - 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, + } }) } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + // for tls + function hasTlsField() { + const tls = getDbTls() -// for tls -function hasTlsField({ discriminator, getValue, watchDependency }) { - const tls = getDbTls({ - discriminator, - getValue, - watchDependency, - }) + return !!tls + } - return !!tls -} + function initIssuerRefApiGroup() { + const kind = getValue(model, '/spec/tls/issuerRef/kind') + // watchDependency('model#/spec/tls/issuerRef/kind') -function initIssuerRefApiGroup({ getValue, model, watchDependency, discriminator }) { - const kind = getValue(model, '/spec/tls/issuerRef/kind') - watchDependency('model#/spec/tls/issuerRef/kind') + if (kind) { + return 'cert-manager.io' + } else return undefined + } - 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') -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - 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` + 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 [] + } - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + async function getIssuer(url) { try { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + 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) - presets.status = String(e.status) + return [] } } - 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 } - async function getIssuer(url) { - try { - const resp = await axios.get(url) - const resources = (resp && resp.data && resp.data.items) || [] + function initTlsOperation() { + return 'update' + } + function onTlsOperationChange() { + const tlsOperation = getValue(discriminator, '/tlsOperation') - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + commit('wizard/model$delete', '/spec/tls') + + if (tlsOperation === 'rotate') { + commit('wizard/model$update', { + path: '/spec/tls/rotateCertificates', + value: true, + force: true, + }) + } else if (tlsOperation === 'remove') { + commit('wizard/model$update', { + path: '/spec/tls/remove', + value: true, + force: true, }) - return resources - } catch (e) { - console.log(e) - return [] } } -} -function initTlsOperation() { - return 'update' -} -function onTlsOperationChange({ discriminator, getValue, commit }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + function showIssuerRefAndCertificates() { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // watchDependency('discriminator#/tlsOperation') + const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' - commit('wizard/model$delete', '/spec/tls') + return verd + } - 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 isIssuerRefRequired() { + const hasTls = hasTlsField() + return hasTls ? false : '' } -} -function showIssuerRefAndCertificates({ discriminator, getValue, watchDependency }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') - watchDependency('discriminator#/tlsOperation') - const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' + function getRequestTypeFromRoute() { + const isDbloading = isDbDetailsLoading() + const { query } = route || {} + const { requestType } = query || {} + return isDbloading ? '' : requestType || '' + } - return verd -} + function isDbDetailsLoading() { + // watchDependency('discriminator#/dbDetails') + // watchDependency('model#/spec/databaseRef/name') + const dbDetails = getValue(discriminator, '/dbDetails') + const dbName = getValue(model, '/spec/databaseRef/name') -function isIssuerRefRequired({ discriminator, getValue, watchDependency }) { - const hasTls = hasTlsField({ - discriminator, - getValue, - watchDependency, - }) + return !dbDetails || !dbName + } - return !hasTls -} + function setValueFromDbDetails(path, commitPath) { + const retValue = getValue(discriminator, `/dbDetails${path}`) -function getRequestTypeFromRoute({ route, model, discriminator, getValue, watchDependency }) { - const isDbloading = isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) - const { query } = route || {} - const { requestType } = query || {} - return isDbloading ? '' : requestType || '' -} + if (commitPath) { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // computed called when tls fields is not visible + if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined -// ************************************** Set db details ***************************************** - -function isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - watchDependency('model#/spec/databaseRef/name') - const dbDetails = getValue(discriminator, '/dbDetails') - const dbName = getValue(model, '/spec/databaseRef/name') + // 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 + } - return !dbDetails || !dbName -} + function getAliasOptions() { + return ['server', 'client', 'metrics-exporter'] + } -function setValueFromDbDetails( - { discriminator, getValue, watchDependency, commit }, - path, - commitPath, -) { - watchDependency('discriminator#/dbDetails') + function isNamespaceDisabled() { + const { namespace } = route.query || {} + return !!namespace + } - const retValue = getValue(discriminator, `/dbDetails${path}`) + function isDatabaseRefDisabled() { + const { name } = route.params || {} + return !!name + } - if (commitPath && retValue) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + function onNamespaceChange() { + commit('wizard/model$delete', '/spec/type') + } - // computed called when tls fields is not visible - if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined + function onDbChange() { + commit('wizard/model$delete', '/spec/type') + getDbDetails() + } - // 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, - }) + function setApplyToIfReady() { + return 'IfReady' } - return retValue || undefined -} + function isVerticalScaleTopologyRequired(type) { + // watchDependency(`discriminator#/topologyKey-${type}`) + // watchDependency(`discriminator#/topologyValue-${type}`) -function setResource({ discriminator, getValue, watchDependency }, path) { - watchDependency('discriminator#/dbDetails') - const containers = getValue(discriminator, `/dbDetails${path}`) || [] - const kind = getValue(discriminator, '/dbDetails/kind') - const resource = containers.filter((ele) => ele.name === kind.toLowerCase()) - return resource[0].resources -} + const key = getValue(discriminator, `/topologyKey-${type}`) + const value = getValue(discriminator, `/topologyValue-${type}`) + const path = `/spec/verticalScaling/${type}/topology` -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} + if (key || value) { + commit('wizard/model$update', { + path: path, + value: { key, value }, + force: true, + }) + return '' + } else { + commit('wizard/model$delete', path) + return false + } + } -function isNamespaceDisabled({ route }) { - const { namespace } = route.query || {} - return !!namespace -} + function fetchAliasOptions() { + return getAliasOptions ? getAliasOptions() : [] + } -function isDatabaseRefDisabled({ route }) { - const { name } = route.params || {} - return !!name -} + function validateNewCertificates({ itemCtx }) { + const addedAliases = (model && model.map((item) => item.alias)) || [] -function onNamespaceChange({ commit }) { - commit('wizard/model$delete', '/spec/type') -} + if (addedAliases.includes(itemCtx.alias) && itemCtx.isCreate) { + return { isInvalid: true, message: 'Alias already exists' } + } + return {} + } -function onDbChange({ commit, axios, storeGet, model, getValue, setDiscriminatorValue }) { - commit('wizard/model$delete', '/spec/type') - getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) -} + function disableAlias() { + return !!(model && model.alias) + } -function setApplyToIfReady() { - return 'IfReady' -} + function setExporter(type) { + let path = `/dbDetails/spec/monitor/prometheus/exporter/resources/limits/${type}` + const limitVal = getValue(discriminator, path) -function isVerticalScaleTopologyRequired({ watchDependency, getValue, discriminator, commit }) { - watchDependency('discriminator#/topologyKey') - watchDependency('discriminator#/topologyValue') + if (!limitVal) { + path = `/dbDetails/spec/monitor/prometheus/exporter/resources/requests/${type}` + const reqVal = getValue(discriminator, path) - const key = getValue(discriminator, '/topologyKey') - const value = getValue(discriminator, '/topologyValue') - const path = `/spec/verticalScaling/ferretdb/topology` + if (reqVal) return reqVal + } + return limitVal + } - if (key || value) { - commit('wizard/model$update', { - path: path, - value: { key, value }, - force: true, - }) - return true - } else { - commit('wizard/model$delete', path) - return false + 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, + }) } -} -return { - isRancherManaged, - setResource, - fetchJsons, - returnFalse, - getNamespaces, - getDbs, - getDbDetails, - getDbVersions, - ifRequestTypeEqualsTo, - onRequestTypeChange, - getDbTls, - getDbType, - initNamespace, - initDatabaseRef, - - showAndInitName, - showAndInitNamespace, - showAndInitDatabaseRef, - showConfigureOpsrequestLabel, - showAndInitOpsRequestType, - - ifDbTypeEqualsTo, - getConfigSecrets, - createSecretUrl, - isEqualToValueFromType, - disableOpsRequest, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - hasTlsField, - initIssuerRefApiGroup, - getIssuerRefsName, - initTlsOperation, - onTlsOperationChange, - showIssuerRefAndCertificates, - isIssuerRefRequired, - getRequestTypeFromRoute, - isDbDetailsLoading, - setValueFromDbDetails, - getAliasOptions, - isNamespaceDisabled, - isDatabaseRefDisabled, - onNamespaceChange, - onDbChange, - setApplyToIfReady, - isVerticalScaleTopologyRequired, - getMachines, - setMachine, - onMachineChange, - isMachineCustom, - ferretTypeEqualsTo, + return { + 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, + ferretTypeEqualsTo, + getConfigSecrets, + createSecretUrl, + isEqualToValueFromType, + getNamespacedResourceList, + getResourceList, + resourceNames, + unNamespacedResourceNames, + hasTlsField, + initIssuerRefApiGroup, + getIssuerRefsName, + initTlsOperation, + onTlsOperationChange, + showIssuerRefAndCertificates, + isIssuerRefRequired, + getRequestTypeFromRoute, + isDbDetailsLoading, + setValueFromDbDetails, + getAliasOptions, + isNamespaceDisabled, + isDatabaseRefDisabled, + onDbChange, + onNamespaceChange, + setApplyToIfReady, + isVerticalScaleTopologyRequired, + getMachines, + setMachine, + onMachineChange, + isMachineCustom, + isTlsEnabled, + } } diff --git a/charts/opskubedbcom-kafkaopsrequest-editor/ui/create-ui.yaml b/charts/opskubedbcom-kafkaopsrequest-editor/ui/create-ui.yaml index 11e895a179..3a81f5d2c8 100644 --- a/charts/opskubedbcom-kafkaopsrequest-editor/ui/create-ui.yaml +++ b/charts/opskubedbcom-kafkaopsrequest-editor/ui/create-ui.yaml @@ -1,563 +1,798 @@ -steps: -- form: - discriminator: - dbDetails: - type: object +type: multi-step-form +step: + - type: single-step-form + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - schema: - $ref: discriminator#/properties/dbDetails - type: input - - if: showAndInitName - label: - text: labels.op_req_name - required: true - schema: - $ref: schema#/properties/metadata/properties/name - type: input - - computed: initNamespace - disabled: isNamespaceDisabled - fetch: getNamespaces - hasGroup: isRancherManaged - if: showAndInitNamespace - label: - text: labels.namespace - onChange: onNamespaceChange - required: true - schema: - $ref: schema#/properties/metadata/properties/namespace - type: select - - computed: initDatabaseRef - disabled: isDatabaseRefDisabled - fetch: getDbs - if: showAndInitDatabaseRef - label: - text: labels.databaseRef - onChange: onDbChange - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/databaseRef/properties/name - type: select - - if: showConfigureOpsrequestLabel - label: - text: labels.config_ops_request - type: label-element - - computed: getRequestTypeFromRoute - disabled: isDbDetailsLoading - hasDescription: true - if: showAndInitOpsRequestType - individualItemDisabilityCheck: disableOpsRequest - label: - text: labels.ops_request_type - onChange: onRequestTypeChange - options: - - description: options.UpdateVersion.description - text: options.UpdateVersion.text - value: UpdateVersion - - description: options.HorizontalScaling.description - text: options.HorizontalScaling.text - value: HorizontalScaling - - description: options.VerticalScaling.description - text: options.VerticalScaling.text - value: VerticalScaling - - description: options.VolumeExpansion.description - text: options.VolumeExpansion.text - value: VolumeExpansion - - description: options.Restart.description - text: options.Restart.text - value: Restart - - description: options.Reconfigure.description - text: options.Reconfigure.text - value: Reconfigure - - description: options.ReconfigureTLS.description - text: options.ReconfigureTLS.text - value: ReconfigureTLS - schema: - $ref: schema#/properties/spec/properties/type - type: radio - - elements: - - computed: setValueFromDbDetails|/spec/version - fetch: getDbVersions - label: - text: labels.targetVersion - schema: - $ref: schema#/properties/spec/properties/updateVersion/properties/targetVersion - type: select - if: ifRequestTypeEqualsTo|UpdateVersion - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/replicas - if: ifDbTypeEqualsTo|Combined|horizontalScaling - label: - text: Node - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/node - type: input - - elements: - - computed: setValueFromDbDetails|/spec/topology/broker/replicas - label: - text: Broker - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/topology/properties/broker - type: input - - computed: setValueFromDbDetails|/spec/topology/controller/replicas - label: - text: Controller - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/topology/properties/controller - type: input - if: ifDbTypeEqualsTo|Topology|horizontalScaling - label: - text: Topology - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/topology - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|HorizontalScaling - label: - text: Horizontal Scaling Form - type: single-step-form - - elements: - - discriminator: - machine-broker: - default: "" - type: string +# common + - type: input + label: op_req_name + if: + type: function + name: showAndInitName + validation: + type: required + schema: schema/properties/metadata/properties/name + - type: select + label: Namespace + if: + type: function + name: showAndInitNamespace + init: + type: func + value: initNamespace + disable: isNamespaceDisabled + loader: getNamespaces + validation: + type: required + hasGroup: isRancherManaged + schema: schema/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/metadata/properties/namespace + - type: select + label: Database Ref + if: + type: function + name: showAndInitDatabaseRef + loader: + name: getDbs + watchPaths: + - schema/properties/metadata/properties/namespace + init: + type: func + value: initDatabaseRef + validation: + type: required + disable: isDatabaseRefDisabled + refresh: true + watcher: + paths: + - schema/properties/spec/properties/databaseRef/properties/name + func: onDbChange + schema: schema/properties/spec/properties/databaseRef/properties/name + - type: label-element + label: config_ops_request + if: + type: function + name: showConfigureOpsrequestLabel + - type: radio + label: Type of Ops Request + if: + type: function + name: showAndInitOpsRequestType + 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 + init: + type: func + value: getRequestTypeFromRoute + disable: isDbDetailsLoading + watcher: + func: onRequestTypeChange + paths: + - schema/properties/spec/properties/type + isHorizontal: true + schema: schema/properties/spec/properties/type +# UpdateVersion + - type: block-layout + showLabels: true + label: Version + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|UpdateVersion elements: - - computed: setMachine|broker - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|broker|/spec/topology/broker/resources - schema: - $ref: discriminator#/machine-broker - type: select - - if: isMachineCustom|/machine-broker - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/broker/properties/resources - type: resource-input-form - - label: - text: Node Selection Policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/broker/properties/nodeSelectionPolicy - type: select - - elements: - - label: - text: key - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/broker/properties/topology/properties/key - type: input - - label: - text: value - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/broker/properties/topology/properties/value - type: input - label: - text: Topology - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/broker/properties/topology - show_label: true - type: single-step-form - if: ifDbTypeEqualsTo|Topology|VerticalScaling - label: - text: Broker - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/broker - show_label: true - type: single-step-form - - discriminator: - machine-controller: - default: "" - type: string + - type: select-compare + label: Target Version + subtitle: Select the desired Kafka version to which you want to update your database. + init: + type: func + value: setValueFromDbDetails|/spec/version + loader: getDbVersions + schema: schema/properties/spec/properties/updateVersion/properties/targetVersion + - type: info + label: '' + loader: + name: getVersionInfo + watchPaths: + - temp/properties/filteredVersion + if: + type: function + name: isVersionEmpty +# Horizontal Scale + - type: block-layout + label: Horizontal Scaling Form + showLabels: true + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|HorizontalScaling elements: - - computed: setMachine|controller - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|controller|/spec/topology/controller/resources - schema: - $ref: discriminator#/machine-controller - type: select - - if: isMachineCustom|/machine-controller - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/controller/properties/resources - type: resource-input-form - - label: - text: Node Selection Policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/controller/properties/nodeSelectionPolicy - type: select - - elements: - - label: - text: key - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/controller/properties/topology/properties/key - type: input - - label: - text: value - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/controller/properties/topology/properties/value - type: input - label: - text: Topology - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/controller/properties/topology - show_label: true - type: single-step-form - if: ifDbTypeEqualsTo|Topology|VerticalScaling - label: - text: Controller - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/controller - show_label: true - type: single-step-form - - discriminator: - machine-node: - default: "" - type: string + - type: input-compare + header: Node + subtitle: How many replicas do you want for your database? Specify the replica count to balance performance and resource usage + label: Node + if: + type: function + name: ifDbTypeEqualsTo|Combined|horizontalScaling + init: + type: func + value: setValueFromDbDetails|/spec/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/node + - type: block-layout + label: Topology horizontal scaling + if: + name: ifDbTypeEqualsTo|Topology|horizontalScaling + type: function + elements: + - type: input-compare + label: Broker + subtitle: How many replicas do you want for your database? Specify the replica count to balance performance and resource usage + schema: schema/properties/spec/properties/horizontalScaling/properties/topology/properties/broker + init: + type: func + value: setValueFromDbDetails|/spec/topology/broker/replicas + - type: input-compare + label: Controller + subtitle: How many replicas do you want for your database? Specify the replica count to balance performance and resource usage + init: + type: func + value: setValueFromDbDetails|/spec/topology/controller/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/topology/properties/controller +# vertical Scale + - type: block-layout + if: + type: function + name: ifRequestTypeEqualsTo|VerticalScaling elements: - - computed: setMachine|node - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|node|/spec/podTemplate/spec/containers - schema: - $ref: discriminator#/machine-node - type: select - - if: isMachineCustom|/machine-node - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/resources - type: resource-input-form - - label: - text: Node Selection Policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/nodeSelectionPolicy - type: select - - elements: - - label: - text: key - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/topology/properties/key - type: input - - label: - text: value - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/topology/properties/value - type: input - label: - text: Topology - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/topology - show_label: true - type: single-step-form - if: ifDbTypeEqualsTo|Combined|VerticalScaling - label: - text: Node - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|VerticalScaling - type: single-step-form - - elements: - - elements: - - computed: setValueFromDbDetails|/spec/topology/broker/storage/resources/requests/storage - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/broker - type: input - validationRuleObject: - func: checkVolume|/spec/topology/broker/storage/resources/requests/storage|/spec/volumeExpansion/broker - if: ifDbTypeEqualsTo|Topology|VolumeExpansion - label: - text: Broker - show_label: true - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/topology/controller/storage/resources/requests/storage - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/controller - type: input - validationRuleObject: - func: checkVolume|/spec/topology/controller/storage/resources/requests/storage|/spec/volumeExpansion/controller - if: ifDbTypeEqualsTo|Topology|VolumeExpansion - label: - text: Controller - show_label: true - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/storage/resources/requests/storage - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/node - type: input - validationRuleObject: - func: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/node - if: ifDbTypeEqualsTo|Combined|VolumeExpansion - label: - text: Node - schema: - $ref: schema#/properties/spec/properties/volumeExpansion - show_label: true - type: single-step-form - - label: - text: Mode - options: - - text: Offline - value: Offline - - text: Online - value: Online - required: true - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/mode - type: select - if: ifRequestTypeEqualsTo|VolumeExpansion - label: - text: Volume Expansion Form - type: single-step-form - - elements: - - discriminator: - reconfigurationType: - type: string + - type: block-layout + label: Combined Vertical Scaling + showLabels: false + if: + type: function + name: ifDbTypeEqualsTo|Combined|verticalScaling + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines|node + init: + type: func + value: setMachine|node + watcher: + func: onMachineChange|node|/spec/podTemplate/spec/containers + paths: + - temp/properties/machine-node + schema: temp/properties/machine-node + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/node/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|node + schema: temp/topologyKey-node + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|node + schema: temp/topologyValue-node + - type: block-layout + if: + type: function + name: ifDbTypeEqualsTo|Topology|verticalScaling + label: Topology Vertical Scaling + showLabels: false + elements: + - type: block-layout + label: Broker Vertical Scaling + showLabels: true + elements: + - type: machine-compare + label: Resources + loader: getMachines|broker + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + init: + type: func + value: setMachine|broker + watcher: + func: onMachineChange|broker|/spec/topology/broker/resources + paths: + - temp/properties/machine-broker + schema: temp/properties/machine-broker + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/broker/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + label: " Label Selector: Specify key-value pairs to target nodes that match your workload's requirements.
Taint: Define tolerations for node traints to ensure your workload runs only on compatible nodes" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|broker + schema: temp/topologyKey-broker + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|broker + schema: temp/topologyValue-broker + - type: block-layout + label: Controller Vertical Scaling + showLabels: true + elements: + - type: machine-compare + label: Resources + loader: getMachines|controller + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + init: + type: func + value: setMachine|controller + watcher: + func: onMachineChange|controller|/spec/topology/controller/resources + paths: + - temp/properties/machine-controller + schema: temp/properties/machine-controller + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/controller/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + label: " Label Selector: Specify key-value pairs to target nodes that match your workload's requirements.
Taint: Define tolerations for node traints to ensure your workload runs only on compatible nodes" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|controller + schema: temp/topologyKey-controller + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|controller + schema: temp/topologyValue-controller + - type: block-layout + label: Exporter + showLabels: true + hideBlock: true + elements: + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setExporter|cpu + type: input + 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 + watcher: + func: onExporterResourceChange|memory + paths: + - schema/properties/spec/properties/verticalScaling/properties/exporter/properties/resources/properties/limits/properties/memory +# Volume Expansion + - type: block-layout + label: Volume Expansion Form + if: + type: function + name: ifRequestTypeEqualsTo|VolumeExpansion elements: - - label: - text: labels.reconfigurationType - onChange: onReconfigurationTypeChange - options: - - text: Select New Config Secret - value: selectNewConfigSecret - - text: Apply Config - value: applyConfig - - text: Remove - value: remove - required: true - schema: - $ref: discriminator#/properties/reconfigurationType - type: radio - - elements: - - add_new_button: - label: labels.createConfig - target: _blank - url: - function: createSecretUrl - computed: setValueFromDbDetails|/spec/configSecret/name - fetch: getConfigSecrets - label: - text: labels.configSecret - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret/properties/name - type: select - if: ifReconfigurationTypeEqualsTo|selectNewConfigSecret - label: - text: Configuration config secret - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret - type: single-step-form - - addFormLabel: labels.applyConfig.label - element: - discriminator: - configArray: - emitAs: applyConfig - type: array + - type: horizontal-layout elements: - - label: - text: labels.applyConfig.key - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/key - type: input - - label: - text: labels.applyConfig.value - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/value - type: editor - type: single-step-form - if: ifReconfigurationTypeEqualsTo|applyConfig - label: - text: labels.applyConfig.label - onChange: onApplyconfigChange - required: true - schema: - $ref: discriminator#/properties/applyConfig - tableContents: - - inTableColumn: true - label: - text: labels.applyConfig.key - path: key - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.applyConfig.value - path: value - type: value - typeOfValue: code - type: single-step-form-array - - if: returnFalse - label: - text: labels.removeCustomConfig - schema: - $ref: schema#/properties/spec/properties/configuration/properties/removeCustomConfig - type: switch - label: - text: labels.configuration - schema: - $ref: schema#/properties/spec/properties/configuration - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|Reconfigure - label: - text: Reconfigure Form - type: single-step-form - - discriminator: - tlsOperation: - default: update - type: string - elements: - - computed: initTlsOperation - if: hasTlsField - label: - text: labels.tlsOperation - onChange: onTlsOperationChange - options: - - text: Update - value: update - - text: Rotate - value: rotate - - text: Remove - value: remove - schema: - $ref: discriminator#/properties/tlsOperation - type: radio - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/remove - type: switch - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/rotateCertificates - type: switch - - elements: - - computed: initIssuerRefApiGroup - disabled: true - label: - text: labels.api_group - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup - type: input - - computed: setValueFromDbDetails|/spec/tls/issuerRef/kind - label: - text: labels.kind - options: - - text: Issuer - value: Issuer - - text: ClusterIssuer - value: ClusterIssuer - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/kind - sortable: true - type: select - - allowUserDefinedOption: true - computed: setValueFromDbDetails|/spec/tls/issuerRef/name - fetch: getIssuerRefsName - label: - text: labels.name - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/name - sortable: true - type: select - if: showIssuerRefAndCertificates - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef - type: single-step-form - - alias: reusable_certificates - chart: - name: uibytebuildersdev-component-certificates - version: v0.29.0 - computed: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates - functionCallbacks: - getAliasOptions: - $ref: functions#/getAliasOptions - if: showIssuerRefAndCertificates - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/spec/properties/tls/properties/certificates - type: reusable-element - if: ifRequestTypeEqualsTo|ReconfigureTLS - label: - text: labels.tls - schema: - $ref: schema#/properties/spec/properties/tls - type: single-step-form - - label: - text: labels.timeout - options: - - text: 5 minutes - value: 5m - - text: 10 minutes - value: 10m - - text: 30 minutes - value: 30m - - text: 1 hour - value: 1h - - text: 2 hours - value: 2h - - text: 5 hours - value: 5h - - text: 10 hours - value: 10h - schema: - $ref: schema#/properties/spec/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: labels.apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/spec/properties/apply - type: radio - type: single-step-form - id: basic - title: steps.0.label -type: multi-step-form + - type: block-layout + elements: + - type: label-element + 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: select + label: Mode + options: + - text: Offline + value: Offline + - text: Online + value: Online + validation: + type: required + schema: schema/properties/spec/properties/volumeExpansion/properties/mode + - type: block-layout + label: Combined volume expansion + showLabels: true + fixedBlock: true + if: + type: function + name: ifDbTypeEqualsTo|Combined|volumeExpansion + elements: + - type: horizontal-layout + elements: + - type: input-compare + header: Node + subtitle: How much extra storage does your database need? Specify the size(e.g. 2Gi for 2 gigabytes) so we can allocate it correctly + label: Node + init: + type: func + value: setValueFromDbDetails|/spec/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/node + schema: schema/properties/spec/properties/volumeExpansion/properties/node + - type: block-layout + label: Topology volume expansion + showLabels: true + fixedBlock: true + if: + type: function + name: ifDbTypeEqualsTo|Topology|volumeExpansion + elements: + - type: horizontal-layout + elements: + - type: input-compare + label: Broker + subtitle: How much extra storage does your database need? Specify the size(e.g. 2Gi for 2 gigabytes) so we can allocate it correctly + init: + type: func + value: setValueFromDbDetails|/spec/topology/broker/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/topology/broker/storage/requests/storage|/spec/volumeExpansion/broker + schema: schema/properties/spec/properties/volumeExpansion/properties/broker + - type: horizontal-layout + elements: + - type: input-compare + label: Controller + subtitle: How much extra storage does your database need? Specify the size(e.g. 2Gi for 2 gigabytes) so we can allocate it correctly + init: + type: func + value: setValueFromDbDetails|/spec/topology/controller/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/topology/controller/storage/resources/requests/storage|/spec/volumeExpansion/controller + schema: schema/properties/spec/properties/volumeExpansion/properties/controller +# Reconfigure + - type: block-layout + label: Reconfigure Form + if: + name: ifRequestTypeEqualsTo|Reconfigure + type: function + loader: + name: fetchConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + elements: + - type: block-layout + label: Configuration + elements: + - type: label-element + label: '' + subtitle: Select a new configuration secret, apply a custom configuration, or remove an existing setup to update your database settings + - type: tab-layout + label: New Config Secret + schema: temp/properties/reconfigurationType + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + elements: + - type: block-layout + label: Config Secret + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret + type: function + elements: + - type: label-element + label: Config Secret + subtitle: Select a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: schema/properties/spec/properties/configuration/properties/configSecret/properties/name + refresh: true + label: Config Secret + loader: + name: getConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/createSecret/properties/status + init: + type: func + value: setValueFromDbDetails|/spec/configSecret/name + watcher: + func: onCreateSecretChange + paths: + - temp/properties/createSecret/properties/status + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|create + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + - type: block-layout + label: Create a New Config Secret + showLabels: true + if: + type: function + name: isCreateSecret + hasButton: + text: Save + hasCancel: cancelCreateSecret + action: createNewConfigSecret + elements: + - type: input + label: Secret Name + schema: temp/properties/createSecret/properties/name + validation: + type: required + - type: array-object-form + label: String Data + schema: temp/properties/createSecret/properties/data + buttonClass: is-light is-outlined + validation: + type: required + elements: + - type: select + label: Key + schema: key + loader: + name: onSelectedSecretChange + watchPaths: + - temp/properties/createSecret/properties/data + validation: + type: required + - type: textarea + label: Value + schema: value + - type: multi-file-editor + editorHeight: 500px + readonly: true + if: + type: function + name: isNotCreateSecret + loader: + name: onNewConfigSecretChange + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + schema: temp/properties/newConfigSecret + - type: block-layout + label: ApplyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig + type: function + elements: + - type: label-element + 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). + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfiguration + refresh: true + label: Configuration + loader: getConfigSecretsforAppyConfig + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|apply + watchPaths: + - temp/properties/selectedConfiguration + - type: multi-file-editor + editorHeight: 500px + schema: temp/properties/applyConfig + loader: + name: setApplyConfig + watchPaths: + - temp/properties/selectedConfiguration + watcher: + func: onApplyconfigChange + paths: + - temp/properties/applyConfig + - type: block-layout + label: Remove + if: + name: ifReconfigurationTypeEqualsTo|remove + type: function + elements: + - type: label-element + label: Remove + subtitle: Selected a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfigurationRemove + refresh: true + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|remove + watchPaths: + - temp/properties/selectedConfigurationRemove + - type: multi-file-editor + editorHeight: 500px + readonly: true + init: + type: func + value: onRemoveConfigChange + watcher: + func: onRemoveConfigChange + paths: + - temp/properties/selectedConfigurationRemove + schema: temp/properties/removeConfig +# Reconfigure TLS + - type: block-layout + label: TLS + if: + name: ifRequestTypeEqualsTo|ReconfigureTLS + type: function + elements: + - type: radio + label: TLS Operation + if: + name: hasTlsField + type: function + options: + - text: Update + value: update + - text: Rotate + value: rotate + - text: Remove + value: remove + init: + type: func + value: initTlsOperation + schema: temp/properties/tlsOperation + - type: switch + label: Remove TLS + fullwidth: true + if: + name: isTlsEnabled + type: function + schema: schema/properties/spec/properties/tls/properties/remove + - type: switch + label: Rotate Certificates + fullwidth: true + schema: schema/properties/spec/properties/tls/properties/rotateCertificates + if: + name: isTlsEnabled + type: function + - type: block-layout + label: Issuer Reference + showLabels: true + if: + name: showIssuerRefAndCertificates + type: function + elements: + - type: input + label: API Group + init: + type: func + value: initIssuerRefApiGroup + watcher: + func: initIssuerRefApiGroup + paths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + disable: true + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup + - type: select + label: Kind + options: + - text: Issuer + value: Issuer + - text: ClusterIssuer + value: ClusterIssuer + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/kind + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - type: select + label: Name + loader: + name: getIssuerRefsName + watchPaths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - schema/properties/metadata/properties/namespace + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/name + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/name + - type: block-layout + label: Certificates + showLabels: false + if: + name: showIssuerRefAndCertificates + type: function + loader: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates + elements: + - type: array-object-form + label: Certificates + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/tls/properties/certificates + elements: + - type: select + label: Alias + loader: fetchAliasOptions + disable: disableAlias + schema: alias + validation: + type: required + - type: input + label: Secret Name + schema: secretName + - type: input + label: Duration + schema: duration + - type: input + label: Renew Before + schema: renewBefore + - type: array-item-form + label: Organizations + buttonClass: is-light is-outlined + schema: subject/properties/organizations + element: + type: input + label: Organization + - type: array-item-form + label: Countries + buttonClass: is-light is-outlined + schema: subject/properties/countries + element: + type: input + label: Country + - type: array-item-form + label: Organizational Units + buttonClass: is-light is-outlined + schema: subject/properties/organizationalUnits + element: + type: input + label: Organizational Unit + - type: array-item-form + label: Provinces + buttonClass: is-light is-outlined + schema: subject/properties/provinces + element: + type: input + label: Province + - type: array-item-form + label: DNS Names + buttonClass: is-light is-outlined + schema: dnsNames + element: + type: input + label: DNS Name + - type: array-item-form + label: IP Addresses + buttonClass: is-light is-outlined + schema: ipAddresses + element: + type: input + label: IP Address +# common + - type: block-layout + label: OpsRequest Options + showLabels: true + elements: + - type: time-picker + label: Timeout + subtitle: Specify the maximum time allowed for the scaling operation to complete. Use formats like 30sec, 1min(1 minute) or 2h(2 hours). + schema: 'schema/properties/spec/properties/timeout' + - type: radio + label: Apply + subtitle: Choose when to apply the OpsRequest. 'IfReady' waits for the database to be ready, while 'Always' applies immediately. + schema: 'schema/properties/spec/properties/apply' + init: + type: func + value: setApplyToIfReady + options: + - text: IfReady (OpsRequest will be applied if database is ready) + value: IfReady + - text: Always (OpsRequest will always be applied) + value: Always diff --git a/charts/opskubedbcom-kafkaopsrequest-editor/ui/functions.js b/charts/opskubedbcom-kafkaopsrequest-editor/ui/functions.js index e3e47f2a40..b324520e5f 100644 --- a/charts/opskubedbcom-kafkaopsrequest-editor/ui/functions.js +++ b/charts/opskubedbcom-kafkaopsrequest-editor/ui/functions.js @@ -1,3 +1,4 @@ +const { axios, useOperator, store, useToast } = window.vueHelpers || {} const machines = { 'db.t.micro': { resources: { @@ -304,181 +305,268 @@ const machineList = [ 'db.r.24xlarge', ] -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, - } -} +let machinesFromPreset = [] +let secretArray = [] +const configSecretKeys = ['server.properties', 'broker.properties', 'controller.properties'] -function returnFalse() { - return false -} +export const useFunc = (model) => { + const route = store.state?.route + const toast = useToast() -async function getNamespaces({ axios, storeGet }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + const { getValue, storeGet, discriminator, setDiscriminatorValue, commit } = useOperator( + model, + store.state, + ) - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + showAndInitOpsRequestType() + async function fetchJsons({ axios, itemCtx }) { + let ui = {} + let language = {} + let functions = {} + const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart - const resources = (resp && resp.data && resp.data.items) || [] + 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 resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' return { - text: name, - value: name, + ui: ui.data || {}, + language: language.data || {}, + functions, } - }) -} + } -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + 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 + ) + } -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/namespace') + 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/kubedb.com/v1alpha2/namespaces/${namespace}/kafkas`, - { + 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) || [] - const resources = (resp && resp.data && resp.data.items) || [] + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } - 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') -async function getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) { - 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') + const namespace = getValue(model, '/metadata/namespace') + // watchDependency('model#/metadata/namespace') - if (namespace && name) { - const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/kafkas/${name}` - const resp = await axios.get(url) + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/kafkas`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) - setDiscriminatorValue('/dbDetails', resp.data || {}) + const resources = (resp && resp.data && resp.data.items) || [] - return resp.data || {} - } else return {} -} + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -async function getDbVersions({ axios, storeGet, getValue, discriminator }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + async function getDbDetails() { + machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] - const url = `/clusters/${owner}/${cluster}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/kubedb-ui-presets` + 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') - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + if (namespace && name) { + const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/kafkas/${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 { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + presetVersions = presets.admin?.databases?.Kafka?.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/kafkaversions`, + { + 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 allowed = found?.spec?.updateConstraints?.allowlist || [] + 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 filteredKafkaVersions = 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.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.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.includes(item.metadata?.name)) && + isVersionWithinConstraints(item.spec?.version, limit) + ) + }) + setDiscriminatorValue('/filteredVersion', filteredKafkaVersions) + return filteredKafkaVersions.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) - presets.status = String(e.status) + return [] } } - try { - const presetVersions = presets.admin?.databases?.Kafka?.versions?.available || [] - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null, updateConstraints: null }, - }, - }, + 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 + } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/catalog.kubedb.com/v1alpha1/kafkaversions`, - { - params: queryParams, - }, - ) + 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 + } - const resources = (resp && resp.data && resp.data.items) || [] + 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: [ ' - 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 allowed = found?.spec?.updateConstraints?.allowlist || [] - 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 filteredKafkaVersions = 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.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.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.includes(item.metadata?.name)) && - isVersionWithinConstraints(item.spec?.version, limit) - ) + presetVersions.forEach((v, idx) => { + txt = `${txt}"${v}"` + if (idx !== presetVersions.length - 1) txt = txt + ', ' + else txt = txt + ' ]' }) - return filteredKafkaVersions.map((item) => { + return txt + } + + function getVersion() { + return filteredVersion.map((item) => { const name = (item.metadata && item.metadata.name) || '' const specVersion = (item.spec && item.spec.version) || '' return { @@ -486,837 +574,1312 @@ async function getDbVersions({ axios, storeGet, getValue, discriminator }) { value: name, } }) - } catch (e) { - console.log(e) - return [] } -} -function versionCompare(v1, v2) { - const arr1 = v1.split('.').map(Number) - const arr2 = v2.split('.').map(Number) + function isVersionEmpty() { + const val = getValue(discriminator, '/filteredVersion') + return val.length === 0 + } - for (let i = 0; i < Math.max(arr1.length, arr2.length); i++) { - const num1 = arr1[i] || 0 - const num2 = arr2[i] || 0 + function ifRequestTypeEqualsTo(type) { + const selectedType = getValue(model, '/spec/type') + // watchDependency('model#/spec/type') - if (num1 > num2) return 1 // v1 is higher - if (num1 < num2) return -1 // v2 is higher + return selectedType === type } - return 0 // versions are equal -} -function isVersionWithinConstraints(version, constraints) { - let constraintsArr = [] - if (constraints.includes(',')) constraintsArr = constraints?.split(',')?.map((c) => c.trim()) - else constraintsArr = [constraints] + 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 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 || {} + + if (topology) { + return 'Topology' + } else { + return 'Combined' + } + } + + function disableOpsRequest() { + if (itemCtx.value === 'HorizontalScaling') { + const dbType = getDbType({ + discriminator, + getValue, + }) + + if (dbType === 'Combined') return true + else return false + } else return false + } - for (let constraint of constraintsArr) { - let match = constraint.match(/^(>=|<=|>|<)/) - let operator = match ? match[0] : '' - let constraintVersion = constraint.replace(/^(>=|<=|>|<)/, '').trim() + function initNamespace() { + const { namespace } = route.query || {} + return namespace || null + } - let comparison = versionCompare(version, constraintVersion) + function initDatabaseRef() { + // watchDependency('model#/metadata/namespace') + const { name } = route.params || {} + return name + } + + function clearOpsReqSpec(verd, opsReqType) { if ( - (operator === '>=' && comparison < 0) || - (operator === '<=' && comparison > 0) || - (operator === '>' && comparison <= 0) || - (operator === '<' && comparison >= 0) - ) - return false + opsReqType === 'verticalScaling' || + opsReqType === 'horizontalScaling' || + opsReqType === 'volumeExpansion' || + opsReqType === 'configuration' + ) { + if (verd === 'Topology') { + commit('wizard/model$delete', `/spec/${opsReqType}/node`) + } else if (verd === 'Combined') { + commit('wizard/model$delete', `/spec/${opsReqType}/broker`) + commit('wizard/model$delete', `/spec/${opsReqType}/controller`) + commit('wizard/model$delete', `/spec/${opsReqType}/topology`) + } + } } - return true -} -function ifRequestTypeEqualsTo({ model, getValue, watchDependency }, type) { - const selectedType = getValue(model, '/spec/type') - watchDependency('model#/spec/type') + function asDatabaseOperation() { + return !!route.params.actions + } - return selectedType === type -} + function generateOpsRequestNameForClusterUI(getValue, model, route) { + const dbName = getValue(model, '/spec/databaseRef/name') -function onRequestTypeChange({ model, getValue, commit }) { - 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]}`) - }) -} + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' -function disableOpsRequest({ itemCtx, discriminator, getValue, watchDependency }) { - if (itemCtx.value === 'HorizontalScaling') { - const dbType = getDbType({ - discriminator, - getValue, - watchDependency, - }) + const resources = route.params.resource || '' + const resource = resources.slice(0, -1) - if (dbType === 'Standalone') return true - else return false - } else return false -} + const opsName = dbName ? dbName : resource + return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` + } -function getDbTls({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + function showAndInitName() { + // watchDependency('model#/spec/type') + // watchDependency('model#/spec/databaseRef/name') + const ver = asDatabaseOperation() - const { spec } = dbDetails || {} - return spec?.tls || undefined -} + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' -function getDbType({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') - const { spec } = dbDetails || {} - const { topology } = spec || {} - if (topology) return 'Topology' - else return 'Combined' -} + 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 initNamespace({ route }) { - const { namespace } = route.query || {} - return namespace || null -} + function showAndInitNamespace() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/metadata/namespace', + value: `${route.query.namespace}`, + force: true, + }) + } -function initDatabaseRef({ route, watchDependency }) { - watchDependency('model#/metadata/namespace') - const { name } = route.params || {} - return name -} + return !ver + } -function asDatabaseOperation(route) { - return !!route.params.actions -} + function showAndInitDatabaseRef() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/spec/databaseRef/name', + value: `${route.params.name}`, + force: true, + }) + } -function generateOpsRequestNameForClusterUI(getValue, model, route) { - const dbName = getValue(model, '/spec/databaseRef/name') + return !ver + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + function showConfigureOpsrequestLabel() { + return !asDatabaseOperation() + } - const resources = route.params.resource || '' - const resource = resources.slice(0, -1) + 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, + }) + } + } - const opsName = dbName ? dbName : resource - return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` -} + return !ver + } -function showAndInitName({ route, commit, getValue, model, watchDependency }) { - watchDependency('model#/spec/type') - watchDependency('model#/spec/databaseRef/name') - const ver = asDatabaseOperation(route) + // // vertical scaling + function ifDbTypeEqualsTo(value, opsReqType) { + const verd = getDbType() - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + clearOpsReqSpec(verd, opsReqType) + return value === verd + } - 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, - }) + // // machine profile stuffs + // let machinesFromPreset = [] + + function getMachines(type) { + const presets = storeGet('/kubedbuiPresets') || {} + const dbDetails = getValue(discriminator, '/dbDetails') + // const limits = dbDetails?.spec?.podTemplate?.spec?.resources?.limits || {} + const limits = (type && type !== 'node' + ? dbDetails?.spec?.topology?.[type]?.resources?.requests + : dbDetails?.spec?.podTemplate?.spec?.containers?.[0]?.resources?.requests) || { + cpu: '', + memory: '', + } + + 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 } - return !ver -} -function showAndInitNamespace({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/metadata/namespace', - value: `${route.query.namespace}`, - force: true, + + function setMachine(type) { + const dbDetails = getValue(discriminator, '/dbDetails') + // const limits = dbDetails?.spec?.podTemplate?.spec?.resources?.limits || {} + const limits = (type && type !== 'node' + ? dbDetails?.spec?.topology?.[type]?.resources?.requests + : dbDetails?.spec?.podTemplate?.spec?.containers?.[0]?.resources?.requests) || { + cpu: '', + memory: '', + } + 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 = {} + } + const machine = parsedInstance[type] || '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-${type}`) + 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') || {} + const instance = annotations['kubernetes.io/instance-type'] + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = {} + } + parsedInstance[type] = selectedMachine.machine + annotations['kubernetes.io/instance-type'] = JSON.stringify(parsedInstance) + + if (machinesFromPreset.length) + commit('wizard/model$update', { + path: '/metadata/annotations', + value: annotations, + force: true, + }) + + if (parsedInstance && Object.keys(parsedInstance).length === 0) + commit('wizard/model$delete', '/metadata/annotations') + } + + function isMachineCustom(path) { + // watchDependency(`discriminator#${path}`) + const machine = getValue(discriminator, `${path}`) + return machine === 'custom' + } + + // Fetch and store database Infos + // for secret configurations in reconfigure + let configSecrets = [] + let secretConfigData = [] + + 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: ['server.properties', 'broker.properties', 'controller.properties'], + }, + }, + ) + configSecrets = resp?.data?.response?.availableSecrets || [] + secretConfigData = resp?.data?.response?.configurations || [] + } 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 } - return !ver -} -function showAndInitDatabaseRef({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/spec/databaseRef/name', - value: `${route.params.name}`, - force: true, + async function getConfigSecretsforAppyConfig() { + const secrets = secretConfigData.map((item) => { + return { text: item.componentName, value: item.componentName } }) + return secrets } - return !ver -} -function showConfigureOpsrequestLabel({ route }) { - return !asDatabaseOperation(route) -} -function showAndInitOpsRequestType({ route, commit }) { - const ver = asDatabaseOperation(route) - const opMap = { - upgrade: 'UpdateVersion', - updateVersion: 'UpdateVersion', - horizontalscaling: 'HorizontalScaling', - verticalscaling: 'VerticalScaling', - volumeexpansion: 'VolumeExpansion', - restart: 'Restart', - reconfiguretls: 'ReconfigureTLS', - reconfigure: 'Reconfigure', - } - if (ver) { - const operation = route.params.actions - const match = /^(.*)-opsrequest-(.*)$/.exec(operation) - const opstype = match[2] + 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: '/spec/type', - value: opMap[opstype], + path: `/temp/${type}applyConfig`, + value: result, force: true, }) + + return result } - return !ver -} + 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` -// vertical scaling -function ifDbTypeEqualsTo({ discriminator, getValue, watchDependency, commit }, value, opsReqType) { - const verd = getDbType({ - discriminator, - getValue, - watchDependency, - }) - return value === verd -} + const selectedConfiguration = + configType === 'create' ? getValue(model, path) : getValue(discriminator, path) -// machine profile stuffs -let machinesFromPreset = [] -function hasMachine({ getValue, discriminator }) { - const dbDetails = getValue(discriminator, '/dbDetails') - const annotations = dbDetails?.metadata?.annotations || {} - return !!annotations['kubernetes.io/instance-type'] -} + 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) -function getMachines({ storeGet }) { - const presets = storeGet('/kubedbuiPresets') || {} - const avlMachines = presets.admin?.machineProfiles?.available || [] - let arr = [] - if (avlMachines.length) { - arr = avlMachines.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - 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 } - } else return { text: machine, value: machine } + 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 } }) - } else { - arr = machineList - .map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + + // 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])) + + 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', }) - .filter((val) => !!val) + 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 arr -} -function setMachine({ getValue, discriminator, storeGet }, type) { - const dbDetails = getValue(discriminator, '/dbDetails') - 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 = {} + 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 + ) } - const machine = parsedInstance[type] || 'custom' - machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] + function isCreateSecret(type) { + type = type ? type + '/' : '' + const selectedSecret = getValue(model, `spec/configuration/${type}configSecret/name`) + const res = selectedSecret === 'Create' - const machinePresets = machinesFromPreset.find((item) => item.id === machine) - if (machinePresets) return machine - else return 'custom' -} + if (res === true) { + commit('wizard/temp$update', { + path: `${type}createSecret/status`, + value: 'pending', + }) + } + return res + } + + function isNotCreateSecret(type) { + return !isCreateSecret(type) + } -function onMachineChange({ getValue, discriminator, commit, model }, type, valPath) { - let selectedMachine = '' - selectedMachine = getValue(discriminator, `/machine-${type}`) - const machine = machinesFromPreset.find((item) => item.id === selectedMachine) + 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 } : '' + } + } - let obj = {} - if (selectedMachine !== 'custom') { - if (machine) obj = { limits: { ...machine?.limits }, requests: { ...machine?.limits } } - else obj = machines[selectedMachine]?.resources - } else { - const val = getValue(discriminator, `/dbDetails${valPath}`) || {} - obj = Array.isArray(val) ? val[0]?.resources : { ...val } + 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', + }) } - const path = `/spec/verticalScaling/${type}/resources` + async function onApplyconfigChange(type) { + type = type ? type + '/' : '' + const configValue = getValue(discriminator, `${type}applyConfig`) - if (obj && Object.keys(obj).length) + if (!configValue) { + commit('wizard/model$delete', `/spec/configuration/${type}applyConfig`) + return + } + const tempConfigObj = {} + configValue.forEach((item) => { + if (item.name) { + 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: path, - value: obj, - force: true, + path: `/spec/configuration/${type}applyConfig`, + value: tempConfigObj, }) + } - // update metadata.annotations - const annotations = getValue(model, '/metadata/annotations') || {} - const instance = annotations['kubernetes.io/instance-type'] - let parsedInstance = {} - try { - if (instance) parsedInstance = JSON.parse(instance) - } catch (e) { - console.log(e) - parsedInstance = {} - } - if (selectedMachine === 'custom') delete parsedInstance[type] - else parsedInstance[type] = selectedMachine - annotations['kubernetes.io/instance-type'] = JSON.stringify(parsedInstance) - - if (machinesFromPreset.length) + 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], + }) + }) + } else { + configObj.push({ name: '', 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: '/metadata/annotations', - value: annotations, - force: true, + path: `/spec/configuration/${type}removeCustomConfig`, + value: true, }) - if (parsedInstance && Object.keys(parsedInstance).length === 0) - commit('wizard/model$delete', '/metadata/annotations') -} + const configuration = secretConfigData.find((item) => item.componentName === selectedConfig) -function isMachineCustom({ watchDependency, getValue, discriminator }, path) { - watchDependency(`discriminator#${path}`) - const machine = getValue(discriminator, `${path}`) - return machine === 'custom' -} + if (!configuration.data) { + return [{ name: '', content: '' }] + } -// for config secret -async function getConfigSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + 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 + } - const secrets = (resp && resp.data && resp.data.items) || [] + async function onNewConfigSecretChange(type) { + type = type ? type + '/' : '' + const path = `/spec/configuration/${type}configSecret/name` + const selectedSecret = getValue(model, path) - const filteredSecrets = secrets + if (!selectedSecret) { + commit('wizard/model$delete', `/spec/configuration/${type}configSecret`) + return [{ name: '', content: '' }] + } + if (selectedSecret === 'Create') return [{ name: '', content: '' }] - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return filteredSecrets -} + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = storeGet('/route/query/namespace') || getValue(model, '/metadata/namespace') -function createSecretUrl({ storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 + }) + } + }) - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/secrets/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/secrets/create` + return configObj + } catch (e) { + console.error('Error fetching secret:', e) + return [{ name: '', content: '' }] + } } -} - -function isEqualToValueFromType({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/valueFromType') - const valueFrom = getValue(discriminator, '/valueFromType') - return valueFrom === value -} -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function onSelectedSecretChange(index) { + const secretData = getValue(discriminator, 'createSecret/data') || [] + const selfSecrets = secretData.map((item) => item.key) - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + const remainingSecrets = configSecretKeys.filter((item) => !selfSecrets.includes(item)) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, + 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 + } - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + function getSelectedConfigSecret(type) { + const path = `/spec/configuration/configSecret/name` + const selectedSecret = getValue(model, path) + return `You have selected ${selectedSecret} secret` || 'No secret selected' } - return ans -} -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function objectToYaml(obj, indent = 0) { + if (obj === null || obj === undefined) return 'null' + if (typeof obj !== 'object') return JSON.stringify(obj) - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` + const spaces = ' '.repeat(indent) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }) + 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}"` + } - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + return `${keyLine} ${value}` + }) + .join('\n') } - return ans -} -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - group, - version, - resource, -) { - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/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) + function getSelectedConfigSecretValue(type) { + const path = `/spec/configuration/configSecret/name` + const selectedSecret = getValue(model, path) + let data + secretArray.forEach((item) => { + if (item.metadata?.name === selectedSecret) { + data = objectToYaml(item.data).trim() || 'No Data Found' + } }) + return data || 'No Data Found' } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + function isVerticalScaleTopologyRequired(type) { + const key = getValue(model, `/temp/topologyKey-${type}`) + const value = getValue(model, `/temp/topologyValue-${type}`) + + if ((key && !value) || (!key && value)) { + return 'Both Key and Value are required for topology' } - }) -} -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) - - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) + + if (key && value) { + const topologyPath = `/spec/verticalScaling/${type}/topology` + commit('wizard/model$update', { + path: topologyPath, + value: { key, value }, + force: true, + }) + } + + return undefined } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + 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` } - }) -} + } -// reconfiguration type -function ifReconfigurationTypeEqualsTo({ discriminator, getValue, watchDependency }, value) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - watchDependency('discriminator#/reconfigurationType') + function isEqualToValueFromType(value) { + // watchDependency('discriminator#/valueFromType') + const valueFrom = getValue(discriminator, '/valueFromType') + return valueFrom === value + } - return reconfigurationType === value -} + async function getNamespacedResourceList({ namespace, group, version, resource }) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function onApplyconfigChange({ discriminator, getValue, commit }) { - const applyconfig = getValue(discriminator, '/applyConfig') + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` - const configObj = {} - if (applyconfig) { - applyconfig.forEach((item) => { - const { key, value } = item - configObj[key] = value - }) + 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') - commit('wizard/model$update', { - path: '/spec/configuration/applyConfig', - value: configObj, - force: true, - }) -} + 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 } }, + }, + }) -function onReconfigurationTypeChange({ commit, discriminator, getValue, setDiscriminatorValue }) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - setDiscriminatorValue('/applyConfig', []) - if (reconfigurationType === 'remove') { - commit('wizard/model$delete', `/spec/configuration`) + const items = (resp && resp.data && resp.data.items) || [] + ans = items + } catch (e) { + console.log(e) + } - commit('wizard/model$update', { - path: `/spec/configuration/removeCustomConfig`, - value: true, - force: true, + 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, + } }) - } else { - commit('wizard/model$delete', `/spec/configuration/configSecret`) - commit('wizard/model$delete', `/spec/configuration/applyConfig`) - commit('wizard/model$delete', `/spec/configuration/removeCustomConfig`) } -} + async function unNamespacedResourceNames(group, version, resource) { + let resources = await getResourceList({ + group, + version, + resource, + }) -// for tls -function hasTlsField({ discriminator, getValue, watchDependency }) { - const tls = getDbTls({ - discriminator, - getValue, - watchDependency, - }) + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } - return !!tls -} + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -function initIssuerRefApiGroup({ getValue, model, watchDependency, discriminator }) { - const kind = getValue(model, '/spec/tls/issuerRef/kind') - watchDependency('model#/spec/tls/issuerRef/kind') + // reconfiguration type + function ifReconfigurationTypeEqualsTo(value) { + const reconfigurationType = getValue(discriminator, '/reconfigurationType') - if (kind) { - const apiGroup = getValue(discriminator, '/dbDetails/spec/tls/issuerRef/apiGroup') - if (apiGroup) return apiGroup - return 'cert-manager.io' - } else return undefined -} + const watchPath = `discriminator#/reconfigurationType` + // watchDependency(watchPath) + return reconfigurationType === value + } -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - 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` + function onReconfigurationTypeChange() { + setDiscriminatorValue(`/applyConfig`, []) + const reconfigurationType = getValue(discriminator, '/reconfigurationType') + if (reconfigurationType === 'remove') { + commit('wizard/model$delete', `/spec/configuration`) - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + 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) { + 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 presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + 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) - presets.status = String(e.status) + return [] } } - 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 } - async function getIssuer(url) { - try { - const resp = await axios.get(url) - const resources = (resp && resp.data && resp.data.items) || [] + function initTlsOperation() { + return 'update' + } + function onTlsOperationChange() { + const tlsOperation = getValue(discriminator, '/tlsOperation') - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + commit('wizard/model$delete', '/spec/tls') + + if (tlsOperation === 'rotate') { + commit('wizard/model$update', { + path: '/spec/tls/rotateCertificates', + value: true, + force: true, + }) + } else if (tlsOperation === 'remove') { + commit('wizard/model$update', { + path: '/spec/tls/remove', + value: true, + force: true, }) - return resources - } catch (e) { - console.log(e) - return [] } } -} -function initTlsOperation() { - return 'update' -} -function onTlsOperationChange({ discriminator, getValue, commit }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') - - commit('wizard/model$delete', '/spec/tls') + function showIssuerRefAndCertificates() { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // watchDependency('discriminator#/tlsOperation') + const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' - 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') + return verd } -} -function showIssuerRefAndCertificates({ discriminator, getValue, watchDependency }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') - watchDependency('discriminator#/tlsOperation') - const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' + function isIssuerRefRequired() { + const hasTls = hasTlsField() + return hasTls ? false : '' + } - return verd -} + function getRequestTypeFromRoute() { + const isDbloading = isDbDetailsLoading() + const { query } = route || {} + const { requestType } = query || {} + return isDbloading ? '' : requestType || '' + } -function isIssuerRefRequired({ discriminator, getValue, watchDependency }) { - const hasTls = hasTlsField({ - discriminator, - getValue, - watchDependency, - }) + function isDbDetailsLoading() { + // watchDependency('discriminator#/dbDetails') + // watchDependency('model#/spec/databaseRef/name') + const dbDetails = getValue(discriminator, '/dbDetails') + const dbName = getValue(model, '/spec/databaseRef/name') - return !hasTls -} + return !dbDetails || !dbName + } -function getRequestTypeFromRoute({ route, model, discriminator, getValue, watchDependency }) { - const isDbloading = isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) - const { query } = route || {} - const { requestType } = query || {} - return isDbloading ? '' : requestType || '' -} + function setValueFromDbDetails(path, commitPath) { + const retValue = getValue(discriminator, `/dbDetails${path}`) -// ************************************** Set db details ***************************************** + if (commitPath) { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // computed called when tls fields is not visible + if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined -function isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - watchDependency('model#/spec/databaseRef/name') - const dbDetails = getValue(discriminator, '/dbDetails') - const dbName = getValue(model, '/spec/databaseRef/name') + // 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 + } - return !dbDetails || !dbName -} + function getAliasOptions() { + return ['server', 'client', 'metrics-exporter'] + } -function setValueFromDbDetails( - { discriminator, getValue, watchDependency, commit }, - path, - commitPath, -) { - watchDependency('discriminator#/dbDetails') + function isNamespaceDisabled() { + const { namespace } = route.query || {} + return !!namespace + } - const retValue = getValue(discriminator, `/dbDetails${path}`) + function isDatabaseRefDisabled() { + const { name } = route.params || {} + return !!name + } - if (commitPath && retValue) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + function onNamespaceChange() { + commit('wizard/model$delete', '/spec/type') + } - // computed called when tls fields is not visible - if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined + function onDbChange() { + commit('wizard/model$delete', '/spec/type') + getDbDetails() + } - // 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, - }) + function setApplyToIfReady() { + return 'IfReady' } - return retValue || undefined -} + function checkVolume(initpath, path) { + const volume = getValue(discriminator, `/dbDetails${initpath}`) + const input = getValue(model, path) -function setResource({ discriminator, getValue, watchDependency }, path) { - watchDependency('discriminator#/dbDetails') - const containers = getValue(discriminator, `/dbDetails${path}`) || [] - const kind = getValue(discriminator, '/dbDetails/kind') - const resource = containers.filter((ele) => ele.name === kind.toLowerCase()) - return resource[0].resources -} + try { + const sizeInBytes = parseSize(volume) + const inputSizeInBytes = parseSize(input) -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} + if (inputSizeInBytes >= sizeInBytes) return + else return 'Cannot expand to lower volume!' + } catch (err) { + return err.message || 'Invalid' + } + } -function isNamespaceDisabled({ route }) { - const { namespace } = route.query || {} - return !!namespace -} + 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, + } -function isDatabaseRefDisabled({ route }) { - const { name } = route.params || {} - return !!name -} + const match = String(sizeStr).match(/^([0-9]+(?:\.[0-9]*)?)\s*([A-Za-z]*)$/) + if (!match) throw new Error('Invalid size format') -function onNamespaceChange({ commit }) { - commit('wizard/model$delete', '/spec/type') -} + const value = parseFloat(match[1]) + const unit = match[2] -function onDbChange({ commit, axios, storeGet, model, getValue, setDiscriminatorValue }) { - commit('wizard/model$delete', '/spec/type') - getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) -} + if (!(unit in units)) + throw new Error('Unrecognized unit. Available units are K, Ki, M, Mi, G, Gi etc') -function setApplyToIfReady() { - return 'IfReady' -} + return value * units[unit] + } -function isVerticalScaleTopologyRequired({ watchDependency, getValue, discriminator, commit }) { - watchDependency('discriminator#/topologyKey') - watchDependency('discriminator#/topologyValue') + function fetchAliasOptions() { + return getAliasOptions ? getAliasOptions() : [] + } - const key = getValue(discriminator, '/topologyKey') - const value = getValue(discriminator, '/topologyValue') - const path = `/spec/verticalScaling/kafka/topology` + function validateNewCertificates({ itemCtx }) { + const addedAliases = (model && model.map((item) => item.alias)) || [] - if (key || value) { - commit('wizard/model$update', { - path: path, - value: { key, value }, - force: true, - }) - return true - } else { - commit('wizard/model$delete', path) - return false + if (addedAliases.includes(itemCtx.alias) && itemCtx.isCreate) { + return { isInvalid: true, message: 'Alias already exists' } + } + return {} + } + + function disableAlias() { + return !!(model && model.alias) } -} -function checkVolume({ model, discriminator, getValue }, initpath, path) { - const volume = getValue(discriminator, `/dbDetails${initpath}`) - const input = getValue(model, path) + function setExporter(type) { + let path = `/dbDetails/spec/monitor/prometheus/exporter/resources/limits/${type}` + const limitVal = getValue(discriminator, path) - try { - const sizeInBytes = parseSize(volume) - const inputSizeInBytes = parseSize(input) + if (!limitVal) { + path = `/dbDetails/spec/monitor/prometheus/exporter/resources/requests/${type}` + const reqVal = getValue(discriminator, path) - if (inputSizeInBytes >= sizeInBytes) return true - else return 'Cannot expand to lower volume!' - } catch (err) { - return err.message || 'Invalid' + if (reqVal) return reqVal + } + return limitVal } -} -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 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, + }) + } -return { - isRancherManaged, - setResource, - fetchJsons, - returnFalse, - getNamespaces, - getDbs, - getDbDetails, - getDbVersions, - ifRequestTypeEqualsTo, - onRequestTypeChange, - getDbTls, - getDbType, - initNamespace, - initDatabaseRef, - - showAndInitName, - showAndInitNamespace, - showAndInitDatabaseRef, - showConfigureOpsrequestLabel, - showAndInitOpsRequestType, - - ifDbTypeEqualsTo, - getConfigSecrets, - createSecretUrl, - isEqualToValueFromType, - disableOpsRequest, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - ifReconfigurationTypeEqualsTo, - onReconfigurationTypeChange, - onApplyconfigChange, - hasTlsField, - initIssuerRefApiGroup, - getIssuerRefsName, - initTlsOperation, - onTlsOperationChange, - showIssuerRefAndCertificates, - isIssuerRefRequired, - getRequestTypeFromRoute, - isDbDetailsLoading, - setValueFromDbDetails, - getAliasOptions, - isNamespaceDisabled, - isDatabaseRefDisabled, - onNamespaceChange, - onDbChange, - setApplyToIfReady, - isVerticalScaleTopologyRequired, - getMachines, - setMachine, - onMachineChange, - isMachineCustom, - checkVolume, + return { + setExporter, + onExporterResourceChange, + fetchAliasOptions, + validateNewCertificates, + disableAlias, + isRancherManaged, + fetchJsons, + returnFalse, + getNamespaces, + getDbs, + getDbDetails, + getDbVersions, + getVersionInfo, + isVersionEmpty, + getVersion, + ifRequestTypeEqualsTo, + onRequestTypeChange, + getDbTls, + getDbType, + disableOpsRequest, + initNamespace, + initDatabaseRef, + clearOpsReqSpec, + showAndInitName, + showAndInitNamespace, + showAndInitDatabaseRef, + showConfigureOpsrequestLabel, + showAndInitOpsRequestType, + ifDbTypeEqualsTo, + getConfigSecrets, + createSecretUrl, + isEqualToValueFromType, + getNamespacedResourceList, + getResourceList, + resourceNames, + unNamespacedResourceNames, + ifReconfigurationTypeEqualsTo, + onReconfigurationTypeChange, + onApplyconfigChange, + hasTlsField, + initIssuerRefApiGroup, + getIssuerRefsName, + initTlsOperation, + onTlsOperationChange, + showIssuerRefAndCertificates, + isIssuerRefRequired, + getRequestTypeFromRoute, + isDbDetailsLoading, + setValueFromDbDetails, + getAliasOptions, + isNamespaceDisabled, + isDatabaseRefDisabled, + onDbChange, + onNamespaceChange, + setApplyToIfReady, + getMachines, + setMachine, + onMachineChange, + isMachineCustom, + checkVolume, + getSelectedConfigSecret, + getSelectedConfigSecretValue, + isVerticalScaleTopologyRequired, + fetchConfigSecrets, + getConfigSecretsforAppyConfig, + getSelectedConfigurationData, + getSelectedConfigurationName, + getSelectedConfigurationValueForRemove, + createNewConfigSecret, + decodeError, + isCreateSecret, + isNotCreateSecret, + onCreateSecretChange, + cancelCreateSecret, + setApplyConfig, + onRemoveConfigChange, + onNewConfigSecretChange, + onSelectedSecretChange, + isTlsEnabled, + } } diff --git a/charts/opskubedbcom-mariadbopsrequest-editor/ui/create-ui.yaml b/charts/opskubedbcom-mariadbopsrequest-editor/ui/create-ui.yaml index 15bb887402..c4fb82daaa 100644 --- a/charts/opskubedbcom-mariadbopsrequest-editor/ui/create-ui.yaml +++ b/charts/opskubedbcom-mariadbopsrequest-editor/ui/create-ui.yaml @@ -1,413 +1,628 @@ -steps: -- form: - discriminator: - dbDetails: - type: object +type: multi-step-form +step: + - type: single-step-form + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - schema: - $ref: discriminator#/properties/dbDetails - type: input - - if: showAndInitName - label: - text: labels.op_req_name - required: true - schema: - $ref: schema#/properties/metadata/properties/name - type: input - - computed: initNamespace - disabled: isNamespaceDisabled - fetch: getNamespaces - hasGroup: isRancherManaged - if: showAndInitNamespace - label: - text: labels.namespace - onChange: onNamespaceChange - required: true - schema: - $ref: schema#/properties/metadata/properties/namespace - type: select - - computed: initDatabaseRef - disabled: isDatabaseRefDisabled - fetch: getDbs - if: showAndInitDatabaseRef - label: - text: labels.databaseRef - onChange: onDbChange - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/databaseRef/properties/name - type: select - - if: showConfigureOpsrequestLabel - label: - text: labels.config_ops_request - type: label-element - - computed: getRequestTypeFromRoute - disabled: isDbDetailsLoading - hasDescription: true - if: showAndInitOpsRequestType - individualItemDisabilityCheck: disableOpsRequest - label: - text: labels.ops_request_type - onChange: onRequestTypeChange - options: - - description: options.UpdateVersion.description - text: options.UpdateVersion.text - value: UpdateVersion - - description: options.HorizontalScaling.description - text: options.HorizontalScaling.text - value: HorizontalScaling - - description: options.VerticalScaling.description - text: options.VerticalScaling.text - value: VerticalScaling - - description: options.VolumeExpansion.description - text: options.VolumeExpansion.text - value: VolumeExpansion - - description: options.Restart.description - text: options.Restart.text - value: Restart - - description: options.Reconfigure.description - text: options.Reconfigure.text - value: Reconfigure - - description: options.ReconfigureTLS.description - text: options.ReconfigureTLS.text - value: ReconfigureTLS - schema: - $ref: schema#/properties/spec/properties/type - type: radio - - elements: - - computed: setValueFromDbDetails|/spec/version - fetch: getDbVersions - label: - text: labels.targetVersion - schema: - $ref: schema#/properties/spec/properties/updateVersion/properties/targetVersion - type: select - if: ifRequestTypeEqualsTo|UpdateVersion - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/replicas - if: ifDbTypeEqualsTo|cluster|horizontalScaling - label: - text: labels.replicas - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/member - type: input - if: ifRequestTypeEqualsTo|HorizontalScaling - label: - text: Horizontal Scaling Form - type: single-step-form - - elements: - - discriminator: - machine: - default: "" - type: string - elements: - - computed: setMachine - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|mariadb|/spec/podTemplate/spec/resources - schema: - $ref: discriminator#/machine - type: select - - if: isMachineCustom - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/mariadb/properties/resources - type: resource-input-form - - label: - text: labels.node_selection_policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/mariadb/properties/nodeSelectionPolicy - type: select - - discriminator: - topologyKey: - default: "" - type: string - topologyValue: - default: "" - type: string - elements: - - label: - text: labels.key - required: isVerticalScaleTopologyRequired - schema: - $ref: discriminator#/topologyKey - type: input - - label: - text: labels.value - required: isVerticalScaleTopologyRequired - schema: - $ref: discriminator#/topologyValue - type: input - label: - text: labels.topology - show_label: true - type: single-step-form - label: - text: labels.mariadb - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/mariadb - show_label: true - type: single-step-form - - computed: setValueFromDbDetails|/spec/monitor/prometheus/exporter/resources|/spec/verticalScaling/exporter/resources - label: - text: labels.exporter - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/exporter/properties/resources - type: resource-input-form - if: ifRequestTypeEqualsTo|VerticalScaling - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/storage/resources/requests/storage - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/mariadb - type: input - validationRuleObject: - func: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/mariadb - - label: - text: Mode +# common + - type: input + label: op_req_name + if: + type: function + name: showAndInitName + validation: + type: required + schema: schema/properties/metadata/properties/name + - type: select + label: Namespace + if: + type: function + name: showAndInitNamespace + init: + type: func + value: initNamespace + disable: isNamespaceDisabled + loader: getNamespaces + validation: + type: required + hasGroup: isRancherManaged + schema: schema/properties/metadata/properties/namespace + - type: select + label: Database Ref + if: + type: function + name: showAndInitDatabaseRef + loader: + name: getDbs + watchPaths: + - schema/properties/metadata/properties/namespace + init: + type: func + value: initDatabaseRef + validation: + type: required + disable: isDatabaseRefDisabled + refresh: true + watcher: + func: onDbChange + paths: + - schema/properties/spec/properties/databaseRef/properties/name + schema: schema/properties/spec/properties/databaseRef/properties/name + - type: label-element + label: config_ops_request + if: + type: function + name: showConfigureOpsrequestLabel + - type: radio + label: Type of Ops Request + if: + type: function + name: showAndInitOpsRequestType options: - - text: Offline - value: Offline - - text: Online - value: Online - required: true - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/mode - type: select - if: ifRequestTypeEqualsTo|VolumeExpansion - label: - text: Volume Expansion Form - type: single-step-form - - elements: - - discriminator: - reconfigurationType: - type: string + - 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 + init: + type: func + value: getRequestTypeFromRoute + disable: isDbDetailsLoading + watcher: + func: isDbDetailsLoading + paths: + - temp/dbDetails + - schema/properties/spec/properties/databaseRef/properties/name + isHorizontal: true + schema: schema/properties/spec/properties/type +# UpdateVersion + - type: block-layout + showLabels: true + label: Version + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|UpdateVersion + elements: + - type: select-compare + label: Target Version + subtitle: Select the desired MariaDB version to which you want to update your database. + init: + type: func + value: setValueFromDbDetails|/spec/version + loader: getDbVersions + schema: schema/properties/spec/properties/updateVersion/properties/targetVersion + - type: info + label: '' + loader: + name: getVersionInfo + watchPaths: + - temp/properties/filteredVersion + if: + type: function + name: isVersionEmpty +# Horizontal Scale + - type: block-layout + label: Horizontal Scaling Form + showLabels: true + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|HorizontalScaling elements: - - label: - text: labels.reconfigurationType - onChange: onReconfigurationTypeChange - options: - - text: Select New Config Secret - value: selectNewConfigSecret - - text: Apply Config - value: applyConfig - - text: Remove - value: remove - required: true - schema: - $ref: discriminator#/properties/reconfigurationType - type: radio - - elements: - - add_new_button: - label: labels.createConfig - target: _blank - url: - function: createSecretUrl - computed: setValueFromDbDetails|/spec/configSecret/name - fetch: getConfigSecrets - label: - text: labels.configSecret - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret/properties/name - type: select - if: ifReconfigurationTypeEqualsTo|selectNewConfigSecret - label: - text: Configuration config secret - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret - type: single-step-form - - addFormLabel: labels.applyConfig.label - element: - discriminator: - configArray: - emitAs: applyConfig - type: array + - type: horizontal-layout elements: - - label: - text: labels.applyConfig.key - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/key - type: input - - label: - text: labels.applyConfig.value - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/value - type: editor - type: single-step-form - if: ifReconfigurationTypeEqualsTo|applyConfig - label: - text: labels.applyConfig.label - onChange: onApplyconfigChange - required: true - schema: - $ref: discriminator#/properties/applyConfig - tableContents: - - inTableColumn: true - label: - text: labels.applyConfig.key - path: key - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.applyConfig.value - path: value - type: value - typeOfValue: code - type: single-step-form-array - - if: returnFalse - label: - text: labels.removeCustomConfig - schema: - $ref: schema#/properties/spec/properties/configuration/properties/removeCustomConfig - type: switch - label: - text: labels.configuration - schema: - $ref: schema#/properties/spec/properties/configuration - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|Reconfigure - label: - text: Reconfigure Form - type: single-step-form - - discriminator: - tlsOperation: - default: update - type: string - elements: - - computed: initTlsOperation - if: hasTlsField - label: - text: labels.tlsOperation - onChange: onTlsOperationChange - options: - - text: Update - value: update - - text: Rotate - value: rotate - - text: Remove - value: remove - schema: - $ref: discriminator#/properties/tlsOperation - type: radio - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/remove - type: switch - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/rotateCertificates - type: switch - - elements: - - computed: setValueFromDbDetails|/spec/requireSSL - label: - text: labels.require_ssl_question - schema: - $ref: schema#/properties/spec/properties/tls/properties/requireSSL - type: switch - - computed: initIssuerRefApiGroup - disabled: true - label: - text: labels.api_group - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup - type: input - - computed: setValueFromDbDetails|/spec/tls/issuerRef/kind - label: - text: labels.kind - options: - - text: Issuer - value: Issuer - - text: ClusterIssuer - value: ClusterIssuer - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/kind - type: select - - allowUserDefinedOption: true - computed: setValueFromDbDetails|/spec/tls/issuerRef/name - fetch: getIssuerRefsName - label: - text: labels.name - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/name - type: select - if: showIssuerRefAndCertificates - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef - type: single-step-form - - alias: reusable_certificates - chart: - name: uibytebuildersdev-component-certificates - version: v0.29.0 - computed: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates - functionCallbacks: - getAliasOptions: - $ref: functions#/getAliasOptions - if: showIssuerRefAndCertificates - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/spec/properties/tls/properties/certificates - type: reusable-element - if: ifRequestTypeEqualsTo|ReconfigureTLS - label: - text: labels.tls - schema: - $ref: schema#/properties/spec/properties/tls - type: single-step-form - - label: - text: labels.timeout - options: - - text: 5 minutes - value: 5m - - text: 10 minutes - value: 10m - - text: 30 minutes - value: 30m - - text: 1 hour - value: 1h - - text: 2 hours - value: 2h - - text: 5 hours - value: 5h - - text: 10 hours - value: 10h - schema: - $ref: schema#/properties/spec/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: labels.apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/spec/properties/apply - type: radio - type: single-step-form - id: basic - title: steps.0.label -type: multi-step-form + - type: input-compare + label: Replicas + header: Replica + subtitle: Define the total number of replicas for the database. Increasing replicas improves fault tolerance and load distribution , while reducing replicas conserves resources + if: + type: function + name: ifDbTypeEqualsTo|cluster|horizontalScaling + init: + type: func + value: setValueFromDbDetails|/spec/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/member + - type: info + 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. +# vertical Scale + - type: block-layout + if: + type: function + name: ifRequestTypeEqualsTo|VerticalScaling + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines + init: + type: func + value: setMachine + watcher: + func: onMachineChange|mariadb|/spec/podTemplate/spec/resources + paths: + - temp/properties/machine + schema: temp/properties/machine + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/mariadb/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired + schema: temp/topologyKey + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired + schema: temp/topologyValue + - type: block-layout + label: Exporter + showLabels: true + hideBlock: true + elements: + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setExporter|cpu + type: input + 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 + watcher: + func: onExporterResourceChange|memory + paths: + - schema/properties/spec/properties/verticalScaling/properties/exporter/properties/resources/properties/limits/properties/memory +# Volume Expansion + - type: block-layout + label: Volume Expansion Form + if: + type: function + name: ifRequestTypeEqualsTo|VolumeExpansion + elements: + - type: horizontal-layout + elements: + - type: block-layout + elements: + - type: label-element + 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: select + label: Mode + options: + - text: Offline + value: Offline + - text: Online + value: Online + validation: + type: required + schema: schema/properties/spec/properties/volumeExpansion/properties/mode + - type: block-layout + label: MariaDB volume expansion + showLabels: true + fixedBlock: true + elements: + - type: horizontal-layout + elements: + - type: input-compare + header: Storage + subtitle: How much extra storage does your database need? Specify the size(e.g. 2Gi for 2 gigabytes) so we can allocate it correctly + label: Storage Size + init: + type: func + value: setValueFromDbDetails|/spec/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/mariadb + schema: schema/properties/spec/properties/volumeExpansion/properties/mariadb +# Reconfigure + - type: block-layout + label: Reconfigure Form + if: + name: ifRequestTypeEqualsTo|Reconfigure + type: function + loader: + name: fetchConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + elements: + - type: block-layout + label: Configuration + elements: + - type: label-element + label: '' + subtitle: Select a new configuration secret, apply a custom configuration, or remove an existing setup to update your database settings + - type: tab-layout + label: New Config Secret + schema: temp/properties/reconfigurationType + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + elements: + - type: block-layout + label: Config Secret + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret + type: function + elements: + - type: label-element + label: Config Secret + subtitle: Select a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: schema/properties/spec/properties/configuration/properties/configSecret/properties/name + refresh: true + label: Config Secret + loader: + name: getConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/createSecret/properties/status + init: + type: func + value: setValueFromDbDetails|/spec/configSecret/name + watcher: + func: onCreateSecretChange + paths: + - temp/properties/createSecret/properties/status + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|create + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + - type: block-layout + label: Create a New Config Secret + showLabels: true + if: + type: function + name: isCreateSecret + hasButton: + text: Save + hasCancel: cancelCreateSecret + action: createNewConfigSecret + elements: + - type: input + label: Secret Name + schema: temp/properties/createSecret/properties/name + validation: + type: required + - type: array-object-form + label: String Data + schema: temp/properties/createSecret/properties/data + buttonClass: is-light is-outlined + validation: + type: required + elements: + - type: select + label: Key + schema: key + loader: + name: onSelectedSecretChange + watchPaths: + - temp/properties/createSecret/properties/data + validation: + type: required + - type: textarea + label: Value + schema: value + - type: multi-file-editor + editorHeight: 500px + readonly: true + if: + type: function + name: isNotCreateSecret + loader: + name: onNewConfigSecretChange + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + schema: temp/properties/newConfigSecret + - type: block-layout + label: ApplyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig + type: function + elements: + - type: label-element + 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). + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfiguration + refresh: true + label: Configuration + loader: getConfigSecretsforAppyConfig + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|apply + watchPaths: + - temp/properties/selectedConfiguration + - type: multi-file-editor + editorHeight: 500px + schema: temp/properties/applyConfig + loader: + name: setApplyConfig + watchPaths: + - temp/properties/selectedConfiguration + watcher: + func: onApplyconfigChange + paths: + - temp/properties/applyConfig + - type: block-layout + label: Remove + if: + name: ifReconfigurationTypeEqualsTo|remove + type: function + elements: + - type: label-element + label: Remove + subtitle: Selected a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfigurationRemove + refresh: true + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|remove + watchPaths: + - temp/properties/selectedConfigurationRemove + - type: multi-file-editor + editorHeight: 500px + readonly: true + init: + type: func + value: onRemoveConfigChange + watcher: + func: onRemoveConfigChange + paths: + - temp/properties/selectedConfigurationRemove + schema: temp/properties/removeConfig +# Reconfigure TLS + - type: block-layout + label: TLS + if: + name: ifRequestTypeEqualsTo|ReconfigureTLS + type: function + elements: + - type: radio + label: TLS Operation + if: + name: hasTlsField + type: function + options: + - text: Update + value: update + - text: Rotate + value: rotate + - text: Remove + value: remove + init: + type: func + value: initTlsOperation + schema: temp/properties/tlsOperation + - type: switch + label: Remove TLS + fullwidth: true + if: + name: isTlsEnabled + type: function + schema: schema/properties/spec/properties/tls/properties/remove + - type: switch + label: Rotate Certificates + fullwidth: true + schema: schema/properties/spec/properties/tls/properties/rotateCertificates + if: + name: isTlsEnabled + type: function + - type: switch + label: Require SSL + fullwidth: true + init: + type: func + value: setValueFromDbDetails|/spec/requireSSL + if: + name: showIssuerRefAndCertificates + type: function + schema: schema/properties/spec/properties/tls/properties/requireSSL + - type: block-layout + label: Issuer Reference + showLabels: true + if: + name: showIssuerRefAndCertificates + type: function + elements: + - type: input + label: API Group + init: + type: func + value: initIssuerRefApiGroup + watcher: + func: initIssuerRefApiGroup + paths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + disable: true + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup + - type: select + label: Kind + options: + - text: Issuer + value: Issuer + - text: ClusterIssuer + value: ClusterIssuer + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/kind + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - type: select + label: Name + loader: + name: getIssuerRefsName + watchPaths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - schema/properties/metadata/properties/namespace + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/name + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/name + - type: block-layout + label: Certificates + showLabels: false + if: + name: showIssuerRefAndCertificates + type: function + loader: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates + elements: + - type: array-object-form + label: Certificates + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/tls/properties/certificates + elements: + - type: select + label: Alias + loader: fetchAliasOptions + disable: disableAlias + schema: alias + validation: + type: required + - type: input + label: Secret Name + schema: secretName + - type: input + label: Duration + schema: duration + - type: input + label: Renew Before + schema: renewBefore + - type: array-item-form + label: Organizations + buttonClass: is-light is-outlined + schema: subject/properties/organizations + element: + type: input + label: Organization + - type: array-item-form + label: Countries + buttonClass: is-light is-outlined + schema: subject/properties/countries + element: + type: input + label: Country + - type: array-item-form + label: Organizational Units + buttonClass: is-light is-outlined + schema: subject/properties/organizationalUnits + element: + type: input + label: Organizational Unit + - type: array-item-form + label: Provinces + buttonClass: is-light is-outlined + schema: subject/properties/provinces + element: + type: input + label: Province + - type: array-item-form + label: DNS Names + buttonClass: is-light is-outlined + schema: dnsNames + element: + type: input + label: DNS Name + - type: array-item-form + label: IP Addresses + buttonClass: is-light is-outlined + schema: ipAddresses + element: + type: input + label: IP Address +# common + - type: block-layout + label: OpsRequest Options + showLabels: true + elements: + - type: time-picker + label: Timeout + schema: 'schema/properties/spec/properties/timeout' + subtitle: Specify the maximum time allowed for the scaling operation to complete. Use formats like 30sec, 1min(1 minute) or 2h(2 hours). + - type: radio + label: Apply + schema: 'schema/properties/spec/properties/apply' + init: + type: func + value: setApplyToIfReady + options: + - text: IfReady (OpsRequest will be applied if database is ready) + value: IfReady + - text: Always (OpsRequest will always be applied) + value: Always \ No newline at end of file diff --git a/charts/opskubedbcom-mariadbopsrequest-editor/ui/functions.js b/charts/opskubedbcom-mariadbopsrequest-editor/ui/functions.js index 8b302af039..7ad7d676c2 100644 --- a/charts/opskubedbcom-mariadbopsrequest-editor/ui/functions.js +++ b/charts/opskubedbcom-mariadbopsrequest-editor/ui/functions.js @@ -1,3 +1,4 @@ +const { axios, useOperator, store, useToast } = window.vueHelpers || {} const machines = { 'db.t.micro': { resources: { @@ -304,181 +305,267 @@ const machineList = [ 'db.r.24xlarge', ] -async function fetchJsons({ axios, itemCtx }) { - let ui = {} - let language = {} - let functions = {} - const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart +let machinesFromPreset = [] +const configSecretKeys = ['kubedb-user.cnf'] - 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) - } +export const useFunc = (model) => { + const route = store.state?.route + const toast = useToast() - return { - ui: ui.data || {}, - language: language.data || {}, - functions, + 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 returnFalse() { + return false + } -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function isTlsEnabled() { + const dbDetails = getValue(discriminator, '/dbDetails') + return ( + (dbDetails?.spec?.sslMode && + dbDetails?.spec?.sslMode !== 'disabled' && + dbDetails?.spec?.sslMode !== 'disable') || + dbDetails?.spec?.tls + ) + } -async function getNamespaces({ axios, storeGet }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + async function getNamespaces() { + if (storeGet('/route/params/actions')) return [] + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - const resources = (resp && resp.data && resp.data.items) || [] + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, + }) - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + const resources = (resp && resp.data && resp.data.items) || [] -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/namespace') + async function getDbs() { + 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/kubedb.com/v1alpha2/namespaces/${namespace}/mariadbs`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + const namespace = getValue(model, '/metadata/namespace') + // watchDependency('model#/metadata/namespace') - const resources = (resp && resp.data && resp.data.items) || [] + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/mariadbs`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + const resources = (resp && resp.data && resp.data.items) || [] -async function getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) { - 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') + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } - if (namespace && name) { - const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/mariadbs/${name}` - const resp = await axios.get(url) + async function getDbDetails() { + machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] - setDiscriminatorValue('/dbDetails', resp.data || {}) + 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') - return resp.data || {} - } else return {} -} + if (namespace && name) { + const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/mariadbs/${name}` + const resp = await axios.get(url) -async function getDbVersions({ axios, storeGet, getValue, discriminator }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + setDiscriminatorValue('/dbDetails', resp.data || {}) - const url = `/clusters/${owner}/${cluster}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/kubedb-ui-presets` + return resp.data || {} + } else return {} + } - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + 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 { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + presetVersions = presets.admin?.databases?.MariaDB?.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/mariadbversions`, + { + 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 allowed = found?.spec?.updateConstraints?.allowlist || [] + 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 filteredDbVersions = 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.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.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.includes(item.metadata?.name)) && + isVersionWithinConstraints(item.spec?.version, limit) + ) + }) + setDiscriminatorValue('/filteredVersion', filteredDbVersions) + return filteredDbVersions.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) - presets.status = String(e.status) + return [] } } - try { - const presetVersions = presets.admin?.databases?.MariaDB?.versions?.available || [] - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null, updateConstraints: null }, - }, - }, + 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 + } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/catalog.kubedb.com/v1alpha1/mariadbversions`, - { - params: queryParams, - }, - ) + 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 + } - const resources = (resp && resp.data && resp.data.items) || [] + 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: [ ' - 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 allowed = found?.spec?.updateConstraints?.allowlist || [] - 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 filteredMariaDBVersions = 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.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.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.includes(item.metadata?.name)) && - isVersionWithinConstraints(item.spec?.version, limit) - ) + presetVersions.forEach((v, idx) => { + txt = `${txt}"${v}"` + if (idx !== presetVersions.length - 1) txt = txt + ', ' + else txt = txt + ' ]' }) - return filteredMariaDBVersions.map((item) => { + return txt + } + + function getVersion() { + return filteredVersion.map((item) => { const name = (item.metadata && item.metadata.name) || '' const specVersion = (item.spec && item.spec.version) || '' return { @@ -486,299 +573,305 @@ async function getDbVersions({ axios, storeGet, getValue, discriminator }) { value: name, } }) - } catch (e) { - console.log(e) - return [] } -} -function versionCompare(v1, v2) { - const arr1 = v1.split('.').map(Number) - const arr2 = v2.split('.').map(Number) + function isVersionEmpty() { + const val = getValue(discriminator, '/filteredVersion') + return val.length === 0 + } - for (let i = 0; i < Math.max(arr1.length, arr2.length); i++) { - const num1 = arr1[i] || 0 - const num2 = arr2[i] || 0 + function ifRequestTypeEqualsTo(type) { + const selectedType = getValue(model, '/spec/type') + // watchDependency('model#/spec/type') - if (num1 > num2) return 1 // v1 is higher - if (num1 < num2) return -1 // v2 is higher + return selectedType === type } - 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 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', + } -function ifRequestTypeEqualsTo({ model, getValue, watchDependency }, type) { - const selectedType = getValue(model, '/spec/type') - watchDependency('model#/spec/type') + Object.keys(reqTypeMapping).forEach((key) => { + if (key !== selectedType) commit('wizard/model$delete', `/spec/${reqTypeMapping[key]}`) + }) + } - return selectedType === type -} + function getDbTls() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') -function onRequestTypeChange({ model, getValue, commit }) { - 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]}`) - }) -} + const { spec } = dbDetails || {} + return spec?.tls || undefined + } -function disableOpsRequest({ itemCtx, discriminator, getValue, watchDependency }) { - if (itemCtx.value === 'HorizontalScaling') { - const dbType = getDbType({ - discriminator, - getValue, - watchDependency, - }) + function getDbType() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') - if (dbType === 'standalone') return true - else return false - } else return false -} + const { spec } = dbDetails || {} + const { replicas } = spec || {} + let verd = '' -function getDbTls({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + if (replicas > 1) { + verd = 'cluster' + } else { + verd = 'standalone' + } - const { spec } = dbDetails || {} - return spec?.tls || undefined -} + return verd + } -function getDbType({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + function disableOpsRequest() { + if (itemCtx.value === 'HorizontalScaling') { + const dbType = getDbType({ + discriminator, + getValue, + }) - const { spec } = dbDetails || {} - const { replicas } = spec || {} - let verd = '' + if (dbType === 'standalone') return true + else return false + } else return false + } - if (replicas > 1) { - verd = 'cluster' - } else { - verd = 'standalone' + function initNamespace() { + const { namespace } = route.query || {} + return namespace || null } - return verd -} + function initDatabaseRef() { + // watchDependency('model#/metadata/namespace') + const { name } = route.params || {} + return name + } -function initNamespace({ route }) { - const { namespace } = route.query || {} - return namespace || null -} + function asDatabaseOperation() { + return !!route.params.actions + } -function initDatabaseRef({ route, watchDependency }) { - watchDependency('model#/metadata/namespace') - const { name } = route.params || {} - return name -} + function generateOpsRequestNameForClusterUI(getValue, model, route) { + const dbName = getValue(model, '/spec/databaseRef/name') -function asDatabaseOperation(route) { - return !!route.params.actions -} + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' -function generateOpsRequestNameForClusterUI(getValue, model, route) { - const dbName = getValue(model, '/spec/databaseRef/name') + const resources = route.params.resource || '' + const resource = resources.slice(0, -1) - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + const opsName = dbName ? dbName : resource + return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` + } - const resources = route.params.resource || '' - const resource = resources.slice(0, -1) + function showAndInitName() { + // watchDependency('model#/spec/type') + // watchDependency('model#/spec/databaseRef/name') + const ver = asDatabaseOperation() - const opsName = dbName ? dbName : resource - return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` -} + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' -function showAndInitName({ route, commit, getValue, model, watchDependency }) { - watchDependency('model#/spec/type') - watchDependency('model#/spec/databaseRef/name') - const ver = asDatabaseOperation(route) + 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 + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + function showAndInitNamespace() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/metadata/namespace', + value: `${route.query.namespace}`, + force: true, + }) + } - 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 } - return !ver -} -function showAndInitNamespace({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/metadata/namespace', - value: `${route.query.namespace}`, - force: true, - }) + + function showAndInitDatabaseRef() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/spec/databaseRef/name', + value: `${route.params.name}`, + force: true, + }) + } + + return !ver } - return !ver -} -function showAndInitDatabaseRef({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/spec/databaseRef/name', - value: `${route.params.name}`, - force: true, - }) + function showConfigureOpsrequestLabel() { + return !asDatabaseOperation() } - return !ver -} -function showConfigureOpsrequestLabel({ route }) { - return !asDatabaseOperation(route) -} -function showAndInitOpsRequestType({ route, commit }) { - const ver = asDatabaseOperation(route) - const opMap = { - upgrade: 'UpdateVersion', - updateVersion: 'UpdateVersion', - horizontalscaling: 'HorizontalScaling', - verticalscaling: 'VerticalScaling', - volumeexpansion: 'VolumeExpansion', - restart: 'Restart', - reconfiguretls: 'ReconfigureTLS', - reconfigure: 'Reconfigure', - } - if (ver) { - const operation = route.params.actions - const match = /^(.*)-opsrequest-(.*)$/.exec(operation) - const opstype = match[2] - commit('wizard/model$update', { - path: '/spec/type', - value: opMap[opstype], - force: true, - }) + 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 } - return !ver -} -// vertical scaling -function ifDbTypeEqualsTo({ discriminator, getValue, watchDependency, commit }, value, opsReqType) { - const verd = getDbType({ - discriminator, - getValue, - watchDependency, - }) - - return value === verd -} + // vertical scaling + function ifDbTypeEqualsTo(value, opsReqType) { + const verd = getDbType() -// machine profile stuffs -let machinesFromPreset = [] + return value === verd + } -function getMachines({ storeGet }) { - const presets = storeGet('/kubedbuiPresets') || {} - const avlMachines = presets.admin?.machineProfiles?.available || [] - let arr = [] - if (avlMachines.length) { - arr = avlMachines.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - 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 } - } else return { text: machine, value: machine } - } - }) - } else { - arr = machineList - .map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + // 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 } } + } }) - .filter((val) => !!val) + } 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 } - return arr -} -function setMachine({ getValue, discriminator, storeGet }) { - const dbDetails = getValue(discriminator, '/dbDetails') - const annotations = dbDetails?.metadata?.annotations || {} - const machine = annotations['kubernetes.io/instance-type'] || 'custom' + 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'] - machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] - - const machinePresets = machinesFromPreset.find((item) => item.id === machine) - if (machinePresets) return machine - else return 'custom' -} + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = instance || {} + } -function onMachineChange({ getValue, discriminator, commit, model }, type, valPath) { - let selectedMachine = '' - selectedMachine = getValue(discriminator, '/machine') - const machine = machinesFromPreset.find((item) => item.id === selectedMachine) + const machine = parsedInstance || 'custom' - let obj = {} - if (selectedMachine !== 'custom') { - if (machine) obj = { limits: { ...machine?.limits }, requests: { ...machine?.limits } } - else obj = machines[selectedMachine]?.resources - } else { - const val = getValue(discriminator, `/dbDetails${valPath}`) || {} - obj = Array.isArray(val) ? val[0]?.resources : { ...val } + 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 } } - const path = `/spec/verticalScaling/${type}/resources` + 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 }, + } + } - if (obj && Object.keys(obj).length) - commit('wizard/model$update', { - path: path, - value: obj, - force: true, - }) + 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') || {} - if (selectedMachine === 'custom') commit('wizard/model$delete', '/metadata/annotations') - else { - annotations['kubernetes.io/instance-type'] = selectedMachine + // 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', @@ -786,517 +879,979 @@ function onMachineChange({ getValue, discriminator, commit, model }, type, valPa force: true, }) } -} -function isMachineCustom({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/machine') - const machine = getValue(discriminator, '/machine') - return machine === 'custom' -} + function isMachineCustom() { + // watchDependency(`discriminator#/machine`) + const machine = getValue(discriminator, `/machine`) + return machine === 'custom' + } -// for config secret -async function getConfigSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + // Fetch and store database Infos + // for secret configurations in reconfigure + let configSecrets = [] + let secretConfigData = [] - const secrets = (resp && resp.data && resp.data.items) || [] + 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 filteredSecrets = secrets + 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') - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return filteredSecrets -} + 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) + } + } -function createSecretUrl({ storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 + } - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/secrets/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/secrets/create` + async function getConfigSecretsforAppyConfig() { + const secrets = secretConfigData.map((item) => { + return { text: item.componentName, value: item.componentName } + }) + return secrets } -} -function isEqualToValueFromType({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/valueFromType') - const valueFrom = getValue(discriminator, '/valueFromType') - return valueFrom === value -} + function getSelectedConfigurationData(type) { + type = type ? type + '/' : '' + const path = `/${type}selectedConfiguration` + const selectedConfiguration = getValue(discriminator, path) -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + if (!selectedConfiguration) { + return [] + } - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + const configuration = secretConfigData.find( + (item) => item.componentName === selectedConfiguration, + ) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, + 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 + }) + } }) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) - } + // Set the value to the model + commit('wizard/model$update', { + path: `/temp/${type}applyConfig`, + value: result, + force: true, + }) - return ans -} -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + return result + } - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` + 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` - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }) + const selectedConfiguration = + configType === 'create' ? getValue(model, path) : getValue(discriminator, path) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + if (selectedConfiguration) + return { subtitle: ` You have selected ${selectedConfiguration} secret` } + else return { subtitle: 'No secret selected' } } - return ans -} -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - group, - version, - resource, -) { - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/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) + 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) } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + 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])) + + 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() } - }) -} -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - 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, + 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 + ) + } -// reconfiguration type -function ifReconfigurationTypeEqualsTo({ discriminator, getValue, watchDependency }, value) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - watchDependency('discriminator#/reconfigurationType') + function isCreateSecret(type) { + type = type ? type + '/' : '' + const selectedSecret = getValue(model, `spec/configuration/${type}configSecret/name`) + const res = selectedSecret === 'Create' - return reconfigurationType === value -} + if (res === true) { + commit('wizard/temp$update', { + path: `${type}createSecret/status`, + value: 'pending', + }) + } + return res + } -function onApplyconfigChange({ discriminator, getValue, commit }) { - const applyconfig = getValue(discriminator, '/applyConfig') + function isNotCreateSecret(type) { + return !isCreateSecret(type) + } - const configObj = {} + 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`) - if (applyconfig) { - applyconfig.forEach((item) => { - const { key, value } = item - configObj[key] = value - }) + const configFound = configSecrets.find((item) => item === name) + return configFound ? { text: name, value: name } : '' + } } - commit('wizard/model$update', { - path: '/spec/configuration/applyConfig', - value: configObj, - force: true, - }) -} + 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', + }) + } -function onReconfigurationTypeChange({ commit, discriminator, getValue, setDiscriminatorValue }) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - setDiscriminatorValue('/applyConfig', []) - if (reconfigurationType === 'remove') { - commit('wizard/model$delete', `/spec/configuration`) + 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) { + 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/removeCustomConfig`, - value: true, - force: true, + path: `/spec/configuration/${type}applyConfig`, + value: tempConfigObj, }) - } 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({ discriminator, getValue, watchDependency }) { - const tls = getDbTls({ - discriminator, - getValue, - watchDependency, - }) + 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], + }) + }) + } else { + configObj.push({ name: '', content: '' }) + } + return configObj + } - return !!tls -} + function onRemoveConfigChange(type) { + type = type ? type + '/' : '' + const configPath = `/${type}selectedConfigurationRemove` + const selectedConfig = getValue(discriminator, configPath) -function initIssuerRefApiGroup({ getValue, model, watchDependency, discriminator }) { - const kind = getValue(model, '/spec/tls/issuerRef/kind') - watchDependency('model#/spec/tls/issuerRef/kind') + if (!selectedConfig) { + commit('wizard/model$delete', `/spec/configuration/${type}removeCustomConfig`) + return [{ name: '', content: '' }] + } + commit('wizard/model$update', { + path: `/spec/configuration/${type}removeCustomConfig`, + value: true, + }) - if (kind) { - const apiGroup = getValue(discriminator, '/dbDetails/spec/tls/issuerRef/apiGroup') - if (apiGroup) return apiGroup - return 'cert-manager.io' - } else return undefined -} + const configuration = secretConfigData.find((item) => item.componentName === selectedConfig) -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - 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` + if (!configuration.data) { + return [{ name: '', content: '' }] + } - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + const configObj = [] + // Decode base64 and format as array of objects with name and content + Object.keys(configuration.data).forEach((fileName) => { try { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + // Decode base64 string + const decodedString = atob(configuration.data[fileName]) + configObj.push({ + name: fileName, + content: decodedString, + }) } catch (e) { - console.log(e) - presets.status = String(e.status) + 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: '' }] } - let clusterIssuers = presets.admin?.clusterIssuers?.available || [] - if (presets.status === '404') { - const url = `/clusters/${owner}/${cluster}/proxy/cert-manager.io/v1/clusterissuers` - return getIssuer(url) + 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: '' }] } - return clusterIssuers } - async function getIssuer(url) { - try { - const resp = await axios.get(url) - const resources = (resp && resp.data && resp.data.items) || [] + function onSelectedSecretChange(index) { + const secretData = getValue(discriminator, 'createSecret/data') || [] + const selfSecrets = secretData.map((item) => item.key) - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + 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 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 } }, + }, }) - return resources + + const items = (resp && resp.data && resp.data.items) || [] + ans = items } catch (e) { console.log(e) - return [] } + + return ans } -} + async function getResourceList({ group, version, resource }) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function initTlsOperation() { - return 'update' -} -function onTlsOperationChange({ discriminator, getValue, commit }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` - commit('wizard/model$delete', '/spec/tls') + let ans = [] + try { + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) - if (tlsOperation === 'rotate') { - commit('wizard/model$update', { - path: '/spec/tls/rotateCertificates', - value: true, - force: true, + 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, }) - 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, + + 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, + } }) - commit('wizard/model$delete', '/spec/tls/certificates') - commit('wizard/model$delete', '/spec/tls/rotateCertificates') } -} + async function unNamespacedResourceNames(group, version, resource) { + let resources = await getResourceList({ + group, + version, + resource, + }) -function showIssuerRefAndCertificates({ discriminator, getValue, watchDependency }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') - watchDependency('discriminator#/tlsOperation') - const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } - return verd -} + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -function isIssuerRefRequired({ discriminator, getValue, watchDependency }) { - const hasTls = hasTlsField({ - discriminator, - getValue, - watchDependency, - }) + // reconfiguration type + function ifReconfigurationTypeEqualsTo(value) { + const reconfigurationType = getValue(discriminator, '/reconfigurationType') - return !hasTls -} + const watchPath = `discriminator#/reconfigurationType` + // watchDependency(watchPath) + return reconfigurationType === value + } -function getRequestTypeFromRoute({ route, model, discriminator, getValue, watchDependency }) { - const isDbloading = isDbDetailsLoading({ - discriminator, - model, - getValue, - watchDependency, - }) - const { query } = route || {} - const { requestType } = query || {} - return isDbloading ? '' : requestType || '' -} + function onReconfigurationTypeChange() { + setDiscriminatorValue(`/applyConfig`, []) + const reconfigurationType = getValue(discriminator, '/reconfigurationType') + if (reconfigurationType === 'remove') { + commit('wizard/model$delete', `/spec/configuration`) -// ************************************** Set db details ***************************************** + 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`) + } + } -function isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - watchDependency('model#/spec/databaseRef/name') - const dbDetails = getValue(discriminator, '/dbDetails') - const dbName = getValue(model, '/spec/databaseRef/name') + // for tls + function hasTlsField() { + const tls = getDbTls() - return !dbDetails || !dbName -} + return !!tls + } -function setValueFromDbDetails( - { discriminator, getValue, watchDependency, commit }, - path, - commitPath, -) { - watchDependency('discriminator#/dbDetails') + 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 [] + } - const retValue = getValue(discriminator, `/dbDetails${path}`) + 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 [] + } + } + } - if (commitPath && retValue) { + function initTlsOperation() { + return 'update' + } + function onTlsOperationChange() { const tlsOperation = getValue(discriminator, '/tlsOperation') - // computed called when tls fields is not visible - if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined + commit('wizard/model$delete', '/spec/tls') - // 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, - }) + 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') + } } - return retValue || undefined -} + function showIssuerRefAndCertificates() { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // watchDependency('discriminator#/tlsOperation') + const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} + return verd + } -function isNamespaceDisabled({ route }) { - const { namespace } = route.query || {} - return !!namespace -} + function isIssuerRefRequired() { + const hasTls = hasTlsField() + return hasTls ? false : '' + } -function isDatabaseRefDisabled({ route }) { - const { name } = route.params || {} - return !!name -} + function getRequestTypeFromRoute() { + const isDbloading = isDbDetailsLoading() + const { query } = route || {} + const { requestType } = query || {} + return isDbloading ? '' : requestType || '' + } -function onNamespaceChange({ commit }) { - commit('wizard/model$delete', '/spec/type') -} + function isDbDetailsLoading() { + // watchDependency('discriminator#/dbDetails') + // watchDependency('model#/spec/databaseRef/name') + const dbDetails = getValue(discriminator, '/dbDetails') + const dbName = getValue(model, '/spec/databaseRef/name') -function onDbChange({ commit, axios, storeGet, model, getValue, setDiscriminatorValue }) { - commit('wizard/model$delete', '/spec/type') - getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) -} + return !dbDetails || !dbName + } -function setApplyToIfReady() { - return 'IfReady' -} + function setValueFromDbDetails(path, commitPath) { + const retValue = getValue(discriminator, `/dbDetails${path}`) + + if (commitPath) { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // computed called when tls fields is not visible + if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined -function isVerticalScaleTopologyRequired({ watchDependency, getValue, discriminator, commit }) { - watchDependency('discriminator#/topologyKey') - watchDependency('discriminator#/topologyValue') + // 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 + } - const key = getValue(discriminator, '/topologyKey') - const value = getValue(discriminator, '/topologyValue') - const path = `/spec/verticalScaling/mariadb/topology` + function getAliasOptions() { + return ['server', 'client', 'metrics-exporter'] + } - if (key || value) { - commit('wizard/model$update', { - path: path, - value: { key, value }, - force: true, + 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/mariadb/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' + console.log('data -> ', item.value, data) + } }) - return true - } else { - commit('wizard/model$delete', path) - return false + return data || 'No Data Found' } -} -function checkVolume({ model, discriminator, getValue }, initpath, path) { - const volume = getValue(discriminator, `/dbDetails${initpath}`) - const input = getValue(model, path) + function setExporter(type) { + let path = `/dbDetails/spec/monitor/prometheus/exporter/resources/limits/${type}` + const limitVal = getValue(discriminator, path) - try { - const sizeInBytes = parseSize(volume) - const inputSizeInBytes = parseSize(input) + if (!limitVal) { + path = `/dbDetails/spec/monitor/prometheus/exporter/resources/requests/${type}` + const reqVal = getValue(discriminator, path) - if (inputSizeInBytes >= sizeInBytes) return true - else return 'Cannot expand to lower volume!' - } catch (err) { - return err.message || 'Invalid' + if (reqVal) return reqVal + } + return limitVal } -} -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 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, + }) + } -return { - fetchJsons, - returnFalse, - getNamespaces, - getDbs, - getDbDetails, - getDbVersions, - ifRequestTypeEqualsTo, - onRequestTypeChange, - getDbTls, - getDbType, - initNamespace, - initDatabaseRef, - isRancherManaged, - showAndInitName, - showAndInitNamespace, - showAndInitDatabaseRef, - showConfigureOpsrequestLabel, - showAndInitOpsRequestType, - - ifDbTypeEqualsTo, - getConfigSecrets, - createSecretUrl, - isEqualToValueFromType, - disableOpsRequest, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - ifReconfigurationTypeEqualsTo, - onReconfigurationTypeChange, - onApplyconfigChange, - hasTlsField, - initIssuerRefApiGroup, - getIssuerRefsName, - initTlsOperation, - onTlsOperationChange, - showIssuerRefAndCertificates, - isIssuerRefRequired, - getRequestTypeFromRoute, - isDbDetailsLoading, - setValueFromDbDetails, - getAliasOptions, - isNamespaceDisabled, - isDatabaseRefDisabled, - onNamespaceChange, - onDbChange, - setApplyToIfReady, - isVerticalScaleTopologyRequired, - getMachines, - setMachine, - onMachineChange, - isMachineCustom, - checkVolume, + return { + 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, + isNamespaceDisabled, + isDatabaseRefDisabled, + onDbChange, + onNamespaceChange, + setApplyToIfReady, + isVerticalScaleTopologyRequired, + getMachines, + setMachine, + onMachineChange, + isMachineCustom, + checkVolume, + fetchConfigSecrets, + getConfigSecretsforAppyConfig, + getSelectedConfigurationData, + getSelectedConfigurationName, + getSelectedConfigurationValueForRemove, + createNewConfigSecret, + decodeError, + isCreateSecret, + isNotCreateSecret, + onCreateSecretChange, + cancelCreateSecret, + setApplyConfig, + onRemoveConfigChange, + onNewConfigSecretChange, + onSelectedSecretChange, + isTlsEnabled, + } } diff --git a/charts/opskubedbcom-memcachedopsrequest-editor/ui/create-ui.yaml b/charts/opskubedbcom-memcachedopsrequest-editor/ui/create-ui.yaml index f76693a10b..8ef8200925 100644 --- a/charts/opskubedbcom-memcachedopsrequest-editor/ui/create-ui.yaml +++ b/charts/opskubedbcom-memcachedopsrequest-editor/ui/create-ui.yaml @@ -1,295 +1,417 @@ -steps: -- form: - discriminator: - dbDetails: - type: object +type: multi-step-form +step: + - type: single-step-form + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - schema: - $ref: discriminator#/properties/dbDetails - type: input - - if: showAndInitName - label: - text: labels.op_req_name - required: true - schema: - $ref: schema#/properties/metadata/properties/name - type: input - - computed: initNamespace - disabled: isNamespaceDisabled - fetch: getNamespaces - hasGroup: isRancherManaged - if: showAndInitNamespace - label: - text: labels.namespace - onChange: onNamespaceChange - required: true - schema: - $ref: schema#/properties/metadata/properties/namespace - type: select - - computed: initDatabaseRef - disabled: isDatabaseRefDisabled - fetch: getDbs - if: showAndInitDatabaseRef - label: - text: labels.databaseRef - onChange: onDbChange - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/databaseRef/properties/name - type: select - - if: showConfigureOpsrequestLabel - label: - text: labels.config_ops_request - type: label-element - - computed: getRequestTypeFromRoute - disabled: isDbDetailsLoading - hasDescription: true - if: showAndInitOpsRequestType - individualItemDisabilityCheck: disableOpsRequest - label: - text: labels.ops_request_type - onChange: onRequestTypeChange - options: - - description: options.UpdateVersion.description - text: options.UpdateVersion.text - value: UpdateVersion - - description: options.HorizontalScaling.description - text: options.HorizontalScaling.text - value: HorizontalScaling - - description: options.VerticalScaling.description - text: options.VerticalScaling.text - value: VerticalScaling - - description: options.Restart.description - text: options.Restart.text - value: Restart - - description: options.Reconfigure.description - text: options.Reconfigure.text - value: Reconfigure - schema: - $ref: schema#/properties/spec/properties/type - type: radio - - elements: - - computed: setValueFromDbDetails|/spec/version - fetch: getDbVersions - label: - text: labels.targetVersion - schema: - $ref: schema#/properties/spec/properties/updateVersion/properties/targetVersion - type: select - if: ifRequestTypeEqualsTo|UpdateVersion - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/replicas - if: ifDbTypeEqualsTo|Combined|horizontalScaling - label: - text: Replicas - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/replicas - type: input - if: ifRequestTypeEqualsTo|HorizontalScaling - label: - text: Horizontal Scaling Form - type: single-step-form - - elements: - - discriminator: - machine: - default: "" - type: string +# common + - type: input + label: op_req_name + if: + type: function + name: showAndInitName + validation: + type: required + schema: schema/properties/metadata/properties/name + - type: select + label: Namespace + if: + type: function + name: showAndInitNamespace + init: + type: func + value: initNamespace + disable: isNamespaceDisabled + loader: getNamespaces + validation: + type: required + hasGroup: isRancherManaged + schema: schema/properties/metadata/properties/namespace + - type: select + label: Database Ref + if: + type: function + name: showAndInitDatabaseRef + loader: + name: getDbs + watchPaths: + - schema/properties/metadata/properties/namespace + init: + type: func + value: initDatabaseRef + validation: + type: required + disable: isDatabaseRefDisabled + refresh: true + watcher: + func: onDbChange + paths: + - schema/properties/spec/properties/databaseRef/properties/name + schema: schema/properties/spec/properties/databaseRef/properties/name + - type: label-element + label: config_ops_request + if: + type: function + name: showConfigureOpsrequestLabel + - type: radio + label: Type of Ops Request + if: + type: function + name: showAndInitOpsRequestType + 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: Restart your database + text: Restart + value: Restart + - description: Reconfigure your database + text: Reconfigure + value: Reconfigure + init: + type: func + value: getRequestTypeFromRoute + disable: isDbDetailsLoading + watcher: + func: isDbDetailsLoading + paths: + - temp/dbDetails + - schema/properties/spec/properties/databaseRef/properties/name + isHorizontal: true + schema: schema/properties/spec/properties/type +# UpdateVersion + - type: block-layout + showLabels: true + label: Version + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|UpdateVersion + elements: + - type: select + label: Target Version + subtitle: Select the desired Memcached version to which you want to update your database. + init: + type: func + value: setValueFromDbDetails|/spec/version + loader: getDbVersions + schema: schema/properties/spec/properties/updateVersion/properties/targetVersion + - type: info + label: '' + loader: + name: getVersionInfo + watchPaths: + - temp/properties/filteredVersion + if: + type: function + name: isVersionEmpty +# Horizontal Scale + - type: block-layout + label: Horizontal Scaling Form + showLabels: true + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|HorizontalScaling elements: - - computed: setMachine - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|memcached|/spec/podTemplate/spec/resources - schema: - $ref: discriminator#/machine - type: select - - if: isMachineCustom - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/memcached/properties/resources - type: resource-input-form - - label: - text: Node Selection Policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/memcached/properties/nodeSelectionPolicy - type: select - - elements: - - label: - text: key - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/memcached/properties/topology/properties/key - type: input - - label: - text: value - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/memcached/properties/topology/properties/value - type: input - label: - text: Topology - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/memcached/properties/topology - show_label: true - type: single-step-form - label: - text: Memcached - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/memcached - show_label: true - type: single-step-form - - computed: setResource|/spec/podTemplate/spec/containers - label: - text: Exporter - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/exporter/properties/resources - type: resource-input-form - - label: - text: Readiness Criteria - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/readinessCriteria - type: input - if: ifRequestTypeEqualsTo|VerticalScaling - type: single-step-form - - elements: - - discriminator: - reconfigurationType: - type: string + - type: input-compare + label: Replicas + if: + type: function + name: ifDbTypeEqualsTo|Combined|horizontalScaling + init: + type: func + value: setValueFromDbDetails|/spec/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/replicas +# vertical Scale + - type: block-layout + if: + type: function + name: ifRequestTypeEqualsTo|VerticalScaling elements: - - label: - text: labels.reconfigurationType - onChange: onReconfigurationTypeChange - options: - - text: Select New Config Secret - value: selectNewConfigSecret - - text: Apply Config - value: applyConfig - - text: Remove - value: remove - required: true - schema: - $ref: discriminator#/properties/reconfigurationType - type: radio - - elements: - - add_new_button: - label: labels.createConfig - target: _blank - url: - function: createSecretUrl - computed: setValueFromDbDetails|/spec/configSecret/name - fetch: getConfigSecrets - label: - text: labels.configSecret - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret/properties/name - type: select - if: ifReconfigurationTypeEqualsTo|selectNewConfigSecret - label: - text: Configuration config secret - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret - type: single-step-form - - addFormLabel: labels.applyConfig.label - element: - discriminator: - configArray: - emitAs: applyConfig - type: array + - type: block-layout + label: Memcached Vertical Scaling + showLabels: false elements: - - label: - text: labels.applyConfig.key - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/key - type: input - - label: - text: labels.applyConfig.value - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/value - type: editor - type: single-step-form - if: ifReconfigurationTypeEqualsTo|applyConfig - label: - text: labels.applyConfig.label - onChange: onApplyconfigChange - required: true - schema: - $ref: discriminator#/properties/applyConfig - tableContents: - - inTableColumn: true - label: - text: labels.applyConfig.key - path: key - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.applyConfig.value - path: value - type: value - typeOfValue: code - type: single-step-form-array - - if: returnFalse - label: - text: labels.removeCustomConfig - schema: - $ref: schema#/properties/spec/properties/configuration/properties/removeCustomConfig - type: switch - label: - text: labels.configuration - schema: - $ref: schema#/properties/spec/properties/configuration - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|Reconfigure - label: - text: Reconfigure Form - type: single-step-form - - label: - text: labels.timeout - options: - - text: 5 minutes - value: 5m - - text: 10 minutes - value: 10m - - text: 30 minutes - value: 30m - - text: 1 hour - value: 1h - - text: 2 hours - value: 2h - - text: 5 hours - value: 5h - - text: 10 hours - value: 10h - schema: - $ref: schema#/properties/spec/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: labels.apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/spec/properties/apply - type: radio - type: single-step-form - id: basic - title: steps.0.label -type: multi-step-form + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines + init: + type: func + value: setMachine + watcher: + func: onMachineChange|memcached|/spec/podTemplate/spec/resources + paths: + - temp/properties/machine + schema: temp/properties/machine + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/memcached/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|memcached + schema: temp/topologyKey-memcached + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|memcached + schema: temp/topologyValue-memcached + - type: block-layout + label: Exporter + showLabels: true + hideBlock: true + elements: + - type: label-element + label: Exporter + subtitle: Configure resource requests for the exporter. These settings determine the CPU and memory allocated to monitor your database metrics. + - type: horizontal-layout + showLabels: true + elements: + - type: input + label: CPU + init: + type: func + value: setExporter|memcached|cpu + schema: schema/properties/spec/properties/verticalScaling/properties/exporter/properties/resources/properties/requests/properties/cpu + - type: input + label: Memory + init: + type: func + value: setExporter|memcached|memory + schema: schema/properties/spec/properties/verticalScaling/properties/exporter/properties/resources/properties/requests/properties/memory + watcher: + func: onExporterResourceChange|memcached + paths: + - schema/properties/spec/properties/verticalScaling/properties/exporter/properties/resources/properties/requests/properties/memory +# Reconfigure + - type: block-layout + label: Reconfigure Form + if: + name: ifRequestTypeEqualsTo|Reconfigure + type: function + loader: + name: fetchConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + elements: + - type: label-element + label: '' + subtitle: Select a new configuration secret, apply a custom configuration, or remove an existing setup to update your database settings + - type: block-layout + label: Configuration + showLabels: false + elements: + - type: tab-layout + label: New Config Secret + schema: temp/properties/reconfigurationType + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + elements: + - type: block-layout + label: Config Secret + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret + type: function + elements: + - type: label-element + label: Config Secret + subtitle: Select a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: schema/properties/spec/properties/configuration/properties/configSecret/properties/name + refresh: true + label: Config Secret + loader: + name: getConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/createSecret/properties/status + init: + type: func + value: setValueFromDbDetails|/spec/configSecret/name + watcher: + func: onCreateSecretChange + paths: + - temp/properties/createSecret/properties/status + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|create + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + - type: block-layout + label: Create a New Config Secret + showLabels: true + if: + type: function + name: isCreateSecret + hasButton: + text: Save + hasCancel: cancelCreateSecret + action: createNewConfigSecret + elements: + - type: input + label: Secret Name + schema: temp/properties/createSecret/properties/name + validation: + type: required + - type: array-object-form + label: String Data + schema: temp/properties/createSecret/properties/data + buttonClass: is-light is-outlined + validation: + type: required + elements: + - type: select + label: Key + schema: key + loader: + name: onSelectedSecretChange + watchPaths: + - temp/properties/createSecret/properties/data + validation: + type: required + - type: textarea + label: Value + schema: value + - type: multi-file-editor + editorHeight: 500px + readonly: true + if: + type: function + name: isNotCreateSecret + loader: + name: onNewConfigSecretChange + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + schema: temp/properties/newConfigSecret + - type: block-layout + label: ApplyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig + type: function + elements: + - type: label-element + 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). + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfiguration + refresh: true + label: Configuration + loader: getConfigSecretsforAppyConfig + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|apply + watchPaths: + - temp/properties/selectedConfiguration + - type: multi-file-editor + editorHeight: 500px + schema: temp/properties/applyConfig + loader: + name: setApplyConfig + watchPaths: + - temp/properties/selectedConfiguration + watcher: + func: onApplyconfigChange + paths: + - temp/properties/applyConfig + - type: block-layout + label: Remove + if: + name: ifReconfigurationTypeEqualsTo|remove + type: function + elements: + - type: label-element + label: Remove + subtitle: Selected a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfigurationRemove + refresh: true + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|remove + watchPaths: + - temp/properties/selectedConfigurationRemove + - type: multi-file-editor + editorHeight: 500px + readonly: true + init: + type: func + value: onRemoveConfigChange + watcher: + func: onRemoveConfigChange + paths: + - temp/properties/selectedConfigurationRemove + schema: temp/properties/removeConfig +# common + - type: block-layout + label: OpsRequest Options + showLabels: true + elements: + - type: time-picker + label: Timeout + schema: schema/properties/spec/properties/timeout + subtitle: Specify the maximum time allowed for the scaling operation to complete. Use formats like 30sec, 1min(1 minute) or 2h(2 hours). + - type: radio + label: Apply + schema: schema/properties/spec/properties/apply + init: + type: func + value: setApplyToIfReady + options: + - text: IfReady (OpsRequest will be applied if database is ready) + value: IfReady + - text: Always (OpsRequest will always be applied) + value: Always \ No newline at end of file diff --git a/charts/opskubedbcom-memcachedopsrequest-editor/ui/functions.js b/charts/opskubedbcom-memcachedopsrequest-editor/ui/functions.js index cbde06300c..1ea82c1a45 100644 --- a/charts/opskubedbcom-memcachedopsrequest-editor/ui/functions.js +++ b/charts/opskubedbcom-memcachedopsrequest-editor/ui/functions.js @@ -1,3 +1,4 @@ +const { axios, useOperator, store, useToast } = window.vueHelpers || {} const machines = { 'db.t.micro': { resources: { @@ -304,182 +305,258 @@ const machineList = [ 'db.r.24xlarge', ] -async function fetchJsons({ axios, itemCtx }) { - let ui = {} - let language = {} - let functions = {} - const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart +let machinesFromPreset = [] +const configSecretKeys = ['kubedb-user.cnf'] - 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) - } +export const useFunc = (model) => { + const route = store.state?.route + const toast = useToast() - return { - ui: ui.data || {}, - language: language.data || {}, - functions, - } -} - -function returnFalse() { - return false -} + const { getValue, storeGet, discriminator, setDiscriminatorValue, commit } = useOperator( + model, + store.state, + ) -async function getNamespaces({ axios, storeGet }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + showAndInitOpsRequestType() - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + async function fetchJsons({ axios, itemCtx }) { + let ui = {} + let language = {} + let functions = {} + const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart - const resources = (resp && resp.data && resp.data.items) || [] + 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 resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' return { - text: name, - value: name, + ui: ui.data || {}, + language: language.data || {}, + functions, } - }) -} + } -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function returnFalse() { + return false + } -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/namespace') + 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/kubedb.com/v1alpha2/namespaces/${namespace}/memcacheds`, - { + 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) || [] + const resources = (resp && resp.data && resp.data.items) || [] - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + 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') -async function getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) { - 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') + const namespace = getValue(model, '/metadata/namespace') + // watchDependency('model#/metadata/namespace') - if (namespace && name) { const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/memcacheds/${name}`, + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/memcacheds`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, ) - setDiscriminatorValue('/dbDetails', resp.data || {}) + const resources = (resp && resp.data && resp.data.items) || [] - return resp.data || {} - } else return {} -} + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -async function getDbVersions({ axios, storeGet, getValue, discriminator }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + async function getDbDetails() { + machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] - const url = `/clusters/${owner}/${cluster}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/kubedb-ui-presets` + 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') - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + if (namespace && name) { + const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/memcacheds/${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 { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + presetVersions = presets.admin?.databases?.Memcached?.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/memcachedversions`, + { + 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 allowed = found?.spec?.updateConstraints?.allowlist || [] + 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 filteredMemcachedVersions = 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.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.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.includes(item.metadata?.name)) && + isVersionWithinConstraints(item.spec?.version, limit) + ) + }) + setDiscriminatorValue('/filteredVersion', filteredMemcachedVersions) + return filteredMemcachedVersions.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) - presets.status = String(e.status) + return [] } } - try { - const presetVersions = presets.admin?.databases?.Memcached?.versions?.available || [] - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null, updateConstraints: null }, - }, - }, + 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 + } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/catalog.kubedb.com/v1alpha1/memcachedversions`, - { - params: queryParams, - }, - ) + 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 + } - const resources = (resp && resp.data && resp.data.items) || [] + 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: [ ' - 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 allowed = found?.spec?.updateConstraints?.allowlist || [] - 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 filteredMemcachedVersions = 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.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.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.includes(item.metadata?.name)) && - isVersionWithinConstraints(item.spec?.version, limit) - ) + presetVersions.forEach((v, idx) => { + txt = `${txt}"${v}"` + if (idx !== presetVersions.length - 1) txt = txt + ', ' + else txt = txt + ' ]' }) - return filteredMemcachedVersions.map((item) => { + return txt + } + + function getVersion() { + return filteredVersion.map((item) => { const name = (item.metadata && item.metadata.name) || '' const specVersion = (item.spec && item.spec.version) || '' return { @@ -487,766 +564,1040 @@ async function getDbVersions({ axios, storeGet, getValue, discriminator }) { value: name, } }) - } catch (e) { - console.log(e) - return [] } -} -function versionCompare(v1, v2) { - const arr1 = v1.split('.').map(Number) - const arr2 = v2.split('.').map(Number) + function isVersionEmpty() { + const val = getValue(discriminator, '/filteredVersion') + return val.length === 0 + } - for (let i = 0; i < Math.max(arr1.length, arr2.length); i++) { - const num1 = arr1[i] || 0 - const num2 = arr2[i] || 0 + function ifRequestTypeEqualsTo(type) { + const selectedType = getValue(model, '/spec/type') + // watchDependency('model#/spec/type') - if (num1 > num2) return 1 // v1 is higher - if (num1 < num2) return -1 // v2 is higher + return selectedType === type } - 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() + 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', + } - let comparison = versionCompare(version, constraintVersion) - if ( - (operator === '>=' && comparison < 0) || - (operator === '<=' && comparison > 0) || - (operator === '>' && comparison <= 0) || - (operator === '<' && comparison >= 0) - ) - return false + Object.keys(reqTypeMapping).forEach((key) => { + if (key !== selectedType) commit('wizard/model$delete', `/spec/${reqTypeMapping[key]}`) + }) } - return true -} -function ifRequestTypeEqualsTo({ model, getValue, watchDependency }, type) { - const selectedType = getValue(model, '/spec/type') - watchDependency('model#/spec/type') + function getDbTls() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') - return selectedType === type -} + const { spec } = dbDetails || {} + return spec?.tls || undefined + } -function onRequestTypeChange({ model, getValue, commit }) { - 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 getDbType() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') -function disableOpsRequest({ itemCtx, discriminator, getValue, watchDependency }) { - if (itemCtx.value === 'HorizontalScaling') { - const dbType = getDbType({ - discriminator, - getValue, - watchDependency, - }) + const { spec } = dbDetails || {} + const { topology } = spec || {} + if (topology) return 'Topology' + else return 'Combined' + } - if (dbType === 'Standalone') return true - else return false - } else return false -} + function disableOpsRequest() { + if (itemCtx.value === 'HorizontalScaling') { + const dbType = getDbType({ + discriminator, + getValue, + }) -function getDbTls({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + if (dbType === 'Standalone') return true + else return false + } else return false + } - const { spec } = dbDetails || {} - return spec?.tls || undefined -} + function initNamespace() { + const { namespace } = route.query || {} + return namespace || null + } -function getDbType({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') - const { spec } = dbDetails || {} - const { topology } = spec || {} - if (topology) return 'Topology' - else return 'Combined' -} + function initDatabaseRef() { + // watchDependency('model#/metadata/namespace') + const { name } = route.params || {} + return name + } -function initNamespace({ route }) { - const { namespace } = route.query || {} - return namespace || null -} + function asDatabaseOperation() { + return !!route.params.actions + } -function initDatabaseRef({ route, watchDependency }) { - watchDependency('model#/metadata/namespace') - const { name } = route.params || {} - return name -} + function generateOpsRequestNameForClusterUI(getValue, model, route) { + const dbName = getValue(model, '/spec/databaseRef/name') -function asDatabaseOperation(route) { - return !!route.params.actions -} + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' -function generateOpsRequestNameForClusterUI(getValue, model, route) { - const dbName = getValue(model, '/spec/databaseRef/name') + const resources = route.params.resource || '' + const resource = resources.slice(0, -1) - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + const opsName = dbName ? dbName : resource + return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` + } - const resources = route.params.resource || '' - const resource = resources.slice(0, -1) + function showAndInitName() { + // watchDependency('model#/spec/type') + // watchDependency('model#/spec/databaseRef/name') + const ver = asDatabaseOperation() - const opsName = dbName ? dbName : resource - return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` -} + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' -function showAndInitName({ route, commit, getValue, model, watchDependency }) { - watchDependency('model#/spec/type') - watchDependency('model#/spec/databaseRef/name') - const ver = asDatabaseOperation(route) + 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 + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + function showAndInitNamespace() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/metadata/namespace', + value: `${route.query.namespace}`, + force: true, + }) + } - 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({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/metadata/namespace', - value: `${route.query.namespace}`, - force: true, - }) + return !ver } - return !ver -} -function showAndInitDatabaseRef({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/spec/databaseRef/name', - value: `${route.params.name}`, - force: true, - }) + function showAndInitDatabaseRef() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/spec/databaseRef/name', + value: `${route.params.name}`, + force: true, + }) + } + + return !ver } - return !ver -} -function showConfigureOpsrequestLabel({ route }) { - return !asDatabaseOperation(route) -} -function showAndInitOpsRequestType({ route, commit }) { - const ver = asDatabaseOperation(route) - const opMap = { - upgrade: 'UpdateVersion', - updateVersion: 'UpdateVersion', - horizontalscaling: 'HorizontalScaling', - verticalscaling: 'VerticalScaling', - volumeexpansion: 'VolumeExpansion', - restart: 'Restart', - reconfiguretls: 'ReconfigureTLS', - reconfigure: 'Reconfigure', - } - if (ver) { - const operation = route.params.actions - const match = /^(.*)-opsrequest-(.*)$/.exec(operation) - const opstype = match[2] - commit('wizard/model$update', { - path: '/spec/type', - value: opMap[opstype], - force: true, - }) + function showConfigureOpsrequestLabel() { + return !asDatabaseOperation() } - return !ver -} + 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, + }) + } + } -// vertical scaling -function ifDbTypeEqualsTo({ discriminator, getValue, watchDependency, commit }, value, opsReqType) { - const verd = getDbType({ - discriminator, - getValue, - watchDependency, - }) - return value === verd -} + return !ver + } -// machine profile stuffs -let machinesFromPreset = [] + // vertical scaling + function ifDbTypeEqualsTo(value, opsReqType) { + const verd = getDbType() -function getMachines({ storeGet }) { - const presets = storeGet('/kubedbuiPresets') || {} - const avlMachines = presets.admin?.machineProfiles?.available || [] - let arr = [] - if (avlMachines.length) { - arr = avlMachines.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - 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 } - } else return { text: machine, value: machine } - } - }) - } else { - arr = machineList - .map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } - }) - .filter((val) => !!val) + return value === verd } - return arr -} -function setMachine({ getValue, discriminator, storeGet }) { - const dbDetails = getValue(discriminator, '/dbDetails') - const annotations = dbDetails?.metadata?.annotations || {} - const machine = annotations['kubernetes.io/instance-type'] || 'custom' + // machine profile stuffs + 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 + } - machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] + 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 - else return '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({ getValue, discriminator, commit, model }, type, valPath) { - let selectedMachine = '' - selectedMachine = getValue(discriminator, '/machine') - const machine = machinesFromPreset.find((item) => item.id === selectedMachine) + 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 }, + } + } - let obj = {} - if (selectedMachine !== 'custom') { - if (machine) obj = { limits: { ...machine?.limits }, requests: { ...machine?.limits } } - else obj = machines[selectedMachine]?.resources - } else { - const val = getValue(discriminator, `/dbDetails${valPath}`) || {} - obj = Array.isArray(val) ? val[0]?.resources : { ...val } - } + const path = `/spec/verticalScaling/${type}/resources` - const path = `/spec/verticalScaling/${type}/resources` + if (obj && Object.keys(obj).length) + commit('wizard/model$update', { + path: path, + value: obj, + force: true, + }) - 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') || {} + const instance = annotations['kubernetes.io/instance-type'] + let parsedInstance = {} + try { + if (instance) parsedInstance = instance + } catch (e) { + console.log(e) + parsedInstance = instance || {} + } + parsedInstance = selectedMachine.machine + annotations['kubernetes.io/instance-type'] = JSON.stringify(parsedInstance) - // update metadata.annotations - const annotations = getValue(model, '/metadata/annotations') || {} - if (selectedMachine === 'custom') commit('wizard/model$delete', '/metadata/annotations') - else { - annotations['kubernetes.io/instance-type'] = selectedMachine if (machinesFromPreset.length) commit('wizard/model$update', { path: '/metadata/annotations', value: annotations, force: true, }) + + if ( + !parsedInstance || + (typeof parsedInstance === 'object' && Object.keys(parsedInstance).length === 0) + ) + commit('wizard/model$delete', '/metadata/annotations') } -} -function isMachineCustom({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/machine') - const machine = getValue(discriminator, '/machine') - return machine === 'custom' -} + function isMachineCustom(path) { + // watchDependency(`discriminator#${path}`) + const machine = getValue(discriminator, `${path}`) + return machine === 'custom' + } -// for config secret -async function getConfigSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + // Fetch and store database Infos + // for secret configurations in reconfigure + let configSecrets = [] + let secretConfigData = [] - const secrets = (resp && resp.data && resp.data.items) || [] + 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 filteredSecrets = secrets + 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') - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return filteredSecrets -} + 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) + } + } -function createSecretUrl({ storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 + } - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/secrets/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/secrets/create` + async function getConfigSecretsforAppyConfig() { + const secrets = secretConfigData.map((item) => { + return { text: item.componentName, value: item.componentName } + }) + return secrets } -} -function isEqualToValueFromType({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/valueFromType') - const valueFrom = getValue(discriminator, '/valueFromType') - return valueFrom === value -} + function getSelectedConfigurationData(type) { + type = type ? type + '/' : '' + const path = `/${type}selectedConfiguration` + const selectedConfiguration = getValue(discriminator, path) -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + if (!selectedConfiguration) { + return [] + } - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + const configuration = secretConfigData.find( + (item) => item.componentName === selectedConfiguration, + ) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, + 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 + }) + } }) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + // Set the value to the model + commit('wizard/model$update', { + path: `/temp/${type}applyConfig`, + value: result, + force: true, + }) + + return result } - return ans -} -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` + const selectedConfiguration = + configType === 'create' ? getValue(model, path) : getValue(discriminator, path) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, + 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 + } }) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + // Convert data object back to YAML string + return yaml.dump(data) } - return ans -} -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - group, - version, - resource, -) { - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/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) - }) + 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])) + + 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 resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + function decodeError(msg, defaultMsg) { + if (typeof msg === 'string') { + return msg || defaultMsg } - }) -} -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) - - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) + return ( + (msg.response && msg.response.data && msg.response.data.message) || + (msg.response && msg.response.data) || + (msg.status && msg.status.status) || + defaultMsg + ) } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + 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 + } -// reconfiguration type -function ifReconfigurationTypeEqualsTo({ discriminator, getValue, watchDependency }, value) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - watchDependency('discriminator#/reconfigurationType') + function isNotCreateSecret(type) { + return !isCreateSecret(type) + } - return reconfigurationType === value -} + 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`) -function onApplyconfigChange({ discriminator, getValue, commit }) { - const applyconfig = getValue(discriminator, '/applyConfig') + const configFound = configSecrets.find((item) => item === name) + return configFound ? { text: name, value: name } : '' + } + } - const configObj = {} - if (applyconfig) { - applyconfig.forEach((item) => { - const { key, value } = item - configObj[key] = value + 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', }) } - commit('wizard/model$update', { - path: '/spec/configuration/applyConfig', - value: configObj, - force: true, - }) -} - -function onReconfigurationTypeChange({ commit, discriminator, getValue, setDiscriminatorValue }) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - setDiscriminatorValue('/applyConfig', []) - if (reconfigurationType === 'remove') { - commit('wizard/model$delete', `/spec/configuration`) + 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) { + 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/removeCustomConfig`, - value: true, - force: true, + path: `/spec/configuration/${type}applyConfig`, + value: tempConfigObj, }) - } 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({ discriminator, getValue, watchDependency }) { - const tls = getDbTls({ - discriminator, - getValue, - watchDependency, - }) + 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], + }) + }) + } else { + configObj.push({ name: '', content: '' }) + } + return configObj + } - return !!tls -} + function onRemoveConfigChange(type) { + type = type ? type + '/' : '' + const configPath = `/${type}selectedConfigurationRemove` + const selectedConfig = getValue(discriminator, configPath) -function initIssuerRefApiGroup({ getValue, model, watchDependency, discriminator }) { - const kind = getValue(model, '/spec/tls/issuerRef/kind') - watchDependency('model#/spec/tls/issuerRef/kind') + if (!selectedConfig) { + commit('wizard/model$delete', `/spec/configuration/${type}removeCustomConfig`) + return [{ name: '', content: '' }] + } + commit('wizard/model$update', { + path: `/spec/configuration/${type}removeCustomConfig`, + value: true, + }) - if (kind) { - const apiGroup = getValue(discriminator, '/dbDetails/spec/tls/issuerRef/apiGroup') - if (apiGroup) return apiGroup - return 'cert-manager.io' - } else return undefined -} + const configuration = secretConfigData.find((item) => item.componentName === selectedConfig) -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - 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` + if (!configuration.data) { + return [{ name: '', content: '' }] + } - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + const configObj = [] + // Decode base64 and format as array of objects with name and content + Object.keys(configuration.data).forEach((fileName) => { try { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + // Decode base64 string + const decodedString = atob(configuration.data[fileName]) + configObj.push({ + name: fileName, + content: decodedString, + }) } catch (e) { - console.log(e) - presets.status = String(e.status) + 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: '' }] } - let clusterIssuers = presets.admin?.clusterIssuers?.available || [] - if (presets.status === '404') { - const url = `/clusters/${owner}/${cluster}/proxy/cert-manager.io/v1/clusterissuers` - return getIssuer(url) + 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: '' }] } - return clusterIssuers } - async function getIssuer(url) { - try { - const resp = await axios.get(url) - const resources = (resp && resp.data && resp.data.items) || [] + function onSelectedSecretChange(index) { + const secretData = getValue(discriminator, 'createSecret/data') || [] + const selfSecrets = secretData.map((item) => item.key) - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + 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 + } + + 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 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 } }, + }, }) - return resources + + const items = (resp && resp.data && resp.data.items) || [] + ans = items } catch (e) { console.log(e) - return [] } + + return ans } -} + async function getResourceList({ group, version, resource }) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function initTlsOperation() { - return 'update' -} -function onTlsOperationChange({ discriminator, getValue, commit }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` - commit('wizard/model$delete', '/spec/tls') + let ans = [] + try { + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) - if (tlsOperation === 'rotate') { - commit('wizard/model$update', { - path: '/spec/tls/rotateCertificates', - value: true, - force: true, + 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, }) - 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, + + 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, + } }) - commit('wizard/model$delete', '/spec/tls/certificates') - commit('wizard/model$delete', '/spec/tls/rotateCertificates') } -} + async function unNamespacedResourceNames(group, version, resource) { + let resources = await getResourceList({ + group, + version, + resource, + }) -function showIssuerRefAndCertificates({ discriminator, getValue, watchDependency }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') - watchDependency('discriminator#/tlsOperation') - const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } - return verd -} + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -function isIssuerRefRequired({ discriminator, getValue, watchDependency }) { - const hasTls = hasTlsField({ - discriminator, - getValue, - watchDependency, - }) + // reconfiguration type + function ifReconfigurationTypeEqualsTo(value) { + const reconfigurationType = getValue(discriminator, '/reconfigurationType') - return !hasTls -} + const watchPath = `discriminator#/reconfigurationType` + // watchDependency(watchPath) + return reconfigurationType === value + } -function getRequestTypeFromRoute({ route, model, discriminator, getValue, watchDependency }) { - const isDbloading = isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) - const { query } = route || {} - const { requestType } = query || {} - return isDbloading ? '' : requestType || '' -} + function onReconfigurationTypeChange() { + setDiscriminatorValue('/applyConfig', []) + const reconfigurationType = getValue(discriminator, '/reconfigurationType') + if (reconfigurationType === 'remove') { + commit('wizard/model$delete', `/spec/configuration`) -// ************************************** Set db details ***************************************** + 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`) + } + } -function isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - watchDependency('model#/spec/databaseRef/name') - const dbDetails = getValue(discriminator, '/dbDetails') - const dbName = getValue(model, '/spec/databaseRef/name') + function getRequestTypeFromRoute() { + const isDbloading = isDbDetailsLoading() + const { query } = route || {} + const { requestType } = query || {} + return isDbloading ? '' : requestType || '' + } - return !dbDetails || !dbName -} + function isDbDetailsLoading() { + // watchDependency('discriminator#/dbDetails') + // watchDependency('model#/spec/databaseRef/name') + const dbDetails = getValue(discriminator, '/dbDetails') + const dbName = getValue(model, '/spec/databaseRef/name') -function setValueFromDbDetails( - { discriminator, getValue, watchDependency, commit }, - path, - commitPath, -) { - watchDependency('discriminator#/dbDetails') + return !dbDetails || !dbName + } - const retValue = getValue(discriminator, `/dbDetails${path}`) + function setValueFromDbDetails(path, commitPath) { + const retValue = getValue(discriminator, `/dbDetails${path}`) - if (commitPath && retValue) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + if (commitPath) { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // computed called when tls fields is not visible + if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined - // 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 + } - // 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, - }) + function isNamespaceDisabled() { + const { namespace } = route.query || {} + return !!namespace } - return retValue || undefined -} + function isDatabaseRefDisabled() { + const { name } = route.params || {} + return !!name + } -function setResource({ discriminator, getValue, watchDependency }, path) { - watchDependency('discriminator#/dbDetails') - const resources = getValue(discriminator, `/dbDetails${path}`) || {} - return resources -} + function onNamespaceChange() { + commit('wizard/model$delete', '/spec/type') + } -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} + function onDbChange() { + commit('wizard/model$delete', '/spec/type') + getDbDetails() + } -function isNamespaceDisabled({ route }) { - const { namespace } = route.query || {} - return !!namespace -} + function setApplyToIfReady() { + return 'IfReady' + } -function isDatabaseRefDisabled({ route }) { - const { name } = route.params || {} - return !!name -} + function isVerticalScaleTopologyRequired() { + // watchDependency(`discriminator#/topologyKey`) + // watchDependency(`discriminator#/topologyValue`) -function onNamespaceChange({ commit }) { - commit('wizard/model$delete', '/spec/type') -} + const key = getValue(discriminator, `/topologyKey`) + const value = getValue(discriminator, `/topologyValue`) + const path = `/spec/verticalScaling/memcached/topology` -function onDbChange({ commit, axios, storeGet, model, getValue, setDiscriminatorValue }) { - commit('wizard/model$delete', '/spec/type') - getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) -} + if (key || value) { + commit('wizard/model$update', { + path: path, + value: { key, value }, + force: true, + }) + return '' + } else { + commit('wizard/model$delete', path) + return false + } + } -function setApplyToIfReady() { - return 'IfReady' -} + function setExporter(type) { + let path = `/dbDetails/spec/monitor/prometheus/exporter/resources/limits/${type}` + const limitVal = getValue(discriminator, path) -function isVerticalScaleTopologyRequired({ watchDependency, getValue, discriminator, commit }) { - watchDependency('discriminator#/topologyKey') - watchDependency('discriminator#/topologyValue') + if (!limitVal) { + path = `/dbDetails/spec/monitor/prometheus/exporter/resources/requests/${type}` + const reqVal = getValue(discriminator, path) - const key = getValue(discriminator, '/topologyKey') - const value = getValue(discriminator, '/topologyValue') - const path = `/spec/verticalScaling/memcached/topology` + if (reqVal) return reqVal + } + return limitVal + } - if (key || value) { - commit('wizard/model$update', { - path: path, - value: { key, value }, - force: true, - }) - return true - } else { - commit('wizard/model$delete', path) - return false + 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, + }) } -} -return { - isRancherManaged, - setResource, - fetchJsons, - returnFalse, - getNamespaces, - getDbs, - getDbDetails, - getDbVersions, - ifRequestTypeEqualsTo, - onRequestTypeChange, - getDbTls, - getDbType, - initNamespace, - initDatabaseRef, - - showAndInitName, - showAndInitNamespace, - showAndInitDatabaseRef, - showConfigureOpsrequestLabel, - showAndInitOpsRequestType, - - ifDbTypeEqualsTo, - getConfigSecrets, - createSecretUrl, - isEqualToValueFromType, - disableOpsRequest, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - ifReconfigurationTypeEqualsTo, - onReconfigurationTypeChange, - onApplyconfigChange, - hasTlsField, - initIssuerRefApiGroup, - getIssuerRefsName, - initTlsOperation, - onTlsOperationChange, - showIssuerRefAndCertificates, - isIssuerRefRequired, - getRequestTypeFromRoute, - isDbDetailsLoading, - setValueFromDbDetails, - getAliasOptions, - isNamespaceDisabled, - isDatabaseRefDisabled, - onNamespaceChange, - onDbChange, - setApplyToIfReady, - isVerticalScaleTopologyRequired, - getMachines, - setMachine, - onMachineChange, - isMachineCustom, + return { + setExporter, + onExporterResourceChange, + fetchJsons, + returnFalse, + isRancherManaged, + getNamespaces, + getDbs, + getDbDetails, + getDbVersions, + getVersionInfo, + isVersionEmpty, + getVersion, + ifRequestTypeEqualsTo, + onRequestTypeChange, + getDbTls, + getDbType, + disableOpsRequest, + initNamespace, + initDatabaseRef, + showAndInitName, + showAndInitNamespace, + showAndInitDatabaseRef, + showConfigureOpsrequestLabel, + showAndInitOpsRequestType, + ifDbTypeEqualsTo, + getConfigSecrets, + createSecretUrl, + isEqualToValueFromType, + getNamespacedResourceList, + getResourceList, + resourceNames, + unNamespacedResourceNames, + ifReconfigurationTypeEqualsTo, + onReconfigurationTypeChange, + onApplyconfigChange, + getRequestTypeFromRoute, + isDbDetailsLoading, + setValueFromDbDetails, + isNamespaceDisabled, + isDatabaseRefDisabled, + onDbChange, + onNamespaceChange, + setApplyToIfReady, + isVerticalScaleTopologyRequired, + getMachines, + setMachine, + onMachineChange, + isMachineCustom, + fetchConfigSecrets, + getConfigSecretsforAppyConfig, + getSelectedConfigurationData, + getSelectedConfigurationName, + getSelectedConfigurationValueForRemove, + createNewConfigSecret, + decodeError, + isCreateSecret, + isNotCreateSecret, + onCreateSecretChange, + cancelCreateSecret, + setApplyConfig, + onRemoveConfigChange, + onNewConfigSecretChange, + onSelectedSecretChange, + } } diff --git a/charts/opskubedbcom-mongodbopsrequest-editor/ui/create-ui.yaml b/charts/opskubedbcom-mongodbopsrequest-editor/ui/create-ui.yaml index a3633e6b13..ff7ad0a091 100644 --- a/charts/opskubedbcom-mongodbopsrequest-editor/ui/create-ui.yaml +++ b/charts/opskubedbcom-mongodbopsrequest-editor/ui/create-ui.yaml @@ -1,1106 +1,1674 @@ -steps: -- form: - discriminator: - dbDetails: - type: object +type: multi-step-form +step: + - type: single-step-form + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - schema: - $ref: discriminator#/properties/dbDetails - type: input - - if: showAndInitName - label: - text: labels.op_req_name - required: true - schema: - $ref: schema#/properties/metadata/properties/name - type: input - - computed: initNamespace - disabled: isNamespaceDisabled - fetch: getNamespaces - hasGroup: isRancherManaged - if: showAndInitNamespace - label: - text: labels.namespace - onChange: onNamespaceChange - required: true - schema: - $ref: schema#/properties/metadata/properties/namespace - type: select - - computed: initDatabaseRef - disabled: isDatabaseRefDisabled - fetch: getDbs - if: showAndInitDatabaseRef - label: - text: labels.databaseRef - onChange: onDbChange - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/databaseRef/properties/name - type: select - - if: showConfigureOpsrequestLabel - label: - text: labels.config_ops_request - type: label-element - - computed: getRequestTypeFromRoute - disabled: isDbDetailsLoading - hasDescription: true - if: showAndInitOpsRequestType - individualItemDisabilityCheck: disableOpsRequest - label: - text: labels.ops_request_type - onChange: onRequestTypeChange - options: - - description: options.UpdateVersion.description - text: options.UpdateVersion.text - value: UpdateVersion - - description: options.HorizontalScaling.description - text: options.HorizontalScaling.text - value: HorizontalScaling - - description: options.VerticalScaling.description - text: options.VerticalScaling.text - value: VerticalScaling - - description: options.VolumeExpansion.description - text: options.VolumeExpansion.text - value: VolumeExpansion - - description: options.Restart.description - text: options.Restart.text - value: Restart - - description: options.Reconfigure.description - text: options.Reconfigure.text - value: Reconfigure - - description: options.ReconfigureTLS.description - text: options.ReconfigureTLS.text - value: ReconfigureTLS - schema: - $ref: schema#/properties/spec/properties/type - type: radio - - elements: - - computed: setValueFromDbDetails|/spec/version - fetch: getDbVersions - label: - text: labels.targetVersion - schema: - $ref: schema#/properties/spec/properties/updateVersion/properties/targetVersion - type: select - if: ifRequestTypeEqualsTo|UpdateVersion - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/replicas - if: ifDbTypeEqualsTo|replicaSet|horizontalScaling - label: - text: labels.replicas - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/replicas - type: input - - elements: - - elements: - - label: - text: labels.configServer - type: label-element - - computed: setValueFromDbDetails|/spec/shardTopology/configServer/replicas - label: - text: labels.replicas - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/configServer/properties/replicas - type: input - label: - text: Config Server horizontal Scaling - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/configServer - type: single-step-form - - elements: - - label: - text: labels.mongos - type: label-element - - computed: setValueFromDbDetails|/spec/shardTopology/mongos/replicas - label: - text: labels.replicas - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/mongos/properties/replicas - type: input - label: - text: Mongos horizontal Scaling - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/mongos - type: single-step-form - - elements: - - label: - text: labels.shard - type: label-element - - computed: setValueFromDbDetails|/spec/shardTopology/shard/replicas - label: - text: labels.replicas - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/shard/properties/replicas - type: input - - computed: setValueFromDbDetails|/spec/shardTopology/shard/shards - label: - text: labels.shards - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/shard/properties/shards - type: input - label: - text: Shard horizontal Scaling - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/shard - type: single-step-form - if: ifDbTypeEqualsTo|sharded|horizontalScaling - label: - text: 'Sharded horizontal scaling ' - type: single-step-form - if: ifRequestTypeEqualsTo|HorizontalScaling - label: - text: Horizontal Scaling Form - type: single-step-form - - elements: - - discriminator: - machine-standalone: - default: "" - type: string +# common + - type: input + label: op_req_name + if: + type: function + name: showAndInitName + validation: + type: required + schema: schema/properties/metadata/properties/name + - type: select + label: Namespace + if: + type: function + name: showAndInitNamespace + init: + type: func + value: initNamespace + disable: isNamespaceDisabled + loader: getNamespaces + validation: + type: required + hasGroup: isRancherManaged + schema: schema/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/metadata/properties/namespace + - type: select + label: Database Ref + if: + type: function + name: showAndInitDatabaseRef + loader: + name: getDbs + watchPaths: + - schema/properties/metadata/properties/namespace + init: + type: func + value: initDatabaseRef + validation: + type: required + disable: isDatabaseRefDisabled + refresh: true + watcher: + paths: + - schema/properties/spec/properties/databaseRef/properties/name + func: onDbChange + schema: schema/properties/spec/properties/databaseRef/properties/name + - type: label-element + label: config_ops_request + if: + type: function + name: showConfigureOpsrequestLabel + - type: radio + label: Type of Ops Request + if: + type: function + name: showAndInitOpsRequestType + 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 + init: + type: func + value: getRequestTypeFromRoute + disable: isDbDetailsLoading + watcher: + func: onRequestTypeChange + paths: + - schema/properties/spec/properties/type + isHorizontal: true + schema: schema/properties/spec/properties/type +# UpdateVersion + - type: block-layout + showLabels: true + label: Version + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|UpdateVersion elements: - - computed: setMachine|standalone - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|standalone|/spec/podTemplate/spec/resources - schema: - $ref: discriminator#/machine-standalone - type: select - - if: isMachineCustom|/machine-standalone - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/standalone/properties/resources - type: resource-input-form - - label: - text: labels.node_selection_policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/standalone/properties/nodeSelectionPolicy - type: select - - discriminator: - topologyKey-standalone: - default: "" - type: string - topologyValue-standalone: - default: "" - type: string - elements: - - label: - text: labels.key - required: isVerticalScaleTopologyRequired|standalone - schema: - $ref: discriminator#/topologyKey-standalone - type: input - - label: - text: labels.value - required: isVerticalScaleTopologyRequired|standalone - schema: - $ref: discriminator#/topologyValue-standalone - type: input - label: - text: labels.topology - show_label: true - type: single-step-form - if: ifDbTypeEqualsTo|standalone|verticalScaling - label: - text: Standalone vertical scaling - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/standalone - show_label: true - type: single-step-form - - discriminator: - machine-replicaSet: - default: "" - type: string + - type: select-compare + label: Target Version + subtitle: Select the desired MongoDB version to which you want to update your database. + init: + type: func + value: setValueFromDbDetails|/spec/version + loader: getDbVersions + schema: schema/properties/spec/properties/updateVersion/properties/targetVersion + - type: info + label: '' + loader: + name: getVersionInfo + watchPaths: + - temp/properties/filteredVersion + if: + type: function + name: isVersionEmpty +# Horizontal Scale + - type: block-layout + label: Horizontal Scaling Form + showLabels: true + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|HorizontalScaling elements: - - computed: setMachine|replicaSet - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|replicaSet|/spec/podTemplate/spec/resources - schema: - $ref: discriminator#/machine-replicaSet - type: select - - if: isMachineCustom|/machine-replicaSet - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/replicaSet/properties/resources - type: resource-input-form - - label: - text: labels.node_selection_policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/replicaSet/properties/nodeSelectionPolicy - type: select - - discriminator: - topologyKey-replicaSet: - default: "" - type: string - topologyValue-replicaSet: - default: "" - type: string - elements: - - label: - text: labels.key - required: isVerticalScaleTopologyRequired|replicaSet - schema: - $ref: discriminator#/topologyKey-replicaSet - type: input - - label: - text: labels.value - required: isVerticalScaleTopologyRequired|replicaSet - schema: - $ref: discriminator#/topologyValue-replicaSet - type: input - label: - text: labels.topology - show_label: true - type: single-step-form - if: ifDbTypeEqualsTo|replicaSet|verticalScaling - label: - text: Replicaset vertical scaling - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/replicaSet - show_label: true - type: single-step-form - - elements: - - discriminator: - machine-configServer: - default: "" - type: string - elements: - - computed: setMachine|configServer - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|configServer|/spec/shardTopology/configServer/podTemplate/spec/resources - schema: - $ref: discriminator#/machine-configServer - type: select - - if: isMachineCustom|/machine-configServer - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/configServer/properties/resources - type: resource-input-form - - label: - text: labels.node_selection_policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/configServer/properties/nodeSelectionPolicy - type: select - - discriminator: - topologyKey-configServer: - default: "" - type: string - topologyValue-configServer: - default: "" - type: string + - type: horizontal-layout elements: - - label: - text: labels.key - required: isVerticalScaleTopologyRequired|configServer - schema: - $ref: discriminator#/topologyKey-configServer - type: input - - label: - text: labels.value - required: isVerticalScaleTopologyRequired|configServer - schema: - $ref: discriminator#/topologyValue-configServer - type: input - label: - text: labels.topology - show_label: true - type: single-step-form - label: - text: Config Server Vertical Scaling - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/configServer - show_label: true - type: single-step-form - - discriminator: - machine-mongos: - default: "" - type: string - elements: - - computed: setMachine|mongos - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|mongos|/spec/shardTopology/mongos/podTemplate/spec/resources - schema: - $ref: discriminator#/machine-mongos - type: select - - if: isMachineCustom|/machine-mongos - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/mongos/properties/resources - type: resource-input-form - - label: - text: labels.node_selection_policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/mongos/properties/nodeSelectionPolicy - type: select - - discriminator: - topologyKey-mongos: - default: "" - type: string - topologyValue-mongos: - default: "" - type: string + - type: input-compare + label: Replicas + header: Replica + subtitle: Define the total number of replicas for the database. Increasing replicas improves fault tolerance and load distribution , while reducing replicas conserves resources + if: + type: function + name: ifDbTypeEqualsTo|replicaSet|horizontalScaling + init: + type: func + value: setValueFromDbDetails|/spec/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/replicas + - type: info + 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. + if: + type: function + name: ifDbTypeEqualsTo|replicaSet|horizontalScaling + - type: block-layout + label: 'Sharded horizontal scaling' + if: + name: ifDbTypeEqualsTo|sharded|horizontalScaling + type: function elements: - - label: - text: labels.key - required: isVerticalScaleTopologyRequired|mongos - schema: - $ref: discriminator#/topologyKey-mongos - type: input - - label: - text: labels.value - required: isVerticalScaleTopologyRequired|mongos - schema: - $ref: discriminator#/topologyValue-mongos - type: input - label: - text: labels.topology - show_label: true - type: single-step-form - label: - text: Mongos Vertical Scaling - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/mongos - show_label: true - type: single-step-form - - discriminator: - machine-shard: - default: "" - type: string - elements: - - computed: setMachine|shard - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|shard|/spec/shardTopology/shard/podTemplate/spec/resources - schema: - $ref: discriminator#/machine-shard - type: select - - if: isMachineCustom|/machine-shard - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/shard/properties/resources - type: resource-input-form - - label: - text: labels.node_selection_policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/shard/properties/nodeSelectionPolicy - type: select - - discriminator: - topologyKey-shard: - default: "" - type: string - topologyValue-shard: - default: "" - type: string + - type: block-layout + label: Config Server horizontal Scaling + # showLabels: true + elements: + - type: label-element + label: Config Server + - type: horizontal-layout + elements: + - type: input-compare + label: Replicas + subtitle: Define the total number of replicas for the database. Increasing replicas improves fault tolerance and load distribution , while reducing replicas conserves resources + schema: schema/properties/spec/properties/horizontalScaling/properties/configServer/properties/replicas + init: + type: func + value: setValueFromDbDetails|/spec/shardTopology/configServer/replicas + - type: info + 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: block-layout + label: Mongo Horizontal Scaling + elements: + - type: label-element + label: Mongos + - type: horizontal-layout + elements: + - type: input-compare + label: Replicas + subtitle: Define the total number of replicas for the database. Increasing replicas improves fault tolerance and load distribution , while reducing replicas conserves resources + init: + type: func + value: setValueFromDbDetails|/spec/shardTopology/mongos/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/mongos/properties/replicas + - type: info + 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: block-layout + label: Shard horizontal Scaling + # showLabels: true + elements: + - type: label-element + label: Shard + - type: horizontal-layout + elements: + - type: input-compare + label: Replicas + subtitle: Define the total number of replicas for the database. Increasing replicas improves fault tolerance and load distribution , while reducing replicas conserves resources + init: + type: func + value: setValueFromDbDetails|/spec/shardTopology/shard/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/shard/properties/replicas + - type: info + 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. 4 + - type: input + label: Shards + init: + type: func + value: setValueFromDbDetails|/spec/shardTopology/shard/shards + schema: schema/properties/spec/properties/horizontalScaling/properties/shard/properties/shards + - type: label-element + label: '' + customClass: mb-16 +# vertical Scale + - type: block-layout + if: + type: function + name: ifRequestTypeEqualsTo|VerticalScaling + elements: + - type: block-layout + label: Standalone Vertical Scaling + if: + type: function + name: ifDbTypeEqualsTo|standalone|verticalScaling elements: - - label: - text: labels.key - required: isVerticalScaleTopologyRequired|shard - schema: - $ref: discriminator#/topologyKey-shard - type: input - - label: - text: labels.value - required: isVerticalScaleTopologyRequired|shard - schema: - $ref: discriminator#/topologyValue-shard - type: input - label: - text: labels.topology - show_label: true - type: single-step-form - label: - text: Shard Vertical Scaling - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/shard - show_label: true - type: single-step-form - if: ifDbTypeEqualsTo|sharded|verticalScaling - label: - text: 'Sharded vertical scaling ' - type: single-step-form - if: ifRequestTypeEqualsTo|VerticalScaling - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/storage/resources/requests/storage - if: ifDbTypeEqualsTo|standalone|volumeExpansion - label: - text: labels.standalone - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/standalone - type: input - validationRuleObject: - func: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/standalone - - label: - text: Mode - options: - - text: Offline - value: Offline - - text: Online - value: Online - required: true - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/mode - type: select - - computed: setValueFromDbDetails|/spec/storage/resources/requests/storage - if: ifDbTypeEqualsTo|replicaSet|volumeExpansion - label: - text: labels.replicaSet - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/replicaSet - type: input - validationRuleObject: - func: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/replicaSet - - elements: - - computed: setValueFromDbDetails|/spec/shardTopology/configServer/storage/resources/requests/storage - label: - text: labels.configServer - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/configServer - type: input - validationRuleObject: - func: checkVolume|/spec/shardTopology/configServer/storage/resources/requests/storage|/spec/volumeExpansion/configServer - - computed: setValueFromDbDetails|/spec/shardTopology/shard/storage/resources/requests/storage - label: - text: labels.shard - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/shard - type: input - validationRuleObject: - func: checkVolume|/spec/shardTopology/shard/storage/resources/requests/storage|/spec/volumeExpansion/shard - if: ifDbTypeEqualsTo|sharded|volumeExpansion - label: - text: Sharded volume expansion - type: single-step-form - if: ifRequestTypeEqualsTo|VolumeExpansion - label: - text: Volume Expansion Form - type: single-step-form - - elements: - - discriminator: - reconfigurationType: - type: string + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines|standalone + init: + type: func + value: setMachine|standalone + watcher: + func: onMachineChange|standalone|/spec/podTemplate/spec/resources + paths: + - temp/properties/machine-standalone + schema: temp/properties/machine-standalone + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/standalone/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|standalone + schema: temp/topologyKey-standalone + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|standalone + schema: temp/topologyValue-standalone + - type: block-layout + label: ReplicaSet Vertical Scaling + if: + type: function + name: ifDbTypeEqualsTo|replicaSet|verticalScaling + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines|replicaSet + init: + type: func + value: setMachine|replicaSet + watcher: + func: onMachineChange|replicaSet|/spec/podTemplate/spec/resources + paths: + - temp/properties/machine-replicaSet + schema: temp/properties/machine-replicaSet + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/replicaSet/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|replicaSet + schema: temp/topologyKey-replicaSet + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|replicaSet + schema: temp/topologyValue-replicaSet + - type: label-element + label: '' + customClass: mb-20 + - type: block-layout + if: + type: function + name: ifDbTypeEqualsTo|sharded|verticalScaling + label: Sharded Vertical Scaling + showLabels: false + elements: + - type: block-layout + label: Config Server Vertical Scaling + showLabels: true + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines|configServer + init: + type: func + value: setMachine|configServer + watcher: + func: onMachineChange|configServer|/spec/shardTopology/configServer/podTemplate/spec/resources + paths: + - temp/properties/machine-configServer + schema: temp/properties/machine-configServer + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/configServer/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|configServer + schema: temp/topologyKey-configServer + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|configServer + schema: temp/topologyValue-configServer + - type: block-layout + label: Mongos Vertical Scaling + showLabels: true + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines|mongos + init: + type: func + value: setMachine|mongos + watcher: + func: onMachineChange|mongos|/spec/shardTopology/mongos/podTemplate/spec/resources + paths: + - temp/properties/machine-mongos + schema: temp/properties/machine-mongos + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/mongos/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|mongos + schema: temp/topologyKey-mongos + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|mongos + schema: temp/topologyValue-mongos + - type: block-layout + label: Shard Vertical Scaling + showLabels: true + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines|shard + init: + type: func + value: setMachine|shard + watcher: + func: onMachineChange|shard|/spec/shardTopology/shard/podTemplate/spec/resources + paths: + - temp/properties/machine-shard + schema: temp/properties/machine-shard + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/shard/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|shard + schema: temp/topologyKey-shard + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|shard + schema: temp/topologyValue-shard + - type: block-layout + label: Exporter + showLabels: true + hideBlock: true + elements: + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setExporter|cpu + type: input + 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 + watcher: + func: onExporterResourceChange|memory + paths: + - schema/properties/spec/properties/verticalScaling/properties/exporter/properties/resources/properties/limits/properties/memory +# Volume Expansion + + - type: block-layout + label: Volume Expansion Form + if: + type: function + name: ifRequestTypeEqualsTo|VolumeExpansion elements: - - label: - text: labels.reconfigurationType - onChange: onReconfigurationTypeChange|standalone - options: - - text: Select New Config Secret - value: selectNewConfigSecret - - text: Apply Config - value: applyConfig - - text: Remove - value: remove - required: true - schema: - $ref: discriminator#/properties/reconfigurationType - type: radio - - elements: - - add_new_button: - label: labels.createConfig - target: _blank - url: - function: createSecretUrl - computed: setValueFromDbDetails|/spec/configSecret/name - fetch: getConfigSecrets - label: - text: labels.configSecret - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/configuration/properties/standalone/properties/configSecret/properties/name - type: select - if: ifReconfigurationTypeEqualsTo|selectNewConfigSecret - label: - text: Standalone configuration config secret - schema: - $ref: schema#/properties/spec/properties/configuration/properties/standalone/properties/configSecret - type: single-step-form - - addFormLabel: labels.applyConfig.label - element: - discriminator: - configArray: - emitAs: standalone/applyConfig - type: array + - type: horizontal-layout + elements: + - type: block-layout + elements: + - type: label-element + 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: select + label: Mode + options: + - text: Offline + value: Offline + - text: Online + value: Online + validation: + type: required + schema: schema/properties/spec/properties/volumeExpansion/properties/mode + - type: block-layout + label: Standalone volume expansion + showLabels: true + fixedBlock: true + if: + type: function + name: ifDbTypeEqualsTo|standalone|volumeExpansion + elements: + - type: horizontal-layout + elements: + - type: input-compare + header: Standalone + subtitle: How much extra storage does your database need? Specify the size(e.g. 2Gi for 2 gigabytes) so we can allocate it correctly + label: Standalone + init: + type: func + value: setValueFromDbDetails|/spec/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/standalone + schema: schema/properties/spec/properties/volumeExpansion/properties/standalone + - type: block-layout + label: Sharded volume expansion + showLabels: true + fixedBlock: true + if: + type: function + name: ifDbTypeEqualsTo|sharded|volumeExpansion + elements: + - type: horizontal-layout + elements: + - type: input-compare + header: Config Server + label: Config Server + subtitle: How much extra storage does your database need? Specify the size(e.g., 2Gi for 2 gigabytes) so we can allocate it correctly + init: + type: func + value: setValueFromDbDetails|/spec/shardTopology/configServer/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/shardTopology/configServer/storage/resources/requests/storage|/spec/volumeExpansion/configServer + schema: schema/properties/spec/properties/volumeExpansion/properties/configServer + - type: info + 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: horizontal-layout + elements: + - type: input-compare + header: Shard + label: Shard + subtitle: How much extra storage does your database need? Specify the size(e.g., 2Gi for 2 gigabytes) so we can allocate it correctly + init: + type: func + value: setValueFromDbDetails|/spec/shardTopology/shard/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/shardTopology/shard/storage/resources/requests/storage|/spec/volumeExpansion/shard + schema: schema/properties/spec/properties/volumeExpansion/properties/shard + - type: info + 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: block-layout + label: ReplicaSet volume expansion + showLabels: true + fixedBlock: true + if: + type: function + name: ifDbTypeEqualsTo|replicaSet|volumeExpansion elements: - - label: - text: labels.applyConfig.key - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/key - type: input - - label: - text: labels.applyConfig.value - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/value - type: editor - type: single-step-form - if: ifReconfigurationTypeEqualsTo|applyConfig - label: - text: labels.applyConfig.label - onChange: onApplyconfigChange|standalone - required: true - schema: - $ref: discriminator#/properties/standalone/applyConfig - tableContents: - - inTableColumn: true - label: - text: labels.applyConfig.key - path: key - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.applyConfig.value - path: value - type: value - typeOfValue: code - type: single-step-form-array - - if: returnFalse - label: - text: labels.removeCustomConfig - schema: - $ref: schema#/properties/spec/properties/configuration/properties/standalone/properties/removeCustomConfig - type: switch - if: ifDbTypeEqualsTo|standalone|configuration - label: - text: labels.standalone - schema: - $ref: schema#/properties/spec/properties/configuration/properties/standalone - show_label: true - type: single-step-form - - discriminator: - reconfigurationType: - type: string + - type: horizontal-layout + elements: + - type: input-compare + header: Replica Set + subtitle: How much extra storage does your database need? Specify the size(e.g. 2Gi for 2 gigabytes) so we can allocate it correctly + label: ReplicaSet + init: + type: func + value: setValueFromDbDetails|/spec/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/replicaSet + schema: schema/properties/spec/properties/volumeExpansion/properties/replicaSet + - type: info + 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. +# Reconfigure + - type: block-layout + label: Reconfigure Form + if: + name: ifRequestTypeEqualsTo|Reconfigure + type: function + loader: + name: fetchConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace elements: - - label: - text: labels.reconfigurationType - onChange: onReconfigurationTypeChange|replicaSet - options: - - text: Select New Config Secret - value: selectNewConfigSecret - - text: Apply Config - value: applyConfig - - text: Remove - value: remove - required: true - schema: - $ref: discriminator#/properties/reconfigurationType - type: radio - - elements: - - add_new_button: - label: labels.createConfig - target: _blank - url: - function: createSecretUrl - computed: setValueFromDbDetails|/spec/configSecret/name - fetch: getConfigSecrets - label: - text: labels.configSecret - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/configuration/properties/replicaSet/properties/configSecret/properties/name - type: select - if: ifReconfigurationTypeEqualsTo|selectNewConfigSecret - label: - text: Replica Set configuration config secret - schema: - $ref: schema#/properties/spec/properties/configuration/properties/replicaSet/properties/configSecret - type: single-step-form - - addFormLabel: labels.applyConfig.label - element: - discriminator: - configArray: - emitAs: replicaSet/applyConfig - type: array + - type: label-element + label: '' + subtitle: Select a new configuration secret, apply a custom configuration, or remove an existing setup to update your database settings + - type: block-layout + label: Standalone + if: + name: ifDbTypeEqualsTo|standalone|configuration + type: function elements: - - label: - text: labels.applyConfig.key - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/key - type: input - - label: - text: labels.applyConfig.value - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/value - type: editor - type: single-step-form - if: ifReconfigurationTypeEqualsTo|applyConfig - label: - text: labels.applyConfig.label - onChange: onApplyconfigChange|replicaSet - required: true - schema: - $ref: discriminator#/properties/replicaSet/applyConfig - tableContents: - - inTableColumn: true - label: - text: labels.applyConfig.key - path: key - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.applyConfig.value - path: value - type: value - typeOfValue: code - type: single-step-form-array - - if: returnFalse - label: - text: labels.removeCustomConfig - schema: - $ref: schema#/properties/spec/properties/configuration/properties/replicaSet/properties/removeCustomConfig - type: switch - if: ifDbTypeEqualsTo|replicaSet|configuration - label: - text: labels.replicaSet - schema: - $ref: schema#/properties/spec/properties/configuration/properties/replicaSet - show_label: true - type: single-step-form - - elements: - - discriminator: - reconfigurationType-configServer: - type: string - elements: - - label: - text: labels.reconfigurationType - onChange: onReconfigurationTypeChange|configServer|true - options: - - text: Select New Config Secret - value: selectNewConfigSecret - - text: Apply Config - value: applyConfig - - text: Remove - value: remove - schema: - $ref: discriminator#/properties/reconfigurationType-configServer - type: radio - - elements: - - add_new_button: - label: labels.createConfig - target: _blank - url: - function: createSecretUrl - computed: setValueFromDbDetails|/spec/shardTopology/configServer/configSecret/name - fetch: getConfigSecrets - label: - text: labels.configSecret - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configServer/properties/configSecret/properties/name - type: select - if: ifReconfigurationTypeEqualsTo|selectNewConfigSecret|configServer|true - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configServer/properties/configSecret - type: single-step-form - - addFormLabel: labels.applyConfig.label - element: - discriminator: - configArray: - emitAs: configServer/applyConfig - type: array + - type: tab-layout + label: New Config Secret + schema: temp/properties/reconfigurationType + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + elements: + - type: block-layout + label: Config Secret + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret + type: function + elements: + - type: label-element + label: Config Secret + subtitle: Select a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: schema/properties/spec/properties/configuration/properties/standalone/properties/configSecret/properties/name + refresh: true + label: Config Secret + loader: + name: getConfigSecrets|standalone + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/standalone/properties/createSecret/properties/status + init: + type: func + value: setValueFromDbDetails|/spec/configSecret/name + watcher: + func: onCreateSecretChange|standalone + paths: + - temp/properties/standalone/properties/createSecret/properties/status + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|create|standalone + watchPaths: + - schema/properties/spec/properties/configuration/properties/standalone/properties/configSecret/properties/name + - type: block-layout + label: Create a New Config Secret + showLabels: true + if: + type: function + name: isCreateSecret|standalone + hasButton: + text: Save + hasCancel: cancelCreateSecret|standalone + action: createNewConfigSecret|standalone + elements: + - type: input + label: Secret Name + schema: temp/properties/standalone/properties/createSecret/properties/name + validation: + type: required + - type: array-object-form + label: String Data + schema: temp/properties/standalone/properties/createSecret/properties/data + buttonClass: is-light is-outlined + validation: + type: required + elements: + - type: select + label: Key + schema: key + loader: + name: onSelectedSecretChange|standalone + watchPaths: + - temp/properties/standalone/properties/createSecret/properties/data + validation: + type: required + - type: textarea + label: Value + schema: value + - type: multi-file-editor + editorHeight: 500px + readonly: true + if: + type: function + name: isNotCreateSecret|standalone + loader: + name: onNewConfigSecretChange|standalone + watchPaths: + - schema/properties/spec/properties/configuration/properties/standalone/properties/configSecret/properties/name + schema: temp/properties/standalone/newConfigSecret + - type: block-layout + label: ApplyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig + type: function + elements: + - type: label-element + 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). + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/standalone/selectedConfiguration + refresh: true + label: Configuration + loader: getConfigSecretsforAppyConfig + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|apply|standalone + watchPaths: + - temp/properties/standalone/selectedConfiguration + - type: multi-file-editor + editorHeight: 500px + schema: temp/properties/standalone/applyConfig + loader: + name: setApplyConfig|standalone + watchPaths: + - temp/properties/standalone/selectedConfiguration + watcher: + func: onApplyconfigChange|standalone + paths: + - temp/properties/standalone/applyConfig + - type: block-layout + label: Remove + if: + name: ifReconfigurationTypeEqualsTo|remove + type: function + elements: + - type: label-element + label: Remove + subtitle: Selected a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/standalone/selectedConfigurationRemove + refresh: true + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|remove|standalone + watchPaths: + - temp/properties/standalone/selectedConfigurationRemove + - type: multi-file-editor + editorHeight: 500px + readonly: true + init: + type: func + value: onRemoveConfigChange|standalone + watcher: + func: onRemoveConfigChange|standalone + paths: + - temp/properties/standalone/selectedConfigurationRemove + schema: temp/properties/standalone/removeConfig + - type: block-layout + label: Replica Set + if: + name: ifDbTypeEqualsTo|replicaSet|configuration + type: function + elements: + - type: tab-layout + label: New Config Secret + schema: temp/properties/reconfigurationType + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + elements: + - type: block-layout + label: Config Secret + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret + type: function + elements: + - type: label-element + label: Config Secret + subtitle: Select a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: schema/properties/spec/properties/configuration/properties/replicaSet/properties/configSecret/properties/name + refresh: true + label: Config Secret + loader: + name: getConfigSecrets|replicaSet + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/replicaSet/properties/createSecret/properties/status + init: + type: func + value: setValueFromDbDetails|/spec/configSecret/name + watcher: + func: onCreateSecretChange|replicaSet + paths: + - temp/properties/replicaSet/properties/createSecret/properties/status + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|create|replicaSet + watchPaths: + - schema/properties/spec/properties/configuration/properties/replicaSet/properties/configSecret/properties/name + - type: block-layout + label: Create a New Config Secret + showLabels: true + if: + type: function + name: isCreateSecret|replicaSet + hasButton: + text: Save + hasCancel: cancelCreateSecret|replicaSet + action: createNewConfigSecret|replicaSet + elements: + - type: input + label: Secret Name + schema: temp/properties/replicaSet/properties/createSecret/properties/name + validation: + type: required + - type: array-object-form + label: String Data + schema: temp/properties/replicaSet/properties/createSecret/properties/data + buttonClass: is-light is-outlined + validation: + type: required + elements: + - type: select + label: Key + schema: key + loader: + name: onSelectedSecretChange|replicaSet + watchPaths: + - temp/properties/replicaSet/properties/createSecret/properties/data + validation: + type: required + - type: textarea + label: Value + schema: value + - type: multi-file-editor + editorHeight: 500px + readonly: true + if: + type: function + name: isNotCreateSecret|replicaSet + loader: + name: onNewConfigSecretChange|replicaSet + watchPaths: + - schema/properties/spec/properties/configuration/properties/replicaSet/properties/configSecret/properties/name + schema: temp/properties/replicaSet/newConfigSecret + - type: block-layout + label: ApplyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig + type: function + elements: + - type: label-element + 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). + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/replicaSet/selectedConfiguration + refresh: true + label: Configuration + loader: getConfigSecretsforAppyConfig + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|apply|replicaSet + watchPaths: + - temp/properties/replicaSet/selectedConfiguration + - type: multi-file-editor + editorHeight: 500px + schema: temp/properties/replicaSet/applyConfig + loader: + name: setApplyConfig|replicaSet + watchPaths: + - temp/properties/replicaSet/selectedConfiguration + watcher: + func: onApplyconfigChange|replicaSet + paths: + - temp/properties/replicaSet/applyConfig + - type: block-layout + label: Remove + if: + name: ifReconfigurationTypeEqualsTo|remove + type: function + elements: + - type: label-element + label: Remove + subtitle: Selected a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/replicaSet/selectedConfigurationRemove + refresh: true + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|remove|replicaSet + watchPaths: + - temp/properties/replicaSet/selectedConfigurationRemove + - type: multi-file-editor + editorHeight: 500px + readonly: true + init: + type: func + value: onRemoveConfigChange|replicaSet + watcher: + func: onRemoveConfigChange|replicaSet + paths: + - temp/properties/replicaSet/selectedConfigurationRemove + schema: temp/properties/replicaSet/removeConfig + - type: block-layout + elements: + - type: block-layout + label: Config Server + showLabels: true + customClass: mt-10 elements: - - label: - text: labels.applyConfig.key - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/key - type: input - - label: - text: labels.applyConfig.value - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/value - type: editor - type: single-step-form - if: ifReconfigurationTypeEqualsTo|applyConfig|configServer|true - label: - text: labels.applyConfig.label - onChange: onApplyconfigChange|configServer - required: true - schema: - $ref: discriminator#/properties/configServer/applyConfig - tableContents: - - inTableColumn: true - label: - text: labels.applyConfig.key - path: key - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.applyConfig.value - path: value - type: value - typeOfValue: code - type: single-step-form-array - - if: returnFalse - label: - text: labels.removeCustomConfig - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configServer/properties/removeCustomConfig - type: switch - label: - text: labels.configServer - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configServer - show_label: true - type: single-step-form - - discriminator: - reconfigurationType-mongos: - type: string - elements: - - label: - text: labels.reconfigurationType - onChange: onReconfigurationTypeChange|mongos|true - options: - - text: Select New Config Secret - value: selectNewConfigSecret - - text: Apply Config - value: applyConfig - - text: Remove - value: remove - schema: - $ref: discriminator#/properties/reconfigurationType-mongos - type: radio - - elements: - - add_new_button: - label: labels.createConfig - target: _blank - url: - function: createSecretUrl - computed: setValueFromDbDetails|/spec/shardTopology/mongos/configSecret/name - fetch: getConfigSecrets - label: - text: labels.configSecret - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mongos/properties/configSecret/properties/name - type: select - if: ifReconfigurationTypeEqualsTo|selectNewConfigSecret|mongos|true - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mongos/properties/configSecret - type: single-step-form - - addFormLabel: labels.applyConfig.label - element: - discriminator: - configArray: - emitAs: mongos/applyConfig - type: array + - type: tab-layout + label: New Config Secret + schema: temp/properties/reconfigurationType-configServer + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + elements: + - type: block-layout + label: Config Secret + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret|configServer|true + type: function + elements: + - type: label-element + label: Config Secret + subtitle: Select a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: schema/properties/spec/properties/configuration/properties/configServer/properties/configSecret/properties/name + refresh: true + label: Config Secret + loader: + name: getConfigSecrets|configServer + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/configServer/properties/createSecret/properties/status + init: + type: func + value: setValueFromDbDetails|/spec/shardTopology/configServer/configSecret/name + watcher: + func: onCreateSecretChange|configServer + paths: + - temp/properties/configServer/properties/createSecret/properties/status + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|create|configServer + watchPaths: + - schema/properties/spec/properties/configuration/properties/configServer/properties/configSecret/properties/name + - type: block-layout + label: Create a New Config Secret + showLabels: true + if: + type: function + name: isCreateSecret|configServer + hasButton: + text: Save + hasCancel: cancelCreateSecret|configServer + action: createNewConfigSecret|configServer + elements: + - type: input + label: Secret Name + schema: temp/properties/configServer/properties/createSecret/properties/name + validation: + type: required + - type: array-object-form + label: String Data + schema: temp/properties/configServer/properties/createSecret/properties/data + buttonClass: is-light is-outlined + validation: + type: required + elements: + - type: select + label: Key + schema: key + loader: + name: onSelectedSecretChange|configServer + watchPaths: + - temp/properties/configServer/properties/createSecret/properties/data + validation: + type: required + - type: textarea + label: Value + schema: value + - type: multi-file-editor + editorHeight: 500px + readonly: true + if: + type: function + name: isNotCreateSecret|configServer + loader: + name: onNewConfigSecretChange|configServer + watchPaths: + - schema/properties/spec/properties/configuration/properties/configServer/properties/configSecret/properties/name + schema: temp/properties/configServer/newConfigSecret + - type: block-layout + label: ApplyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig|configServer|true + type: function + elements: + - type: label-element + 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). + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/configServer/selectedConfiguration + refresh: true + label: Configuration + loader: getConfigSecretsforAppyConfig + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|apply|configServer + watchPaths: + - temp/properties/configServer/selectedConfiguration + - type: multi-file-editor + editorHeight: 500px + schema: temp/properties/configServer/applyConfig + loader: + name: setApplyConfig|configServer + watchPaths: + - temp/properties/configServer/selectedConfiguration + watcher: + func: onApplyconfigChange|configServer + paths: + - temp/properties/configServer/applyConfig + - type: block-layout + label: Remove + if: + name: ifReconfigurationTypeEqualsTo|remove|configServer|true + type: function + elements: + - type: label-element + label: Remove + subtitle: Selected a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/configServer/selectedConfigurationRemove + refresh: true + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|remove|configServer + watchPaths: + - temp/properties/configServer/selectedConfigurationRemove + - type: multi-file-editor + editorHeight: 500px + readonly: true + init: + type: func + value: onRemoveConfigChange|configServer + watcher: + func: onRemoveConfigChange|configServer + paths: + - temp/properties/configServer/selectedConfigurationRemove + schema: temp/properties/configServer/removeConfig + - type: block-layout + label: Mongos + showLabels: true elements: - - label: - text: labels.applyConfig.key - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/key - type: input - - label: - text: labels.applyConfig.value - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/value - type: editor - type: single-step-form - if: ifReconfigurationTypeEqualsTo|applyConfig|mongos|true - label: - text: labels.applyConfig.label - onChange: onApplyconfigChange|mongos - required: true - schema: - $ref: discriminator#/properties/mongos/applyConfig - tableContents: - - inTableColumn: true - label: - text: labels.applyConfig.key - path: key - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.applyConfig.value - path: value - type: value - typeOfValue: code - type: single-step-form-array - - if: returnFalse - label: - text: labels.removeCustomConfig - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mongos/properties/removeCustomConfig - type: switch - label: - text: labels.mongos - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mongos - show_label: true - type: single-step-form - - discriminator: - reconfigurationType-shard: - type: string - elements: - - label: - text: labels.reconfigurationType - onChange: onReconfigurationTypeChange|shard|true - options: - - text: Select New Config Secret - value: selectNewConfigSecret - - text: Apply Config - value: applyConfig - - text: Remove - value: remove - schema: - $ref: discriminator#/properties/reconfigurationType-shard - type: radio - - elements: - - add_new_button: - label: labels.createConfig - target: _blank - url: - function: createSecretUrl - computed: setValueFromDbDetails|/spec/shardTopology/shard/configSecret/name - fetch: getConfigSecrets - label: - text: labels.configSecret - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/configuration/properties/shard/properties/configSecret/properties/name - type: select - if: ifReconfigurationTypeEqualsTo|selectNewConfigSecret|shard|true - schema: - $ref: schema#/properties/spec/properties/configuration/properties/shard/properties/configSecret - type: single-step-form - - addFormLabel: labels.applyConfig.label - element: - discriminator: - configArray: - emitAs: shard/applyConfig - type: array + - type: tab-layout + label: New Config Secret + schema: temp/properties/reconfigurationType-mongos + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + elements: + - type: block-layout + label: Config Secret + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret|mongos|true + type: function + elements: + - type: label-element + label: Config Secret + subtitle: Select a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: schema/properties/spec/properties/configuration/properties/mongos/properties/configSecret/properties/name + refresh: true + label: Config Secret + loader: + name: getConfigSecrets|mongos + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/mongos/properties/createSecret/properties/status + init: + type: func + value: setValueFromDbDetails|/spec/shardTopology/mongos/configSecret/name + watcher: + func: onCreateSecretChange|mongos + paths: + - temp/properties/mongos/properties/createSecret/properties/status + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|create|mongos + watchPaths: + - schema/properties/spec/properties/configuration/properties/mongos/properties/configSecret/properties/name + - type: block-layout + label: Create a New Config Secret + showLabels: true + if: + type: function + name: isCreateSecret|mongos + hasButton: + text: Save + hasCancel: cancelCreateSecret|mongos + action: createNewConfigSecret|mongos + elements: + - type: input + label: Secret Name + schema: temp/properties/mongos/properties/createSecret/properties/name + validation: + type: required + - type: array-object-form + label: String Data + schema: temp/properties/mongos/properties/createSecret/properties/data + buttonClass: is-light is-outlined + validation: + type: required + elements: + - type: select + label: Key + schema: key + loader: + name: onSelectedSecretChange|mongos + watchPaths: + - temp/properties/mongos/properties/createSecret/properties/data + validation: + type: required + - type: textarea + label: Value + schema: value + - type: multi-file-editor + editorHeight: 500px + readonly: true + if: + type: function + name: isNotCreateSecret|mongos + loader: + name: onNewConfigSecretChange|mongos + watchPaths: + - schema/properties/spec/properties/configuration/properties/mongos/properties/configSecret/properties/name + schema: temp/properties/mongos/newConfigSecret + - type: block-layout + label: ApplyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig|mongos|true + type: function + elements: + - type: label-element + 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). + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/mongos/selectedConfiguration + refresh: true + label: Configuration + loader: getConfigSecretsforAppyConfig + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|apply|mongos + watchPaths: + - temp/properties/mongos/selectedConfiguration + - type: multi-file-editor + editorHeight: 500px + schema: temp/properties/mongos/applyConfig + loader: + name: setApplyConfig|mongos + watchPaths: + - temp/properties/mongos/selectedConfiguration + watcher: + func: onApplyconfigChange|mongos + paths: + - temp/properties/mongos/applyConfig + - type: block-layout + label: Remove + if: + name: ifReconfigurationTypeEqualsTo|remove|mongos|true + type: function + elements: + - type: label-element + label: Remove + subtitle: Selected a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/mongos/selectedConfigurationRemove + refresh: true + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|remove|mongos + watchPaths: + - temp/properties/mongos/selectedConfigurationRemove + - type: multi-file-editor + editorHeight: 500px + readonly: true + init: + type: func + value: onRemoveConfigChange|mongos + watcher: + func: onRemoveConfigChange|mongos + paths: + - temp/properties/mongos/selectedConfigurationRemove + schema: temp/properties/mongos/removeConfig + - type: block-layout + label: Shard + showLabels: true elements: - - label: - text: labels.applyConfig.key - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/key - type: input - - label: - text: labels.applyConfig.value - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/value - type: editor - type: single-step-form - if: ifReconfigurationTypeEqualsTo|applyConfig|shard|true - label: - text: labels.applyConfig.label - onChange: onApplyconfigChange|shard - required: true - schema: - $ref: discriminator#/properties/shard/applyConfig - tableContents: - - inTableColumn: true - label: - text: labels.applyConfig.key - path: key - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.applyConfig.value - path: value - type: value - typeOfValue: code - type: single-step-form-array - - if: returnFalse - label: - text: labels.removeCustomConfig - schema: - $ref: schema#/properties/spec/properties/configuration/properties/shard/properties/removeCustomConfig - type: switch - label: - text: labels.shard - schema: - $ref: schema#/properties/spec/properties/configuration/properties/shard - show_label: true - type: single-step-form - if: ifDbTypeEqualsTo|sharded|configuration - label: - text: Sharded Reconfigure form - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|Reconfigure - label: - text: Reconfigure Form - type: single-step-form - - discriminator: - tlsOperation: - default: update - type: string - elements: - - computed: initTlsOperation - if: hasTlsField - label: - text: labels.tlsOperation - onChange: onTlsOperationChange - options: - - text: Update - value: update - - text: Rotate - value: rotate - - text: Remove - value: remove - schema: - $ref: discriminator#/properties/tlsOperation - type: radio - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/remove - type: switch - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/rotateCertificates - type: switch - - elements: - - computed: initIssuerRefApiGroup - disabled: true - label: - text: labels.api_group - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup - type: input - - computed: setValueFromDbDetails|/spec/tls/issuerRef/kind - label: - text: labels.kind - options: - - text: Issuer - value: Issuer - - text: ClusterIssuer - value: ClusterIssuer - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/kind - type: select - - allowUserDefinedOption: true - computed: setValueFromDbDetails|/spec/tls/issuerRef/name - fetch: getIssuerRefsName - label: - text: labels.name - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/name - type: select - if: showIssuerRefAndCertificates - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef - type: single-step-form - - alias: reusable_certificates - chart: - name: uibytebuildersdev-component-certificates - version: v0.29.0 - computed: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates - functionCallbacks: - getAliasOptions: - $ref: functions#/getAliasOptions - if: showIssuerRefAndCertificates - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/spec/properties/tls/properties/certificates - type: reusable-element - if: ifRequestTypeEqualsTo|ReconfigureTLS - label: - text: labels.tls - schema: - $ref: schema#/properties/spec/properties/tls - type: single-step-form - - label: - text: labels.timeout - options: - - text: 5 minutes - value: 5m - - text: 10 minutes - value: 10m - - text: 30 minutes - value: 30m - - text: 1 hour - value: 1h - - text: 2 hours - value: 2h - - text: 5 hours - value: 5h - - text: 10 hours - value: 10h - schema: - $ref: schema#/properties/spec/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: labels.apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/spec/properties/apply - type: radio - type: single-step-form - id: basic - title: steps.0.label -type: multi-step-form + - type: tab-layout + label: New Config Secret + schema: temp/properties/reconfigurationType-shard + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + elements: + - type: block-layout + label: Config Secret + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret|shard|true + type: function + elements: + - type: label-element + label: Config Secret + subtitle: Select a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: schema/properties/spec/properties/configuration/properties/shard/properties/configSecret/properties/name + refresh: true + label: Config Secret + loader: + name: getConfigSecrets|shard + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/shard/properties/createSecret/properties/status + init: + type: func + value: setValueFromDbDetails|/spec/shardTopology/shard/configSecret/name + watcher: + func: onCreateSecretChange|shard + paths: + - temp/properties/shard/properties/createSecret/properties/status + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|create|shard + watchPaths: + - schema/properties/spec/properties/configuration/properties/shard/properties/configSecret/properties/name + - type: block-layout + label: Create a New Config Secret + showLabels: true + if: + type: function + name: isCreateSecret|shard + hasButton: + text: Save + hasCancel: cancelCreateSecret|shard + action: createNewConfigSecret|shard + elements: + - type: input + label: Secret Name + schema: temp/properties/shard/properties/createSecret/properties/name + validation: + type: required + - type: array-object-form + label: String Data + schema: temp/properties/shard/properties/createSecret/properties/data + buttonClass: is-light is-outlined + validation: + type: required + elements: + - type: select + label: Key + schema: key + loader: + name: onSelectedSecretChange|shard + watchPaths: + - temp/properties/shard/properties/createSecret/properties/data + validation: + type: required + - type: textarea + label: Value + schema: value + - type: multi-file-editor + editorHeight: 500px + readonly: true + if: + type: function + name: isNotCreateSecret|shard + loader: + name: onNewConfigSecretChange|shard + watchPaths: + - schema/properties/spec/properties/configuration/properties/shard/properties/configSecret/properties/name + schema: temp/properties/shard/newConfigSecret + - type: block-layout + label: ApplyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig|shard|true + type: function + elements: + - type: label-element + 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). + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/shard/selectedConfiguration + refresh: true + label: Configuration + loader: getConfigSecretsforAppyConfig + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|apply|shard + watchPaths: + - temp/properties/shard/selectedConfiguration + - type: multi-file-editor + editorHeight: 500px + schema: temp/properties/shard/applyConfig + loader: + name: setApplyConfig|shard + watchPaths: + - temp/properties/shard/selectedConfiguration + watcher: + func: onApplyconfigChange|shard + paths: + - temp/properties/shard/applyConfig + - type: block-layout + label: Remove + if: + name: ifReconfigurationTypeEqualsTo|remove|shard|true + type: function + elements: + - type: label-element + label: Remove + subtitle: Selected a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/shard/selectedConfigurationRemove + refresh: true + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|remove|shard + watchPaths: + - temp/properties/shard/selectedConfigurationRemove + - type: multi-file-editor + editorHeight: 500px + readonly: true + init: + type: func + value: onRemoveConfigChange|shard + watcher: + func: onRemoveConfigChange|shard + paths: + - temp/properties/shard/selectedConfigurationRemove + schema: temp/properties/shard/removeConfig + label: Sharded Reconfigure form + if: + name: ifDbTypeEqualsTo|sharded|configuration + type: function +# Reconfigure TLS + - type: block-layout + label: TLS + if: + name: ifRequestTypeEqualsTo|ReconfigureTLS + type: function + elements: + - type: radio + label: TLS Operation + schema: temp/properties/tlsOperation + if: + name: hasTlsField + type: function + options: + - text: Update + value: update + - text: Rotate + value: rotate + - text: Remove + value: remove + init: + type: func + value: initTlsOperation + watcher: + func: onTlsOperationChange + paths: + - temp/properties/tlsOperation + - type: switch + label: Remove TLS + fullwidth: true + if: + name: isTlsEnabled + type: function + schema: schema/properties/spec/properties/tls/properties/remove + - type: switch + label: Rotate Certificates + fullwidth: true + schema: schema/properties/spec/properties/tls/properties/rotateCertificates + if: + name: isTlsEnabled + type: function + - type: block-layout + label: Issuer Reference + showLabels: true + if: + name: showIssuerRefAndCertificates + type: function + elements: + - type: input + label: API Group + init: + type: func + value: initIssuerRefApiGroup + watcher: + func: initIssuerRefApiGroup + paths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + disable: true + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup + - type: select + label: Kind + options: + - text: Issuer + value: Issuer + - text: ClusterIssuer + value: ClusterIssuer + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/kind + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - type: select + label: Name + loader: + name: getIssuerRefsName + watchPaths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - schema/properties/metadata/properties/namespace + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/name + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/name + - type: block-layout + label: Certificates + showLabels: false + if: + name: showIssuerRefAndCertificates + type: function + loader: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates + elements: + - type: array-object-form + label: Certificates + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/tls/properties/certificates + elements: + - type: select + label: Alias + loader: fetchAliasOptions + disable: disableAlias + schema: alias + validation: + type: required + - type: input + label: Secret Name + schema: secretName + - type: input + label: Duration + schema: duration + - type: input + label: Renew Before + schema: renewBefore + - type: array-item-form + label: Organizations + buttonClass: is-light is-outlined + schema: subject/properties/organizations + element: + type: input + label: Organization + - type: array-item-form + label: Countries + buttonClass: is-light is-outlined + schema: subject/properties/countries + element: + type: input + label: Country + - type: array-item-form + label: Organizational Units + buttonClass: is-light is-outlined + schema: subject/properties/organizationalUnits + element: + type: input + label: Organizational Unit + - type: array-item-form + label: Provinces + buttonClass: is-light is-outlined + schema: subject/properties/provinces + element: + type: input + label: Province + - type: array-item-form + label: DNS Names + buttonClass: is-light is-outlined + schema: dnsNames + element: + type: input + label: DNS Name + - type: array-item-form + label: IP Addresses + buttonClass: is-light is-outlined + schema: ipAddresses + element: + type: input + label: IP Address +# common + - type: block-layout + label: OpsRequest Options + showLabels: true + elements: + - type: time-picker + label: Timeout + schema: 'schema/properties/spec/properties/timeout' + subtitle: Specify the maximum time allowed for the scaling operation to complete. Use formats like 30sec, 1min(1 minute) or 2h(2 hours). + - type: radio + label: Apply + schema: 'schema/properties/spec/properties/apply' + init: + type: func + value: setApplyToIfReady + options: + - text: IfReady (OpsRequest will be applied if database is ready) + value: IfReady + - text: Always (OpsRequest will always be applied) + value: Always diff --git a/charts/opskubedbcom-mongodbopsrequest-editor/ui/functions.js b/charts/opskubedbcom-mongodbopsrequest-editor/ui/functions.js index 1831ab9a2a..2ef03535df 100644 --- a/charts/opskubedbcom-mongodbopsrequest-editor/ui/functions.js +++ b/charts/opskubedbcom-mongodbopsrequest-editor/ui/functions.js @@ -1,3 +1,14 @@ +const { + axios, + useOperator, + store, + yaml, + useResourceInfo, + resourceCreate$api, + ref, + useToast, + axiosVue, +} = window.vueHelpers || {} const machines = { 'db.t.micro': { resources: { @@ -304,181 +315,269 @@ const machineList = [ 'db.r.24xlarge', ] -async function fetchJsons({ axios, itemCtx }) { - let ui = {} - let language = {} - let functions = {} - const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart +const configSecretKeys = ['mongod.conf', 'replicaset.json', 'configuration.js'] - 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) +let machinesFromPreset = [] + +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, + } } - return { - ui: ui.data || {}, - language: language.data || {}, - functions, + function returnFalse() { + return true } -} -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({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } -async function getNamespaces({ axios, storeGet }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 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) || [] + const resources = (resp && resp.data && resp.data.items) || [] - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 namespace = getValue(model, '/metadata/namespace') + // watchDependency('model#/metadata/namespace') - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/mongodbs`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/mongodbs`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) - const resources = (resp && resp.data && resp.data.items) || [] + const resources = (resp && resp.data && resp.data.items) || [] - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -async function getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) { - 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') + async function getDbDetails() { + machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] - if (namespace && name) { - const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/mongodbs/${name}` - const resp = await axios.get(url) + 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') - setDiscriminatorValue('/dbDetails', resp.data || {}) + if (namespace && name) { + const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/mongodbs/${name}` + const resp = await axios.get(url) - return resp.data || {} - } else return {} -} + setDiscriminatorValue('/dbDetails', resp.data || {}) -async function getDbVersions({ axios, storeGet, getValue, discriminator }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + return resp.data || {} + } else return {} + } - const url = `/clusters/${owner}/${cluster}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/kubedb-ui-presets` + let presetVersions = [] + setDiscriminatorValue('/filteredVersion', []) - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + 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 { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + presetVersions = presets.admin?.databases?.MongoDB?.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/mongodbversions`, + { + 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 allowed = found?.spec?.updateConstraints?.allowlist || [] + 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 filteredDbVersions = 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.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.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.includes(item.metadata?.name)) && + isVersionWithinConstraints(item.spec?.version, limit) + ) + }) + setDiscriminatorValue('/filteredVersion', filteredDbVersions) + return filteredDbVersions.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) - presets.status = String(e.status) + return [] } } - try { - const presetVersions = presets.admin?.databases?.MongoDB?.versions?.available || [] - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null, updateConstraints: null }, - }, - }, + 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 + } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/catalog.kubedb.com/v1alpha1/mongodbversions`, - { - params: queryParams, - }, - ) + 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 + } - const resources = (resp && resp.data && resp.data.items) || [] + function getVersionInfo() { + const filteredVersion = getValue(discriminator, '/filteredVersion') + if (filteredVersion.length) return '' - 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 allowed = found?.spec?.updateConstraints?.allowlist || [] - 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 filteredMongoDbVersions = 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.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.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.includes(item.metadata?.name)) && - isVersionWithinConstraints(item.spec?.version, limit) - ) + 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 filteredMongoDbVersions.map((item) => { + return txt + } + + function getVersion() { + return filteredVersion.map((item) => { const name = (item.metadata && item.metadata.name) || '' const specVersion = (item.spec && item.spec.version) || '' return { @@ -486,864 +585,1347 @@ async function getDbVersions({ axios, storeGet, getValue, discriminator }) { value: name, } }) - } catch (e) { - console.log(e) - return [] } -} -function versionCompare(v1, v2) { - const arr1 = v1.split('.').map(Number) - const arr2 = v2.split('.').map(Number) + function isVersionEmpty() { + const val = getValue(discriminator, '/filteredVersion') + return val.length === 0 + } - for (let i = 0; i < Math.max(arr1.length, arr2.length); i++) { - const num1 = arr1[i] || 0 - const num2 = arr2[i] || 0 + function ifRequestTypeEqualsTo(type) { + const selectedType = getValue(model, '/spec/type') + // watchDependency('model#/spec/type') - if (num1 > num2) return 1 // v1 is higher - if (num1 < num2) return -1 // v2 is higher + return selectedType === type } - return 0 // versions are equal -} -function isVersionWithinConstraints(version, constraints) { - let constraintsArr = [] - if (constraints.includes(',')) constraintsArr = constraints?.split(',')?.map((c) => c.trim()) - else constraintsArr = [constraints] + 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', + } - for (let constraint of constraintsArr) { - let match = constraint.match(/^(>=|<=|>|<)/) - let operator = match ? match[0] : '' - let constraintVersion = constraint.replace(/^(>=|<=|>|<)/, '').trim() + Object.keys(reqTypeMapping).forEach((key) => { + if (key !== selectedType) commit('wizard/model$delete', `/spec/${reqTypeMapping[key]}`) + }) + } + + function getDbTls() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') + + const { spec } = dbDetails || {} + return spec?.tls || undefined + } - let comparison = versionCompare(version, constraintVersion) + function getDbType() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') + + const { spec } = dbDetails || {} + const { shardTopology, replicaSet } = spec || {} + let verd = '' + if (shardTopology) { + verd = 'sharded' + } else { + if (replicaSet) { + verd = 'replicaSet' + } else verd = 'standalone' + } + + return verd + } + + function disableOpsRequest() { + if (itemCtx.value === 'HorizontalScaling') { + const dbType = getDbType() + + if (dbType === 'standalone') return true + else return false + } else return false + } + + function initNamespace() { + const { namespace } = route.query || {} + return namespace || null + } + + function initDatabaseRef() { + // watchDependency('model#/metadata/namespace') + const { name } = route.params || {} + return name + } + + function clearOpsReqSpec(verd, opsReqType) { if ( - (operator === '>=' && comparison < 0) || - (operator === '<=' && comparison > 0) || - (operator === '>' && comparison <= 0) || - (operator === '<' && comparison >= 0) - ) - return false + opsReqType === 'verticalScaling' || + opsReqType === 'horizontalScaling' || + opsReqType === 'volumeExpansion' || + opsReqType === 'configuration' + ) { + if (verd === 'sharded') { + commit('wizard/model$delete', `/spec/${opsReqType}/replicaSet`) + commit('wizard/model$delete', `/spec/${opsReqType}/replicas`) + commit('wizard/model$delete', `/spec/${opsReqType}/standalone`) + } else if (verd === 'standalone') { + commit('wizard/model$delete', `/spec/${opsReqType}/replicaSet`) + commit('wizard/model$delete', `/spec/${opsReqType}/configServer`) + commit('wizard/model$delete', `/spec/${opsReqType}/mongos`) + commit('wizard/model$delete', `/spec/${opsReqType}/shard`) + } else { + commit('wizard/model$delete', `/spec/${opsReqType}/standalone`) + commit('wizard/model$delete', `/spec/${opsReqType}/configServer`) + commit('wizard/model$delete', `/spec/${opsReqType}/mongos`) + commit('wizard/model$delete', `/spec/${opsReqType}/shard`) + } + } } - return true -} -function ifRequestTypeEqualsTo({ model, getValue, watchDependency }, type) { - const selectedType = getValue(model, '/spec/type') - watchDependency('model#/spec/type') + function asDatabaseOperation() { + return !!route.params.actions + } - return selectedType === type -} -function onRequestTypeChange({ model, getValue, commit }) { - 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 generateOpsRequestNameForClusterUI(getValue, model, route) { + const dbName = getValue(model, '/spec/databaseRef/name') -function getDbTls({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' - const { spec } = dbDetails || {} - return spec.tls || undefined -} + 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() -function getDbType({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' - const { spec } = dbDetails || {} - const { shardTopology, replicaSet } = spec || {} - let verd = '' - if (shardTopology) { - verd = 'sharded' - } else { - if (replicaSet) { - verd = 'replicaSet' - } else verd = 'standalone' + 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 } - return verd -} + function showAndInitNamespace() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/metadata/namespace', + value: `${route.query.namespace}`, + force: true, + }) + } -function disableOpsRequest({ itemCtx, discriminator, getValue, watchDependency }) { - if (itemCtx.value === 'HorizontalScaling') { - const dbType = getDbType({ - discriminator, - getValue, - watchDependency, - }) + return !ver + } - if (dbType === 'standalone') return true - else return false - } else return false -} + function showAndInitDatabaseRef() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/spec/databaseRef/name', + value: `${route.params.name}`, + force: true, + }) + } -function initNamespace({ route }) { - const { namespace } = route.query || {} - return namespace || null -} + return !ver + } -function initDatabaseRef({ route, watchDependency }) { - watchDependency('model#/metadata/namespace') - const { name } = route.params || {} - return name -} + 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() + + clearOpsReqSpec(verd, opsReqType) + return value === verd + } -function clearOpsReqSpec(verd, opsReqType, commit) { - if ( - opsReqType === 'verticalScaling' || - opsReqType === 'horizontalScaling' || - opsReqType === 'volumeExpansion' || - opsReqType === 'configuration' - ) { - if (verd === 'sharded') { - commit('wizard/model$delete', `/spec/${opsReqType}/replicaSet`) - commit('wizard/model$delete', `/spec/${opsReqType}/replicas`) - commit('wizard/model$delete', `/spec/${opsReqType}/standalone`) - } else if (verd === 'standalone') { - commit('wizard/model$delete', `/spec/${opsReqType}/replicaSet`) - commit('wizard/model$delete', `/spec/${opsReqType}/configServer`) - commit('wizard/model$delete', `/spec/${opsReqType}/mongos`) - commit('wizard/model$delete', `/spec/${opsReqType}/shard`) + // // machine profile stuffs + // let machinesFromPreset = [] + + function getMachines(type) { + const presets = storeGet('/kubedbuiPresets') || {} + const dbDetails = getValue(discriminator, '/dbDetails') + // const limits = dbDetails?.spec?.podTemplate?.spec?.resources?.limits || {} + const limits = (type === 'replicaSet' || type === 'standalone' + ? dbDetails?.spec?.podTemplate?.spec?.resources?.requests + : dbDetails?.spec?.shardTopology?.[type]?.podTemplate?.spec?.resources?.requests) || { + cpu: '', + memory: '', + } + + 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 { - commit('wizard/model$delete', `/spec/${opsReqType}/standalone`) - commit('wizard/model$delete', `/spec/${opsReqType}/configServer`) - commit('wizard/model$delete', `/spec/${opsReqType}/mongos`) - commit('wizard/model$delete', `/spec/${opsReqType}/shard`) + 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 asDatabaseOperation(route) { - return !!route.params.actions -} + function setMachine(type) { + const dbDetails = getValue(discriminator, '/dbDetails') + // const limits = dbDetails?.spec?.podTemplate?.spec?.resources?.limits || {} + const limits = (type === 'replicaSet' || type === 'standalone' + ? dbDetails?.spec?.podTemplate?.spec?.resources?.requests + : dbDetails?.spec?.shardTopology?.[type]?.podTemplate?.spec?.resources?.requests) || { + cpu: '', + memory: '', + } + 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[type] || 'custom' -function generateOpsRequestNameForClusterUI(getValue, model, route) { - const dbName = getValue(model, '/spec/databaseRef/name') + 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 } + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + function onMachineChange(type, valPath) { + let selectedMachine = {} + selectedMachine = getValue(discriminator, `/machine-${type}`) + const machine = machinesFromPreset.find((item) => item.id === selectedMachine.machine) - const resources = route.params.resource || '' - const resource = resources.slice(0, -1) + 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 opsName = dbName ? dbName : resource - return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` -} + const path = `/spec/verticalScaling/${type}/resources` -function showAndInitName({ route, commit, getValue, model, watchDependency }) { - watchDependency('model#/spec/type') - watchDependency('model#/spec/databaseRef/name') - const ver = asDatabaseOperation(route) + if (obj && Object.keys(obj).length) + commit('wizard/model$update', { + path: path, + value: obj, + force: true, + }) - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + // update metadata.annotations + const annotations = getValue(model, '/metadata/annotations') || {} + const instance = annotations['kubernetes.io/instance-type'] + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = {} + } + parsedInstance[type] = selectedMachine.machine + annotations['kubernetes.io/instance-type'] = JSON.stringify(parsedInstance) + + if (machinesFromPreset.length) + commit('wizard/model$update', { + path: '/metadata/annotations', + value: annotations, + force: true, + }) - 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, - }) + if (parsedInstance && Object.keys(parsedInstance).length === 0) + commit('wizard/model$delete', '/metadata/annotations') } - return !ver -} -function showAndInitNamespace({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/metadata/namespace', - value: `${route.query.namespace}`, - force: true, + + function isMachineCustom(path) { + // watchDependency(`discriminator#${path}`) + const machine = getValue(discriminator, `${path}`) + return machine === 'custom' + } + + // Fetch and store database Infos + // for secret configurations in reconfigure + let configSecrets = [] + let secretConfigData = [] + + 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: ['mongod.conf', 'replicaset.json', 'configuration.js'], + }, + }, + ) + configSecrets = resp?.data?.response?.availableSecrets || [] + secretConfigData = resp?.data?.response?.configurations || [] + } 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 } - return !ver -} -function showAndInitDatabaseRef({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/spec/databaseRef/name', - value: `${route.params.name}`, - force: true, + async function getConfigSecretsforAppyConfig() { + const secrets = secretConfigData.map((item) => { + return { text: item.componentName, value: item.componentName } }) + return secrets } - return !ver -} -function showConfigureOpsrequestLabel({ route }) { - return !asDatabaseOperation(route) -} -function showAndInitOpsRequestType({ route, commit }) { - const ver = asDatabaseOperation(route) - const opMap = { - upgrade: 'UpdateVersion', - updateVersion: 'UpdateVersion', - horizontalscaling: 'HorizontalScaling', - verticalscaling: 'VerticalScaling', - volumeexpansion: 'VolumeExpansion', - restart: 'Restart', - reconfiguretls: 'ReconfigureTLS', - reconfigure: 'Reconfigure', - } - if (ver) { - const operation = route.params.actions - const match = /^(.*)-opsrequest-(.*)$/.exec(operation) - const opstype = match[2] + 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: '/spec/type', - value: opMap[opstype], + path: `/temp/${type}applyConfig`, + value: result, force: true, }) + + return result } - return !ver -} + 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` -// vertical scaling -function ifDbTypeEqualsTo({ discriminator, getValue, watchDependency, commit }, value, opsReqType) { - const verd = getDbType({ discriminator, getValue, watchDependency }) + const selectedConfiguration = + configType === 'create' ? getValue(model, path) : getValue(discriminator, path) - clearOpsReqSpec(verd, opsReqType, commit) - return value === verd -} + if (selectedConfiguration) + return { subtitle: ` You have selected ${selectedConfiguration} secret` } + else return { subtitle: 'No secret selected' } + } -// machine profile stuffs -let machinesFromPreset = [] + 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 '' + } -function getMachines({ storeGet }) { - const presets = storeGet('/kubedbuiPresets') || {} - const avlMachines = presets.admin?.machineProfiles?.available || [] - let arr = [] - if (avlMachines.length) { - arr = avlMachines.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - 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 } - } else return { text: machine, value: machine } + 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 } }) - } else { - arr = machineList - .map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + + // Convert data object back to YAML string + return yaml.dump(data) + } + + 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` + } + } + + 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])) + + 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, }) - .filter((val) => !!val) + toast.success('Secret created successfully') + } catch (error) { + const errMsg = decodeError(error, 'Failed to create secret') + toast.error(errMsg, { timeout: 5000 }) + cancelCreateSecret() + } } - return arr -} -function setMachine({ getValue, discriminator, storeGet }, type) { - const dbDetails = getValue(discriminator, '/dbDetails') - 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 = {} + 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 + ) } - const machine = parsedInstance[type] || 'custom' - machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] + function isCreateSecret(type) { + type = type ? type + '/' : '' + const selectedSecret = getValue(model, `spec/configuration/${type}configSecret/name`) + const res = selectedSecret === 'Create' - const machinePresets = machinesFromPreset.find((item) => item.id === machine) - if (machinePresets) return machine - else return 'custom' -} + if (res === true) { + commit('wizard/temp$update', { + path: `${type}createSecret/status`, + value: 'pending', + }) + } + return res + } + + function isNotCreateSecret(type) { + return !isCreateSecret(type) + } -function onMachineChange({ getValue, discriminator, commit, model }, type, valPath) { - let selectedMachine = '' - selectedMachine = getValue(discriminator, `/machine-${type}`) - const machine = machinesFromPreset.find((item) => item.id === selectedMachine) + 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`) - let obj = {} - if (selectedMachine !== 'custom') { - if (machine) obj = { limits: { ...machine?.limits }, requests: { ...machine?.limits } } - else obj = machines[selectedMachine]?.resources - } else { - const val = getValue(discriminator, `/dbDetails${valPath}`) || {} - obj = Array.isArray(val) ? val[0]?.resources : { ...val } + 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', + }) } - const path = `/spec/verticalScaling/${type}/resources` + async function onApplyconfigChange(type) { + type = type ? type + '/' : '' + const configValue = getValue(discriminator, `${type}applyConfig`) - if (obj && Object.keys(obj).length) + if (!configValue) { + commit('wizard/model$delete', `/spec/configuration/${type}applyConfig`) + return + } + const tempConfigObj = {} + configValue.forEach((item) => { + if (item.name) { + 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: path, - value: obj, - force: true, + 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], + }) + }) + } else { + configObj.push({ name: '', content: '' }) + } + return configObj + } + + function onRemoveConfigChange(type) { + type = type ? type + '/' : '' + const configPath = `/${type}selectedConfigurationRemove` + const selectedConfig = getValue(discriminator, configPath) - // update metadata.annotations - const annotations = getValue(model, '/metadata/annotations') || {} - const instance = annotations['kubernetes.io/instance-type'] - let parsedInstance = {} - try { - if (instance) parsedInstance = JSON.parse(instance) - } catch (e) { - console.log(e) - parsedInstance = {} - } - if (selectedMachine === 'custom') delete parsedInstance[type] - else parsedInstance[type] = selectedMachine - annotations['kubernetes.io/instance-type'] = JSON.stringify(parsedInstance) - - if (machinesFromPreset.length) + if (!selectedConfig) { + commit('wizard/model$delete', `/spec/configuration/${type}removeCustomConfig`) + return [{ name: '', content: '' }] + } commit('wizard/model$update', { - path: '/metadata/annotations', - value: annotations, - force: true, + path: `/spec/configuration/${type}removeCustomConfig`, + value: true, }) - if (parsedInstance && Object.keys(parsedInstance).length === 0) - commit('wizard/model$delete', '/metadata/annotations') -} + const configuration = secretConfigData.find((item) => item.componentName === selectedConfig) -function isMachineCustom({ watchDependency, getValue, discriminator }, path) { - watchDependency(`discriminator#${path}`) - const machine = getValue(discriminator, `${path}`) - return machine === 'custom' -} + if (!configuration.data) { + return [{ name: '', content: '' }] + } -// for config secret -async function getConfigSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + 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 + } - const secrets = (resp && resp.data && resp.data.items) || [] + async function onNewConfigSecretChange(type) { + type = type ? type + '/' : '' + const path = `/spec/configuration/${type}configSecret/name` + const selectedSecret = getValue(model, path) - const filteredSecrets = secrets + if (!selectedSecret) { + commit('wizard/model$delete', `/spec/configuration/${type}configSecret`) + return [{ name: '', content: '' }] + } + if (selectedSecret === 'Create') return [{ name: '', content: '' }] - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return filteredSecrets -} + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = storeGet('/route/query/namespace') || getValue(model, '/metadata/namespace') -function createSecretUrl({ storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 + }) + } + }) - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/secrets/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/secrets/create` + return configObj + } catch (e) { + console.error('Error fetching secret:', e) + return [{ name: '', content: '' }] + } } -} - -function isEqualToValueFromType({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/valueFromType') - const valueFrom = getValue(discriminator, '/valueFromType') - return valueFrom === value -} -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function onSelectedSecretChange(type, index) { + type = type ? type + '/' : '' + const secretData = getValue(discriminator, `${type}createSecret/data`) || [] + const selfSecrets = secretData.map((item) => item.key) - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + const remainingSecrets = configSecretKeys.filter((item) => !selfSecrets.includes(item)) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, + const selfKey = getValue(discriminator, `${type}createSecret/data/${index}/key`) + if (selfKey) { + remainingSecrets.push(selfKey) + } + const resSecret = remainingSecrets.map((item) => { + return { text: item, value: item } }) - - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + return resSecret } - return ans -} -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` + function ifReconfigurationTypeEqualsTo(value, property, isShard) { + let path = '/reconfigurationType' + if (isShard) path += `-${property}` + const reconfigurationType = getValue(discriminator, path) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }) + const watchPath = `discriminator#${path}` + // watchDependency(watchPath) + return reconfigurationType === value + } - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + function onReconfigurationTypeChange(property, isShard) { + setDiscriminatorValue(`/${property}/applyConfig`, []) + let path = '/reconfigurationType' + if (isShard) path += `-${property}` + const reconfigurationType = getValue(discriminator, path) + if (reconfigurationType === 'remove') { + commit('wizard/model$delete', `/spec/configuration/${property}`) + + commit('wizard/model$update', { + path: `/spec/configuration/${property}/removeCustomConfig`, + value: true, + force: true, + }) + } else { + commit('wizard/model$delete', `/spec/configuration/${property}/configSecret`) + commit('wizard/model$delete', `/spec/configuration/${property}/applyConfig`) + commit('wizard/model$delete', `/spec/configuration/${property}/removeCustomConfig`) + } } - return ans -} -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - group, - version, - resource, -) { - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/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) - }) + function isEqualToValueFromType(value) { + // watchDependency('discriminator#/valueFromType') + const valueFrom = getValue(discriminator, '/valueFromType') + return valueFrom === value } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + 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) } - }) -} -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) - - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) + + return ans } + async function getResourceList({ group, version, resource }) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` -// reconfiguration type -function ifReconfigurationTypeEqualsTo( - { discriminator, getValue, watchDependency }, - value, - property, - isShard, -) { - let path = '/reconfigurationType' - if (isShard) path += `-${property}` - const reconfigurationType = getValue(discriminator, path) - const watchPath = `discriminator#${path}` - watchDependency(watchPath) - return reconfigurationType === value -} + let ans = [] + try { + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) -function onApplyconfigChange({ discriminator, getValue, commit }, type) { - const configPath = `/${type}/applyConfig` - const applyconfig = getValue(discriminator, configPath) + const items = (resp && resp.data && resp.data.items) || [] + ans = items + } catch (e) { + console.log(e) + } - const configObj = {} + 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 (applyconfig) { - applyconfig.forEach((item) => { - const { key, value } = item - configObj[key] = value + 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, + }) - commit('wizard/model$update', { - path: `/spec/configuration/${type}/applyConfig`, - value: configObj, - force: true, - }) -} - -function onReconfigurationTypeChange( - { commit, discriminator, getValue, setDiscriminatorValue }, - property, - isShard, -) { - setDiscriminatorValue(`/${property}/applyConfig`, []) - let path = '/reconfigurationType' - if (isShard) path += `-${property}` - const reconfigurationType = getValue(discriminator, path) - if (reconfigurationType === 'remove') { - commit('wizard/model$delete', `/spec/configuration/${property}`) + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } - commit('wizard/model$update', { - path: `/spec/configuration/${property}/removeCustomConfig`, - value: true, - force: true, + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } }) - } else { - commit('wizard/model$delete', `/spec/configuration/${property}/configSecret`) - commit('wizard/model$delete', `/spec/configuration/${property}/applyConfig`) - commit('wizard/model$delete', `/spec/configuration/${property}/removeCustomConfig`) } -} -// for tls -function hasTlsField({ discriminator, getValue, watchDependency }) { - const tls = getDbTls({ - discriminator, - getValue, - watchDependency, - }) + // for tls + function hasTlsField() { + const tls = getDbTls() - return !!tls -} + return !!tls + } -function initIssuerRefApiGroup({ getValue, model, watchDependency }) { - const kind = getValue(model, '/spec/tls/issuerRef/kind') - watchDependency('model#/spec/tls/issuerRef/kind') + function initIssuerRefApiGroup() { + const kind = getValue(model, '/spec/tls/issuerRef/kind') + // watchDependency('model#/spec/tls/issuerRef/kind') - if (kind) { - return 'cert-manager.io' - } else return undefined -} + if (kind) { + return 'cert-manager.io' + } else return undefined + } -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - 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` + 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') - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + 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 presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + 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) - presets.status = String(e.status) + return [] } } - let clusterIssuers = presets.admin?.clusterIssuers?.available || [] - if (presets.status === '404') { - const url = `/clusters/${owner}/${cluster}/proxy/cert-manager.io/v1/clusterissuers` - return getIssuer(url) + } + + 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, + }) + } else if (tlsOperation === 'remove') { + commit('wizard/model$update', { + path: '/spec/tls/remove', + value: true, + force: true, + }) } - return clusterIssuers } - async function getIssuer(url) { - try { - const resp = await axios.get(url) - const resources = (resp && resp.data && resp.data.items) || [] + function showIssuerRefAndCertificates() { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // watchDependency('discriminator#/tlsOperation') + const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + return verd + } + + function isIssuerRefRequired() { + const hasTls = hasTlsField() + return hasTls ? false : '' + } + + function getRequestTypeFromRoute() { + const isDbloading = isDbDetailsLoading() + const { query } = route || {} + const { requestType } = query || {} + return isDbloading ? '' : requestType || '' + } + + 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) { + const retValue = getValue(discriminator, `/dbDetails${path}`) + if (commitPath) { + 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 resources - } catch (e) { - console.log(e) - return [] } + return retValue || undefined } -} -function initTlsOperation() { - return 'update' -} -function onTlsOperationChange({ discriminator, getValue, commit }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + function getAliasOptions() { + return ['server', 'client', 'metrics-exporter'] + } - commit('wizard/model$delete', '/spec/tls') + function isNamespaceDisabled() { + const { namespace } = route.query || {} + return !!namespace + } - if (tlsOperation === 'rotate') { - commit('wizard/model$update', { - path: '/spec/tls/rotateCertificates', - value: true, - force: true, - }) - } else if (tlsOperation === 'remove') { - commit('wizard/model$update', { - path: '/spec/tls/remove', - value: true, - force: true, - }) + function isDatabaseRefDisabled() { + const { name } = route.params || {} + return !!name } -} -function showIssuerRefAndCertificates({ discriminator, getValue, watchDependency }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') - watchDependency('discriminator#/tlsOperation') - const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' + function onNamespaceChange() { + commit('wizard/model$delete', '/spec/type') + } - return verd -} + function onDbChange() { + commit('wizard/model$delete', '/spec/type') + getDbDetails() + } -function isIssuerRefRequired({ discriminator, getValue, watchDependency }) { - const hasTls = hasTlsField({ - discriminator, - getValue, - watchDependency, - }) + function setApplyToIfReady() { + return 'IfReady' + } - return !hasTls -} + function isVerticalScaleTopologyRequired(type) { + // watchDependency(`discriminator#/topologyKey-${type}`) + // watchDependency(`discriminator#/topologyValue-${type}`) -function getRequestTypeFromRoute({ route, model, discriminator, getValue, watchDependency }) { - const isDbloading = isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) - const { query } = route || {} - const { requestType } = query || {} - return isDbloading ? '' : requestType || '' -} + const key = getValue(discriminator, `/topologyKey-${type}`) + const value = getValue(discriminator, `/topologyValue-${type}`) + const path = `/spec/verticalScaling/${type}/topology` -function isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - watchDependency('model#/spec/databaseRef/name') - const dbDetails = getValue(discriminator, '/dbDetails') - const dbName = getValue(model, '/spec/databaseRef/name') + if (key || value) { + commit('wizard/model$update', { + path: path, + value: { key, value }, + force: true, + }) + return '' + } else { + commit('wizard/model$delete', path) + return false + } + } - return !dbDetails || !dbName -} + function checkVolume(initpath, path) { + const volume = getValue(discriminator, `/dbDetails${initpath}`) + const input = getValue(model, path) -function setValueFromDbDetails( - { discriminator, getValue, watchDependency, commit }, - path, - commitPath, -) { - watchDependency('discriminator#/dbDetails') - const retValue = getValue(discriminator, `/dbDetails${path}`) + try { + const sizeInBytes = parseSize(volume) + const inputSizeInBytes = parseSize(input) - if (commitPath) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + if (inputSizeInBytes >= sizeInBytes) return + else return 'Cannot expand to lower volume!' + } catch (err) { + return err.message || 'Invalid' + } + } - // computed called when tls fields is not visible - if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined + 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, + } - // 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, - }) + 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] } - return retValue || undefined -} + function fetchAliasOptions() { + return getAliasOptions ? getAliasOptions() : [] + } -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} + function validateNewCertificates({ itemCtx }) { + const addedAliases = (model && model.map((item) => item.alias)) || [] -function isNamespaceDisabled({ route }) { - const { namespace } = route.query || {} - return !!namespace -} + if (addedAliases.includes(itemCtx.alias) && itemCtx.isCreate) { + return { isInvalid: true, message: 'Alias already exists' } + } + return {} + } -function isDatabaseRefDisabled({ route }) { - const { name } = route.params || {} - return !!name -} + function disableAlias() { + return !!(model && model.alias) + } -function onNamespaceChange({ commit }) { - commit('wizard/model$delete', '/spec/type') -} + function objectToYaml(obj, indent = 0) { + if (obj === null || obj === undefined) return 'null' + if (typeof obj !== 'object') return JSON.stringify(obj) -function onDbChange({ commit, axios, storeGet, model, getValue, setDiscriminatorValue }) { - commit('wizard/model$delete', '/spec/type') - getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) -} + const spaces = ' '.repeat(indent) -function setApplyToIfReady() { - return 'IfReady' -} + if (Array.isArray(obj)) { + return obj + .map((item) => `${spaces}- ${objectToYaml(item, indent + 1).trimStart()}`) + .join('\n') + } -function isVerticalScaleTopologyRequired( - { watchDependency, getValue, discriminator, commit }, - type, -) { - watchDependency(`discriminator#/topologyKey-${type}`) - watchDependency(`discriminator#/topologyValue-${type}`) + return Object.keys(obj) + .map((key) => { + const value = obj[key] + const keyLine = `${spaces}${key}:` - const key = getValue(discriminator, `/topologyKey-${type}`) - const value = getValue(discriminator, `/topologyValue-${type}`) - const path = `/spec/verticalScaling/${type}/topology` + if (value === null || value === undefined) { + return `${keyLine} null` + } - if (key || value) { - commit('wizard/model$update', { - path: path, - value: { key, value }, - force: true, - }) - return true - } else { - commit('wizard/model$delete', path) - return false + 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 checkVolume({ model, discriminator, getValue }, initpath, path) { - const volume = getValue(discriminator, `/dbDetails${initpath}`) - const input = getValue(model, path) + async function getSelectedConfigSecretValue(type) { + const path = `/spec/configuration/${type}/configSecret/name` + const selectedSecret = getValue(model, path) - try { - const sizeInBytes = parseSize(volume) - const inputSizeInBytes = parseSize(input) + if (!selectedSecret) { + return '' + } - if (inputSizeInBytes >= sizeInBytes) return true - else return 'Cannot expand to lower volume!' - } catch (err) { - return err.message || 'Invalid' + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = storeGet('/route/query/namespace') || getValue(model, '/metadata/namespace') + + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets/${selectedSecret}`, + ) + + const secretData = resp.data?.data || {} + let data = {} + Object.keys(secretData).forEach((item) => { + try { + // Decode base64 string + const decodedString = atob(secretData[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(secretData[item]) // Fallback to decoded string + } + }) + + // Convert data object back to YAML string + return yaml.dump(data) + } catch (e) { + console.error('Error fetching secret:', e) + return '' + } } -} -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 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 + } -return { - isRancherManaged, - fetchJsons, - returnFalse, - getNamespaces, - getDbs, - getDbDetails, - getDbVersions, - ifRequestTypeEqualsTo, - onRequestTypeChange, - getDbTls, - getDbType, - disableOpsRequest, - initNamespace, - initDatabaseRef, - clearOpsReqSpec, - - showAndInitName, - showAndInitNamespace, - showAndInitDatabaseRef, - showConfigureOpsrequestLabel, - showAndInitOpsRequestType, - - ifDbTypeEqualsTo, - getConfigSecrets, - createSecretUrl, - isEqualToValueFromType, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - ifReconfigurationTypeEqualsTo, - onReconfigurationTypeChange, - onApplyconfigChange, - hasTlsField, - initIssuerRefApiGroup, - getIssuerRefsName, - initTlsOperation, - onTlsOperationChange, - showIssuerRefAndCertificates, - isIssuerRefRequired, - getRequestTypeFromRoute, - isDbDetailsLoading, - setValueFromDbDetails, - getAliasOptions, - isNamespaceDisabled, - isDatabaseRefDisabled, - onDbChange, - onNamespaceChange, - setApplyToIfReady, - isVerticalScaleTopologyRequired, - getMachines, - setMachine, - onMachineChange, - isMachineCustom, - checkVolume, + 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, + }) + } + + return { + setExporter, + onExporterResourceChange, + fetchAliasOptions, + validateNewCertificates, + disableAlias, + isRancherManaged, + fetchJsons, + returnFalse, + getNamespaces, + getDbs, + getDbDetails, + getDbVersions, + getVersionInfo, + isVersionEmpty, + getVersion, + ifRequestTypeEqualsTo, + onRequestTypeChange, + getDbTls, + getDbType, + disableOpsRequest, + initNamespace, + initDatabaseRef, + clearOpsReqSpec, + showAndInitName, + showAndInitNamespace, + showAndInitDatabaseRef, + showConfigureOpsrequestLabel, + showAndInitOpsRequestType, + ifDbTypeEqualsTo, + getConfigSecrets, + fetchConfigSecrets, + createSecretUrl, + isEqualToValueFromType, + getNamespacedResourceList, + getResourceList, + resourceNames, + unNamespacedResourceNames, + ifReconfigurationTypeEqualsTo, + onReconfigurationTypeChange, + onApplyconfigChange, + hasTlsField, + initIssuerRefApiGroup, + getIssuerRefsName, + initTlsOperation, + onTlsOperationChange, + showIssuerRefAndCertificates, + isIssuerRefRequired, + getRequestTypeFromRoute, + isDbDetailsLoading, + setValueFromDbDetails, + getAliasOptions, + isNamespaceDisabled, + isDatabaseRefDisabled, + onDbChange, + onNamespaceChange, + setApplyToIfReady, + isVerticalScaleTopologyRequired, + getMachines, + setMachine, + onMachineChange, + isMachineCustom, + checkVolume, + getSelectedConfigSecretValue, + setApplyConfig, + getConfigSecretsforAppyConfig, + getSelectedConfigurationData, + getSelectedConfigurationName, + getSelectedConfigurationValueForRemove, + onRemoveConfigChange, + onNewConfigSecretChange, + createNewConfigSecret, + isCreateSecret, + isNotCreateSecret, + onCreateSecretChange, + cancelCreateSecret, + onSelectedSecretChange, + isTlsEnabled, + } } diff --git a/charts/opskubedbcom-mssqlserveropsrequest-editor/ui/create-ui.yaml b/charts/opskubedbcom-mssqlserveropsrequest-editor/ui/create-ui.yaml index 3044be462e..a2ef24e031 100644 --- a/charts/opskubedbcom-mssqlserveropsrequest-editor/ui/create-ui.yaml +++ b/charts/opskubedbcom-mssqlserveropsrequest-editor/ui/create-ui.yaml @@ -1,329 +1,497 @@ -steps: -- form: - discriminator: - dbDetails: - type: object +type: multi-step-form +step: + - type: single-step-form + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - schema: - $ref: discriminator#/properties/dbDetails - type: input - - if: showAndInitName - label: - text: labels.op_req_name - required: true - schema: - $ref: schema#/properties/metadata/properties/name - type: input - - computed: initNamespace - disabled: isNamespaceDisabled - fetch: getNamespaces - hasGroup: isRancherManaged - if: showAndInitNamespace - label: - text: labels.namespace - onChange: onNamespaceChange - required: true - schema: - $ref: schema#/properties/metadata/properties/namespace - type: select - - computed: initDatabaseRef - disabled: isDatabaseRefDisabled - fetch: getDbs - if: showAndInitDatabaseRef - label: - text: labels.databaseRef - onChange: onDbChange - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/databaseRef/properties/name - type: select - - if: showConfigureOpsrequestLabel - label: - text: labels.config_ops_request - type: label-element - - computed: getRequestTypeFromRoute - disabled: isDbDetailsLoading - hasDescription: true - if: showAndInitOpsRequestType - individualItemDisabilityCheck: disableOpsRequest - label: - text: labels.ops_request_type - onChange: onRequestTypeChange - options: - - description: options.UpdateVersion.description - text: options.UpdateVersion.text - value: UpdateVersion - - description: options.HorizontalScaling.description - text: options.HorizontalScaling.text - value: HorizontalScaling - - description: options.VerticalScaling.description - text: options.VerticalScaling.text - value: VerticalScaling - - description: options.VolumeExpansion.description - text: options.VolumeExpansion.text - value: VolumeExpansion - - description: options.Restart.description - text: options.Restart.text - value: Restart - - description: options.Reconfigure.description - text: options.Reconfigure.text - value: Reconfigure - schema: - $ref: schema#/properties/spec/properties/type - type: radio - - elements: - - computed: setValueFromDbDetails|/spec/version - fetch: getDbVersions - label: - text: labels.targetVersion - schema: - $ref: schema#/properties/spec/properties/updateVersion/properties/targetVersion - type: select - if: ifRequestTypeEqualsTo|UpdateVersion - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/replicas - label: - text: Replicas - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/replicas - type: input - if: ifRequestTypeEqualsTo|HorizontalScaling - label: - text: Horizontal Scaling Form - type: single-step-form - - elements: - - discriminator: - machine: - default: "" - type: string - elements: - - computed: setMachine - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|mssqlserver|/spec/podTemplate/spec/containers - schema: - $ref: discriminator#/machine - type: select - - if: isMachineCustom - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/mssqlserver/properties/resources - type: resource-input-form - - label: - text: Node Selection Policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/mssqlserver/properties/nodeSelectionPolicy - type: select - - elements: - - label: - text: key - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/mssqlserver/properties/topology/properties/key - type: input - - label: - text: value - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/mssqlserver/properties/topology/properties/value - type: input - label: - text: Topology - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/mssqlserver/properties/topology - show_label: true - type: single-step-form - label: - text: MSSQLServer - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/mssqlserver - show_label: true - type: single-step-form - - computed: setResource|/spec/podTemplate/spec/containers - label: - text: Exporter - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/exporter/properties/resources - type: resource-input-form - - computed: setResource|/spec/podTemplate/spec/containers - label: - text: Coordinator - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/coordinator/properties/resources - type: resource-input-form - if: ifRequestTypeEqualsTo|VerticalScaling - type: single-step-form - - elements: - - elements: - - computed: setValueFromDbDetails|/spec/storage/resources/requests/storage - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/mssqlserver - type: input - validationRuleObject: - func: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/mssqlserver - label: - text: MSSQLServer - schema: - $ref: schema#/properties/spec/properties/volumeExpansion - show_label: true - type: single-step-form - - label: - text: Mode +# common + - type: input + label: op_req_name + if: + type: function + name: showAndInitName + validation: + type: required + schema: schema/properties/metadata/properties/name + - type: select + label: Namespace + if: + type: function + name: showAndInitNamespace + init: + type: func + value: initNamespace + disable: isNamespaceDisabled + loader: getNamespaces + validation: + type: required + hasGroup: isRancherManaged + schema: schema/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/metadata/properties/namespace + - type: select + label: Database Ref + if: + type: function + name: showAndInitDatabaseRef + loader: + name: getDbs + watchPaths: + - schema/properties/metadata/properties/namespace + init: + type: func + value: initDatabaseRef + validation: + type: required + disable: isDatabaseRefDisabled + refresh: true + watcher: + paths: + - schema/properties/spec/properties/databaseRef/properties/name + func: onDbChange + schema: schema/properties/spec/properties/databaseRef/properties/name + - type: label-element + label: config_ops_request + if: + type: function + name: showConfigureOpsrequestLabel + - type: radio + label: Type of Ops Request + if: + type: function + name: showAndInitOpsRequestType options: - - text: Offline - value: Offline - - text: Online - value: Online - required: true - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/mode - type: select - if: ifRequestTypeEqualsTo|VolumeExpansion - label: - text: Volume Expansion Form - type: single-step-form - - elements: - - discriminator: - reconfigurationType: - type: string + - 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 + init: + type: func + value: getRequestTypeFromRoute + disable: isDbDetailsLoading + watcher: + func: onRequestTypeChange + paths: + - schema/properties/spec/properties/type + isHorizontal: true + schema: schema/properties/spec/properties/type +# UpdateVersion + - type: block-layout + showLabels: true + label: Version + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|UpdateVersion elements: - - label: - text: labels.reconfigurationType - onChange: onReconfigurationTypeChange - options: - - text: Select New Config Secret - value: selectNewConfigSecret - - text: Apply Config - value: applyConfig - - text: Remove - value: remove - required: true - schema: - $ref: discriminator#/properties/reconfigurationType - type: radio - - elements: - - add_new_button: - label: labels.createConfig - target: _blank - url: - function: createSecretUrl - computed: setValueFromDbDetails|/spec/configSecret/name - fetch: getConfigSecrets - label: - text: labels.configSecret - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret/properties/name - type: select - if: ifReconfigurationTypeEqualsTo|selectNewConfigSecret - label: - text: Configuration config secret - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret - type: single-step-form - - addFormLabel: labels.applyConfig.label - element: - discriminator: - configArray: - emitAs: applyConfig - type: array + - type: select-compare + label: Target Version + subtitle: Select the desired MSSQLServer version to which you want to update your database. + init: + type: func + value: setValueFromDbDetails|/spec/version + loader: getDbVersions + schema: schema/properties/spec/properties/updateVersion/properties/targetVersion + - type: info + label: '' + loader: + name: getVersionInfo + watchPaths: + - temp/properties/filteredVersion + if: + type: function + name: isVersionEmpty +# Horizontal Scale + - type: block-layout + label: Horizontal Scaling Form + showLabels: true + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|HorizontalScaling + elements: + - type: horizontal-layout elements: - - label: - text: labels.applyConfig.key - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/key - type: input - - label: - text: labels.applyConfig.value - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/value - type: editor - type: single-step-form - if: ifReconfigurationTypeEqualsTo|applyConfig - label: - text: labels.applyConfig.label - onChange: onApplyconfigChange - required: true - schema: - $ref: discriminator#/properties/applyConfig - tableContents: - - inTableColumn: true - label: - text: labels.applyConfig.key - path: key - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.applyConfig.value - path: value - type: value - typeOfValue: code - type: single-step-form-array - - if: returnFalse - label: - text: labels.removeCustomConfig - schema: - $ref: schema#/properties/spec/properties/configuration/properties/removeCustomConfig - type: switch - label: - text: labels.configuration - schema: - $ref: schema#/properties/spec/properties/configuration - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|Reconfigure - label: - text: Reconfigure Form - type: single-step-form - - label: - text: labels.timeout - options: - - text: 5 minutes - value: 5m - - text: 10 minutes - value: 10m - - text: 30 minutes - value: 30m - - text: 1 hour - value: 1h - - text: 2 hours - value: 2h - - text: 5 hours - value: 5h - - text: 10 hours - value: 10h - schema: - $ref: schema#/properties/spec/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: labels.apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/spec/properties/apply - type: radio - type: single-step-form - id: basic - title: steps.0.label -type: multi-step-form + - type: input-compare + label: Replicas + header: Replica + subtitle: Define the total number of replicas for the database. Increasing replicas improves fault tolerance and load distribution, while reducing replicas conserves resources + init: + type: func + value: setValueFromDbDetails|/spec/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/replicas + - type: info + 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. +# vertical Scale + - type: block-layout + if: + type: function + name: ifRequestTypeEqualsTo|VerticalScaling + elements: + - type: block-layout + label: MSSQLServer Vertical Scaling + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines + init: + type: func + value: setMachine + watcher: + func: onMachineChange|mssqlserver|/spec/podTemplate/spec/containers + paths: + - temp/properties/machine + schema: temp/properties/machine + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/mssqlserver/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired + schema: temp/topologyKey + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired + schema: temp/topologyValue + - type: block-layout + label: Exporter + showLabels: true + hideBlock: true + elements: + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setExporter|cpu + type: input + 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 + watcher: + func: onExporterResourceChange|memory + paths: + - schema/properties/spec/properties/verticalScaling/properties/exporter/properties/resources/properties/limits/properties/memory + - type: horizontal-layout + showLabels: true + label: Coordinator + elements: + - type: input + label: CPU Requests + schema: schema/properties/spec/properties/verticalScaling/properties/coordinator/properties/resources/properties/requests/cpu + init: + type: func + value: setValueFromDbDetails|/spec/coordinator/podTemplate/spec/resources/requests/cpu|/spec/verticalScaling/coordinator/resources/requests/cpu + - type: input + label: CPU Limits + schema: schema/properties/spec/properties/verticalScaling/properties/coordinator/properties/resources/properties/limits/cpu + init: + type: func + value: setValueFromDbDetails|/spec/coordinator/podTemplate/spec/resources/limits/cpu|/spec/verticalScaling/coordinator/resources/limits/cpu + - type: input + label: Memory Requests + schema: schema/properties/spec/properties/verticalScaling/properties/coordinator/properties/resources/properties/requests/memory + init: + type: func + value: setValueFromDbDetails|/spec/coordinator/podTemplate/spec/resources/requests/memory|/spec/verticalScaling/coordinator/resources/requests/memory + - type: input + label: Memory Limits + schema: schema/properties/spec/properties/verticalScaling/properties/coordinator/properties/resources/properties/limits/memory + init: + type: func + value: setValueFromDbDetails|/spec/coordinator/podTemplate/spec/resources/limits/memory|/spec/verticalScaling/coordinator/resources/limits/memory +# Volume Expansion + + - type: block-layout + label: Volume Expansion Form + if: + type: function + name: ifRequestTypeEqualsTo|VolumeExpansion + elements: + - type: horizontal-layout + elements: + - type: block-layout + elements: + - type: label-element + 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: select + label: Mode + options: + - text: Offline + value: Offline + - text: Online + value: Online + validation: + type: required + schema: schema/properties/spec/properties/volumeExpansion/properties/mode + - type: block-layout + label: MSSQLServer volume expansion + showLabels: true + fixedBlock: true + elements: + - type: horizontal-layout + elements: + - type: input-compare + header: MSSQLServer + subtitle: How much extra storage does your database need? Specify the size(e.g. 2Gi for 2 gigabytes) so we can allocate it correctly + label: Storage Size + init: + type: func + value: setValueFromDbDetails|/spec/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/mssqlserver + schema: schema/properties/spec/properties/volumeExpansion/properties/mssqlserver + - type: info + hasIcon: true + label: Expanding storage allows your database to accommodate more data. Ensure the specified size is larger than the current storage capacity. +# Reconfigure + - type: block-layout + label: Reconfigure Form + if: + name: ifRequestTypeEqualsTo|Reconfigure + type: function + loader: + name: fetchConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + elements: + - type: block-layout + label: Configuration + elements: + - type: label-element + label: '' + subtitle: Select a new configuration secret, apply a custom configuration, or remove an existing setup to update your database settings + - type: tab-layout + label: New Config Secret + schema: temp/properties/reconfigurationType + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + elements: + - type: block-layout + label: Config Secret + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret + type: function + elements: + - type: label-element + label: Config Secret + subtitle: Select a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: schema/properties/spec/properties/configuration/properties/configSecret/properties/name + refresh: true + label: Config Secret + loader: + name: getConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/createSecret/properties/status + init: + type: func + value: setValueFromDbDetails|/spec/configSecret/name + watcher: + func: onCreateSecretChange + paths: + - temp/properties/createSecret/properties/status + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|create + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + - type: block-layout + label: Create a New Config Secret + showLabels: true + if: + type: function + name: isCreateSecret + hasButton: + text: Save + hasCancel: cancelCreateSecret + action: createNewConfigSecret + elements: + - type: input + label: Secret Name + schema: temp/properties/createSecret/properties/name + validation: + type: required + - type: array-object-form + label: String Data + schema: temp/properties/createSecret/properties/data + buttonClass: is-light is-outlined + validation: + type: required + elements: + - type: select + label: Key + schema: key + loader: + name: onSelectedSecretChange + watchPaths: + - temp/properties/createSecret/properties/data + validation: + type: required + - type: textarea + label: Value + schema: value + - type: multi-file-editor + editorHeight: 500px + readonly: true + if: + type: function + name: isNotCreateSecret + loader: + name: onNewConfigSecretChange + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + schema: temp/properties/newConfigSecret + - type: block-layout + label: ApplyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig + type: function + elements: + - type: label-element + 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). + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfiguration + refresh: true + label: Configuration + loader: getConfigSecretsforAppyConfig + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|apply + watchPaths: + - temp/properties/selectedConfiguration + - type: multi-file-editor + editorHeight: 500px + schema: temp/properties/applyConfig + loader: + name: setApplyConfig + watchPaths: + - temp/properties/selectedConfiguration + watcher: + func: onApplyconfigChange + paths: + - temp/properties/applyConfig + - type: block-layout + label: Remove + if: + name: ifReconfigurationTypeEqualsTo|remove + type: function + elements: + - type: label-element + label: Remove + subtitle: Selected a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfigurationRemove + refresh: true + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|remove + watchPaths: + - temp/properties/selectedConfigurationRemove + - type: multi-file-editor + editorHeight: 500px + readonly: true + init: + type: func + value: onRemoveConfigChange + watcher: + func: onRemoveConfigChange + paths: + - temp/properties/selectedConfigurationRemove + schema: temp/properties/removeConfig + +# common + - type: block-layout + label: OpsRequest Options + showLabels: true + elements: + - type: time-picker + label: Timeout + schema: 'schema/properties/spec/properties/timeout' + subtitle: Specify the maximum time allowed for the scaling operation to complete. Use formats like 30sec, 1min(1 minute) or 2h(2 hours). + - type: radio + label: Apply + schema: 'schema/properties/spec/properties/apply' + init: + type: func + value: setApplyToIfReady + options: + - text: IfReady (OpsRequest will be applied if database is ready) + value: IfReady + - text: Always (OpsRequest will always be applied) + value: Always diff --git a/charts/opskubedbcom-mssqlserveropsrequest-editor/ui/functions.js b/charts/opskubedbcom-mssqlserveropsrequest-editor/ui/functions.js index e26e2f618d..d115aaabaa 100644 --- a/charts/opskubedbcom-mssqlserveropsrequest-editor/ui/functions.js +++ b/charts/opskubedbcom-mssqlserveropsrequest-editor/ui/functions.js @@ -1,3 +1,4 @@ +const { axios, useOperator, store, useToast } = window.vueHelpers || {} const machines = { 'db.t.micro': { resources: { @@ -304,181 +305,222 @@ const machineList = [ 'db.r.24xlarge', ] -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, - } -} +let machinesFromPreset = [] +const configSecretKeys = ['mssql.conf'] -function returnFalse() { - return false -} +export const useFunc = (model) => { + const route = store.state?.route + const toast = useToast() -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + const { getValue, storeGet, discriminator, setDiscriminatorValue, commit } = useOperator( + model, + store.state, + ) -async function getNamespaces({ axios, storeGet }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + showAndInitOpsRequestType() - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + async function fetchJsons({ axios, itemCtx }) { + let ui = {} + let language = {} + let functions = {} + const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart - const resources = (resp && resp.data && resp.data.items) || [] + 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 resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' return { - text: name, - value: name, + ui: ui.data || {}, + language: language.data || {}, + functions, } - }) -} + } -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function returnFalse() { + return true + } + + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/namespace') + 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/kubedb.com/v1alpha2/namespaces/${namespace}/mssqlservers`, - { + 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) || [] + const resources = (resp && resp.data && resp.data.items) || [] - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -async function getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) { - 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') + async function getDbs() { + if (storeGet('/route/params/actions')) return [] + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - if (namespace && name) { - const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/mssqlservers/${name}` - const resp = await axios.get(url) + const namespace = getValue(model, '/metadata/namespace') + // watchDependency('model#/metadata/namespace') - setDiscriminatorValue('/dbDetails', resp.data || {}) + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/mssqlservers`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) - return resp.data || {} - } else return {} -} + const resources = (resp && resp.data && resp.data.items) || [] -async function getDbVersions({ axios, storeGet, getValue, discriminator }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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}/mssqlservers/${name}` + const resp = await axios.get(url) - const url = `/clusters/${owner}/${cluster}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/kubedb-ui-presets` + setDiscriminatorValue('/dbDetails', resp.data || {}) - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + 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 { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + presetVersions = presets.admin?.databases?.MSSQLServer?.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/mssqlserverversions`, + { + 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 allowed = found?.spec?.updateConstraints?.allowlist || [] + 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 filteredMSSQLServerVersions = 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.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.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.includes(item.metadata?.name)) && + isVersionWithinConstraints(item.spec?.version, limit) + ) + }) + setDiscriminatorValue('/filteredVersion', filteredMSSQLServerVersions) + return filteredMSSQLServerVersions.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) - presets.status = String(e.status) + return [] } } - try { - const presetVersions = presets.admin?.databases?.MSSQLServer?.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/mssqlserverversions`, - { - params: queryParams, - }, - ) + function getVersionInfo() { + const filteredVersion = getValue(discriminator, '/filteredVersion') + if (filteredVersion.length) return '' - const resources = (resp && resp.data && resp.data.items) || [] + let txt = 'No versions from this list can be selected as the target version: [ ' - 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 allowed = found?.spec?.updateConstraints?.allowlist || [] - 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 filteredMSSQLServerVersions = 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.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.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.includes(item.metadata?.name)) && - isVersionWithinConstraints(item.spec?.version, limit) - ) + presetVersions.forEach((v, idx) => { + txt = `${txt}"${v}"` + if (idx !== presetVersions.length - 1) txt = txt + ', ' + else txt = txt + ' ]' }) - return filteredMSSQLServerVersions.map((item) => { + return txt + } + + function getVersion() { + return filteredVersion.map((item) => { const name = (item.metadata && item.metadata.name) || '' const specVersion = (item.spec && item.spec.version) || '' return { @@ -486,291 +528,330 @@ async function getDbVersions({ axios, storeGet, getValue, discriminator }) { value: name, } }) - } catch (e) { - console.log(e) - return [] } -} -function versionCompare(v1, v2) { - const arr1 = v1.split('.').map(Number) - const arr2 = v2.split('.').map(Number) + 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 + 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 + if (num1 > num2) return 1 // v1 is higher + if (num1 < num2) return -1 // v2 is higher + } + return 0 // versions are equal } - 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 + 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 } - return true -} -function ifRequestTypeEqualsTo({ model, getValue, watchDependency }, type) { - const selectedType = getValue(model, '/spec/type') - watchDependency('model#/spec/type') + function ifRequestTypeEqualsTo(type) { + const selectedType = getValue(model, '/spec/type') + // watchDependency('model#/spec/type') - return selectedType === type -} + return selectedType === type + } -function onRequestTypeChange({ model, getValue, commit }) { - 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 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', + } -function disableOpsRequest({ itemCtx, discriminator, getValue, watchDependency }) { - if (itemCtx.value === 'HorizontalScaling') { - const dbType = getDbType({ - discriminator, - getValue, - watchDependency, + Object.keys(reqTypeMapping).forEach((key) => { + if (key !== selectedType) commit('wizard/model$delete', `/spec/${reqTypeMapping[key]}`) }) + } - if (dbType === 'Standalone') return true - else return false - } else return false -} + function getDbTls() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') -function getDbTls({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + const { spec } = dbDetails || {} + return spec?.tls || undefined + } - const { spec } = dbDetails || {} - return spec?.tls || undefined -} + function getDbType() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') + const { spec } = dbDetails || {} + const { topology } = spec || {} + if (topology) return 'Topology' + else return 'Combined' + } -function getDbType({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') - const { spec } = dbDetails || {} - const { topology } = spec || {} - if (topology) return 'Topology' - else return 'Combined' -} + function disableOpsRequest() { + if (itemCtx.value === 'HorizontalScaling') { + const dbType = getDbType() -function initNamespace({ route }) { - const { namespace } = route.query || {} - return namespace || null -} + if (dbType === 'Standalone') return true + else return false + } else return false + } -function initDatabaseRef({ route, watchDependency }) { - watchDependency('model#/metadata/namespace') - const { name } = route.params || {} - return name -} + function initNamespace() { + const { namespace } = route.query || {} + return namespace || null + } -function asDatabaseOperation(route) { - return !!route.params.actions -} + function initDatabaseRef() { + // watchDependency('model#/metadata/namespace') + const { name } = route.params || {} + return name + } -function generateOpsRequestNameForClusterUI(getValue, model, route) { - const dbName = getValue(model, '/spec/databaseRef/name') + function asDatabaseOperation() { + return !!route.params.actions + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + function generateOpsRequestNameForClusterUI(getValue, model, route) { + const dbName = getValue(model, '/spec/databaseRef/name') - const resources = route.params.resource || '' - const resource = resources.slice(0, -1) + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' - const opsName = dbName ? dbName : resource - return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` -} + const resources = route.params.resource || '' + const resource = resources.slice(0, -1) -function showAndInitName({ route, commit, getValue, model, watchDependency }) { - watchDependency('model#/spec/type') - watchDependency('model#/spec/databaseRef/name') - const ver = asDatabaseOperation(route) + const opsName = dbName ? dbName : resource + return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + function showAndInitName() { + // watchDependency('model#/spec/type') + // watchDependency('model#/spec/databaseRef/name') + const ver = asDatabaseOperation() - 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, - }) + 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 } - return !ver -} -function showAndInitNamespace({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/metadata/namespace', - value: `${route.query.namespace}`, - force: true, - }) + + function showAndInitNamespace() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/metadata/namespace', + value: `${route.query.namespace}`, + force: true, + }) + } + + return !ver } - return !ver -} -function showAndInitDatabaseRef({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/spec/databaseRef/name', - value: `${route.params.name}`, - force: true, - }) + function showAndInitDatabaseRef() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/spec/databaseRef/name', + value: `${route.params.name}`, + force: true, + }) + } + + return !ver } - return !ver -} -function showConfigureOpsrequestLabel({ route }) { - return !asDatabaseOperation(route) -} -function showAndInitOpsRequestType({ route, commit }) { - const ver = asDatabaseOperation(route) - const opMap = { - upgrade: 'UpdateVersion', - updateVersion: 'UpdateVersion', - horizontalscaling: 'HorizontalScaling', - verticalscaling: 'VerticalScaling', - volumeexpansion: 'VolumeExpansion', - restart: 'Restart', - reconfiguretls: 'ReconfigureTLS', - reconfigure: 'Reconfigure', - } - if (ver) { - const operation = route.params.actions - const match = /^(.*)-opsrequest-(.*)$/.exec(operation) - const opstype = match[2] - commit('wizard/model$update', { - path: '/spec/type', - value: opMap[opstype], - force: true, - }) + function showConfigureOpsrequestLabel() { + return !asDatabaseOperation() } - return !ver -} + 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, + }) + } + } -// vertical scaling -function ifDbTypeEqualsTo({ discriminator, getValue, watchDependency, commit }, value, opsReqType) { - const verd = getDbType({ - discriminator, - getValue, - watchDependency, - }) - return value === verd -} + return !ver + } -// machine profile stuffs -let machinesFromPreset = [] + // vertical scaling + function ifDbTypeEqualsTo(value, opsReqType) { + const verd = getDbType() + return value === verd + } -function getMachines({ storeGet }) { - const presets = storeGet('/kubedbuiPresets') || {} - const avlMachines = presets.admin?.machineProfiles?.available || [] - let arr = [] - if (avlMachines.length) { - arr = avlMachines.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - 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 } - } else return { text: machine, value: machine } - } - }) - } else { - arr = machineList - .map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + // machine profile stuffs + function getMachines() { + const presets = storeGet('/kubedbuiPresets') || {} + const dbDetails = getValue(discriminator, '/dbDetails') + const containers = dbDetails?.spec?.podTemplate?.spec?.containers || [] + const mssqlContainer = containers.find((c) => c.name === 'mssql') + const limits = mssqlContainer?.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 } } + } }) - .filter((val) => !!val) + } 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 } - return arr -} -function setMachine({ getValue, discriminator, storeGet }) { - const dbDetails = getValue(discriminator, '/dbDetails') - const annotations = dbDetails?.metadata?.annotations || {} - const machine = annotations['kubernetes.io/instance-type'] || 'custom' + function setMachine() { + const dbDetails = getValue(discriminator, '/dbDetails') + const containers = dbDetails?.spec?.podTemplate?.spec?.containers || [] + const mssqlContainer = containers.find((c) => c.name === 'mssql') + const limits = mssqlContainer?.resources?.requests || {} + const annotations = dbDetails?.metadata?.annotations || {} + const instance = annotations['kubernetes.io/instance-type'] - machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] - - const machinePresets = machinesFromPreset.find((item) => item.id === machine) - if (machinePresets) return machine - else return 'custom' -} + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = instance || {} + } -function onMachineChange({ getValue, discriminator, commit, model }, type, valPath) { - let selectedMachine = '' - selectedMachine = getValue(discriminator, '/machine') - const machine = machinesFromPreset.find((item) => item.id === selectedMachine) + const machine = parsedInstance || 'custom' - let obj = {} - if (selectedMachine !== 'custom') { - if (machine) obj = { limits: { ...machine?.limits }, requests: { ...machine?.limits } } - else obj = machines[selectedMachine]?.resources - } else { - const val = getValue(discriminator, `/dbDetails${valPath}`) || {} - obj = Array.isArray(val) ? val[0]?.resources : { ...val } + 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 } } - const path = `/spec/verticalScaling/${type}/resources` + 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 }, + } + } - if (obj && Object.keys(obj).length) - commit('wizard/model$update', { - path: path, - value: obj, - force: true, - }) + 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') || {} - if (selectedMachine === 'custom') commit('wizard/model$delete', '/metadata/annotations') - else { - annotations['kubernetes.io/instance-type'] = selectedMachine + // 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', @@ -778,520 +859,963 @@ function onMachineChange({ getValue, discriminator, commit, model }, type, valPa force: true, }) } -} -function isMachineCustom({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/machine') - const machine = getValue(discriminator, '/machine') - return machine === 'custom' -} + function isMachineCustom(path) { + // watchDependency(`discriminator#${path}`) + const machine = getValue(discriminator, `${path}`) + return machine === 'custom' + } -// for config secret -async function getConfigSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + // Fetch and store database Infos + // for secret configurations in reconfigure + let configSecrets = [] + let secretConfigData = [] - const secrets = (resp && resp.data && resp.data.items) || [] + 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 filteredSecrets = secrets + 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') - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return filteredSecrets -} + 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: ['mssql.conf'], + }, + }, + ) + configSecrets = resp?.data?.response?.availableSecrets || [] + secretConfigData = resp?.data?.response?.configurations || [] + } catch (e) { + console.log(e) + } + } -function createSecretUrl({ storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 + } - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/secrets/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/secrets/create` + async function getConfigSecretsforAppyConfig() { + const secrets = secretConfigData.map((item) => { + return { text: item.componentName, value: item.componentName } + }) + return secrets } -} -function isEqualToValueFromType({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/valueFromType') - const valueFrom = getValue(discriminator, '/valueFromType') - return valueFrom === value -} + function getSelectedConfigurationData(type) { + type = type ? type + '/' : '' + const path = `/${type}selectedConfiguration` + const selectedConfiguration = getValue(discriminator, path) -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + if (!selectedConfiguration) { + return [] + } - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + const configuration = secretConfigData.find( + (item) => item.componentName === selectedConfiguration, + ) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, + 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 + }) + } }) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + // Set the value to the model + commit('wizard/model$update', { + path: `/temp/${type}applyConfig`, + value: result, + force: true, + }) + + return result } - return ans -} -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` + const selectedConfiguration = + configType === 'create' ? getValue(model, path) : getValue(discriminator, path) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, + 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 + } }) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + // Convert data object back to YAML string + return yaml.dump(data) } - return ans -} -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - group, - version, - resource, -) { - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/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) - }) + 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])) + + 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 resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + function decodeError(msg, defaultMsg) { + if (typeof msg === 'string') { + return msg || defaultMsg } - }) -} -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) - - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) + return ( + (msg.response && msg.response.data && msg.response.data.message) || + (msg.response && msg.response.data) || + (msg.status && msg.status.status) || + defaultMsg + ) } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + 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 + } -// reconfiguration type -function ifReconfigurationTypeEqualsTo({ discriminator, getValue, watchDependency }, value) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - watchDependency('discriminator#/reconfigurationType') + function isNotCreateSecret(type) { + return !isCreateSecret(type) + } - return reconfigurationType === value -} + 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`) -function onApplyconfigChange({ discriminator, getValue, commit }) { - const applyconfig = getValue(discriminator, '/applyConfig') + const configFound = configSecrets.find((item) => item === name) + return configFound ? { text: name, value: name } : '' + } + } - const configObj = {} - if (applyconfig) { - applyconfig.forEach((item) => { - const { key, value } = item - configObj[key] = value + 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', }) } - commit('wizard/model$update', { - path: '/spec/configuration/applyConfig', - value: configObj, - force: true, - }) -} - -function onReconfigurationTypeChange({ commit, discriminator, getValue, setDiscriminatorValue }) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - setDiscriminatorValue('/applyConfig', []) - if (reconfigurationType === 'remove') { - commit('wizard/model$delete', `/spec/configuration`) + 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) { + 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/removeCustomConfig`, - value: true, - force: true, + path: `/spec/configuration/${type}applyConfig`, + value: tempConfigObj, }) - } 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({ discriminator, getValue, watchDependency }) { - const tls = getDbTls({ - discriminator, - getValue, - watchDependency, - }) + 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], + }) + }) + } else { + configObj.push({ name: '', content: '' }) + } + return configObj + } - return !!tls -} + function onRemoveConfigChange(type) { + type = type ? type + '/' : '' + const configPath = `/${type}selectedConfigurationRemove` + const selectedConfig = getValue(discriminator, configPath) -function initIssuerRefApiGroup({ getValue, model, watchDependency, discriminator }) { - const kind = getValue(model, '/spec/tls/issuerRef/kind') - watchDependency('model#/spec/tls/issuerRef/kind') + if (!selectedConfig) { + commit('wizard/model$delete', `/spec/configuration/${type}removeCustomConfig`) + return [{ name: '', content: '' }] + } + commit('wizard/model$update', { + path: `/spec/configuration/${type}removeCustomConfig`, + value: true, + }) - if (kind) { - const apiGroup = getValue(discriminator, '/dbDetails/spec/tls/issuerRef/apiGroup') - if (apiGroup) return apiGroup - return 'cert-manager.io' - } else return undefined -} + const configuration = secretConfigData.find((item) => item.componentName === selectedConfig) -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - 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` + if (!configuration.data) { + return [{ name: '', content: '' }] + } - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + const configObj = [] + // Decode base64 and format as array of objects with name and content + Object.keys(configuration.data).forEach((fileName) => { try { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + // Decode base64 string + const decodedString = atob(configuration.data[fileName]) + configObj.push({ + name: fileName, + content: decodedString, + }) } catch (e) { - console.log(e) - presets.status = String(e.status) + 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: '' }] } - let clusterIssuers = presets.admin?.clusterIssuers?.available || [] - if (presets.status === '404') { - const url = `/clusters/${owner}/${cluster}/proxy/cert-manager.io/v1/clusterissuers` - return getIssuer(url) + 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) } - return clusterIssuers + const resSecret = remainingSecrets.map((item) => { + return { text: item, value: item } + }) + return resSecret } - async function getIssuer(url) { + 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 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) - const resources = (resp && resp.data && resp.data.items) || [] + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + 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 } }, + }, }) - return resources + + const items = (resp && resp.data && resp.data.items) || [] + ans = items } catch (e) { console.log(e) - return [] } + + return ans } -} -function initTlsOperation() { - return 'update' -} -function onTlsOperationChange({ discriminator, getValue, commit }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + async function resourceNames(group, version, resource) { + const namespace = getValue(model, '/metadata/namespace') + // watchDependency('model#/metadata/namespace') - commit('wizard/model$delete', '/spec/tls') + let resources = await getNamespacedResourceList({ + namespace, + group, + version, + resource, + }) - if (tlsOperation === 'rotate') { - commit('wizard/model$update', { - path: '/spec/tls/rotateCertificates', - value: true, - force: true, + 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, + } }) - 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, + } + + 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, + } }) - commit('wizard/model$delete', '/spec/tls/certificates') - commit('wizard/model$delete', '/spec/tls/rotateCertificates') } -} -function showIssuerRefAndCertificates({ discriminator, getValue, watchDependency }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') - watchDependency('discriminator#/tlsOperation') - const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' + // reconfiguration type + function ifReconfigurationTypeEqualsTo(value) { + const reconfigurationType = getValue(discriminator, '/reconfigurationType') + // watchDependency('discriminator#/reconfigurationType') - return verd -} + return reconfigurationType === value + } -function isIssuerRefRequired({ discriminator, getValue, watchDependency }) { - const hasTls = hasTlsField({ - discriminator, - getValue, - watchDependency, - }) + function onReconfigurationTypeChange() { + const reconfigurationType = getValue(discriminator, '/reconfigurationType') + setDiscriminatorValue('/applyConfig', []) + if (reconfigurationType === 'remove') { + commit('wizard/model$delete', `/spec/configuration`) - return !hasTls -} + 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`) + } + } -function getRequestTypeFromRoute({ route, model, discriminator, getValue, watchDependency }) { - const isDbloading = isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) - const { query } = route || {} - const { requestType } = query || {} - return isDbloading ? '' : requestType || '' -} + // for tls + function hasTlsField() { + const tls = getDbTls() -// ************************************** Set db details ***************************************** + return !!tls + } -function isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - watchDependency('model#/spec/databaseRef/name') - const dbDetails = getValue(discriminator, '/dbDetails') - const dbName = getValue(model, '/spec/databaseRef/name') + function initIssuerRefApiGroup() { + const kind = getValue(model, '/spec/tls/issuerRef/kind') + // watchDependency('model#/spec/tls/issuerRef/kind') - return !dbDetails || !dbName -} + if (kind) { + return 'cert-manager.io' + } else return undefined + } -function setValueFromDbDetails( - { discriminator, getValue, watchDependency, commit }, - path, - commitPath, -) { - watchDependency('discriminator#/dbDetails') + 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') - const retValue = getValue(discriminator, `/dbDetails${path}`) + 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' + } - if (commitPath && retValue) { + function onTlsOperationChange() { const tlsOperation = getValue(discriminator, '/tlsOperation') - // computed called when tls fields is not visible - if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined + commit('wizard/model$delete', '/spec/tls') - // 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, - }) + if (tlsOperation === 'rotate') { + commit('wizard/model$update', { + path: '/spec/tls/rotateCertificates', + value: true, + force: true, + }) + } else if (tlsOperation === 'remove') { + commit('wizard/model$update', { + path: '/spec/tls/remove', + value: true, + force: true, + }) + } } - return retValue || undefined -} + function showIssuerRefAndCertificates() { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // watchDependency('discriminator#/tlsOperation') + const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' -function setResource({ discriminator, getValue, watchDependency }, path) { - watchDependency('discriminator#/dbDetails') - const containers = getValue(discriminator, `/dbDetails${path}`) || [] - const resource = containers.filter((ele) => ele.name === 'mssql') - return resource[0].resources -} + return verd + } -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} + function isIssuerRefRequired() { + const hasTls = hasTlsField() + return hasTls ? false : '' + } -function isNamespaceDisabled({ route }) { - const { namespace } = route.query || {} - return !!namespace -} + function getRequestTypeFromRoute() { + const isDbloading = isDbDetailsLoading() + const { query } = route || {} + const { requestType } = query || {} + return isDbloading ? '' : requestType || '' + } -function isDatabaseRefDisabled({ route }) { - const { name } = route.params || {} - return !!name -} + function isDbDetailsLoading() { + // watchDependency('discriminator#/dbDetails') + // watchDependency('model#/spec/databaseRef/name') + const dbDetails = getValue(discriminator, '/dbDetails') + const dbName = getValue(model, '/spec/databaseRef/name') -function onNamespaceChange({ commit }) { - commit('wizard/model$delete', '/spec/type') -} + return !dbDetails || !dbName + } -function onDbChange({ commit, axios, storeGet, model, getValue, setDiscriminatorValue }) { - commit('wizard/model$delete', '/spec/type') - getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) -} + function setValueFromDbDetails(path, commitPath) { + // watchDependency('discriminator#/dbDetails') + const retValue = getValue(discriminator, `/dbDetails${path}`) -function setApplyToIfReady() { - return 'IfReady' -} + if (commitPath) { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // computed called when tls fields is not visible + if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined -function isVerticalScaleTopologyRequired({ watchDependency, getValue, discriminator, commit }) { - watchDependency('discriminator#/topologyKey') - watchDependency('discriminator#/topologyValue') + // 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 + } - const key = getValue(discriminator, '/topologyKey') - const value = getValue(discriminator, '/topologyValue') - const path = `/spec/verticalScaling/mssqlserver/topology` + function setResource(path) { + // watchDependency('discriminator#/dbDetails') + const containers = getValue(discriminator, `/dbDetails${path}`) || [] + const resource = containers.filter((ele) => ele.name === 'mssql') + return resource[0]?.resources + } - if (key || value) { - commit('wizard/model$update', { - path: path, - value: { key, value }, - force: true, + 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/mssqlserver/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 getSelectedConfigSecret() { + 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() { + 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 true - } else { - commit('wizard/model$delete', path) - return false + return data || 'No Data Found' } -} -function checkVolume({ model, discriminator, getValue }, initpath, path) { - const volume = getValue(discriminator, `/dbDetails${initpath}`) - const input = getValue(model, path) + function setExporter(type) { + let path = `/dbDetails/spec/monitor/prometheus/exporter/resources/limits/${type}` + const limitVal = getValue(discriminator, path) - try { - const sizeInBytes = parseSize(volume) - const inputSizeInBytes = parseSize(input) + if (!limitVal) { + path = `/dbDetails/spec/monitor/prometheus/exporter/resources/requests/${type}` + const reqVal = getValue(discriminator, path) - if (inputSizeInBytes >= sizeInBytes) return true - else return 'Cannot expand to lower volume!' - } catch (err) { - return err.message || 'Invalid' + if (reqVal) return reqVal + } + return limitVal } -} -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 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, + }) + } -return { - isRancherManaged, - setResource, - fetchJsons, - returnFalse, - getNamespaces, - getDbs, - getDbDetails, - getDbVersions, - ifRequestTypeEqualsTo, - onRequestTypeChange, - getDbTls, - getDbType, - initNamespace, - initDatabaseRef, - - showAndInitName, - showAndInitNamespace, - showAndInitDatabaseRef, - showConfigureOpsrequestLabel, - showAndInitOpsRequestType, - - ifDbTypeEqualsTo, - getConfigSecrets, - createSecretUrl, - isEqualToValueFromType, - disableOpsRequest, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - ifReconfigurationTypeEqualsTo, - onReconfigurationTypeChange, - onApplyconfigChange, - hasTlsField, - initIssuerRefApiGroup, - getIssuerRefsName, - initTlsOperation, - onTlsOperationChange, - showIssuerRefAndCertificates, - isIssuerRefRequired, - getRequestTypeFromRoute, - isDbDetailsLoading, - setValueFromDbDetails, - getAliasOptions, - isNamespaceDisabled, - isDatabaseRefDisabled, - onNamespaceChange, - onDbChange, - setApplyToIfReady, - isVerticalScaleTopologyRequired, - getMachines, - setMachine, - onMachineChange, - isMachineCustom, - checkVolume, + return { + isRancherManaged, + setExporter, + onExporterResourceChange, + setResource, + fetchJsons, + returnFalse, + getNamespaces, + getDbs, + getDbDetails, + getDbVersions, + getVersionInfo, + isVersionEmpty, + getVersion, + ifRequestTypeEqualsTo, + onRequestTypeChange, + getDbTls, + getDbType, + initNamespace, + initDatabaseRef, + showAndInitName, + showAndInitNamespace, + showAndInitDatabaseRef, + showConfigureOpsrequestLabel, + showAndInitOpsRequestType, + ifDbTypeEqualsTo, + getConfigSecrets, + getSelectedConfigSecret, + getSelectedConfigSecretValue, + createSecretUrl, + isEqualToValueFromType, + disableOpsRequest, + getNamespacedResourceList, + getResourceList, + resourceNames, + unNamespacedResourceNames, + ifReconfigurationTypeEqualsTo, + onReconfigurationTypeChange, + onApplyconfigChange, + hasTlsField, + initIssuerRefApiGroup, + getIssuerRefsName, + initTlsOperation, + onTlsOperationChange, + showIssuerRefAndCertificates, + isIssuerRefRequired, + getRequestTypeFromRoute, + isDbDetailsLoading, + setValueFromDbDetails, + getAliasOptions, + isNamespaceDisabled, + isDatabaseRefDisabled, + onNamespaceChange, + onDbChange, + setApplyToIfReady, + isVerticalScaleTopologyRequired, + getMachines, + setMachine, + onMachineChange, + isMachineCustom, + checkVolume, + fetchConfigSecrets, + getConfigSecretsforAppyConfig, + getSelectedConfigurationData, + getSelectedConfigurationName, + getSelectedConfigurationValueForRemove, + createNewConfigSecret, + decodeError, + isCreateSecret, + isNotCreateSecret, + onCreateSecretChange, + cancelCreateSecret, + setApplyConfig, + onRemoveConfigChange, + onNewConfigSecretChange, + onSelectedSecretChange, + } } diff --git a/charts/opskubedbcom-mysqlopsrequest-editor/ui/create-ui.yaml b/charts/opskubedbcom-mysqlopsrequest-editor/ui/create-ui.yaml index 61bc461563..e8db964553 100644 --- a/charts/opskubedbcom-mysqlopsrequest-editor/ui/create-ui.yaml +++ b/charts/opskubedbcom-mysqlopsrequest-editor/ui/create-ui.yaml @@ -1,413 +1,642 @@ -steps: -- form: - discriminator: - dbDetails: - type: object +type: multi-step-form +step: + - type: single-step-form + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - schema: - $ref: discriminator#/properties/dbDetails - type: input - - if: showAndInitName - label: - text: labels.op_req_name - required: true - schema: - $ref: schema#/properties/metadata/properties/name - type: input - - computed: initNamespace - disabled: isNamespaceDisabled - fetch: getNamespaces - hasGroup: isRancherManaged - if: showAndInitNamespace - label: - text: labels.namespace - onChange: onNamespaceChange - required: true - schema: - $ref: schema#/properties/metadata/properties/namespace - type: select - - computed: initDatabaseRef - disabled: isDatabaseRefDisabled - fetch: getDbs - if: showAndInitDatabaseRef - label: - text: labels.databaseRef - onChange: onDbChange - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/databaseRef/properties/name - type: select - - if: showConfigureOpsrequestLabel - label: - text: labels.config_ops_request - type: label-element - - computed: getRequestTypeFromRoute - disabled: isDbDetailsLoading - hasDescription: true - if: showAndInitOpsRequestType - individualItemDisabilityCheck: disableOpsRequest - label: - text: labels.ops_request_type - onChange: onRequestTypeChange - options: - - description: options.UpdateVersion.description - text: options.UpdateVersion.text - value: UpdateVersion - - description: options.HorizontalScaling.description - text: options.HorizontalScaling.text - value: HorizontalScaling - - description: options.VerticalScaling.description - text: options.VerticalScaling.text - value: VerticalScaling - - description: options.VolumeExpansion.description - text: options.VolumeExpansion.text - value: VolumeExpansion - - description: options.Restart.description - text: options.Restart.text - value: Restart - - description: options.Reconfigure.description - text: options.Reconfigure.text - value: Reconfigure - - description: options.ReconfigureTLS.description - text: options.ReconfigureTLS.text - value: ReconfigureTLS - schema: - $ref: schema#/properties/spec/properties/type - type: radio - - elements: - - computed: setValueFromDbDetails|/spec/version - fetch: getDbVersions - label: - text: labels.targetVersion - schema: - $ref: schema#/properties/spec/properties/updateVersion/properties/targetVersion - type: select - if: ifRequestTypeEqualsTo|UpdateVersion - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/replicas - if: ifDbTypeEqualsTo|cluster|horizontalScaling - label: - text: labels.replicas - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/member - type: input - if: ifRequestTypeEqualsTo|HorizontalScaling - label: - text: Horizontal Scaling Form - type: single-step-form - - elements: - - discriminator: - machine: - default: "" - type: string - elements: - - computed: setMachine - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|mysql|/spec/podTemplate/spec/resources - schema: - $ref: discriminator#/machine - type: select - - if: isMachineCustom - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/mysql/properties/resources - type: resource-input-form - - label: - text: labels.node_selection_policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/mysql/properties/nodeSelectionPolicy - type: select - - discriminator: - topologyKey: - default: "" - type: string - topologyValue: - default: "" - type: string - elements: - - label: - text: labels.key - required: isVerticalScaleTopologyRequired - schema: - $ref: discriminator#/topologyKey - type: input - - label: - text: labels.value - required: isVerticalScaleTopologyRequired - schema: - $ref: discriminator#/topologyValue - type: input - label: - text: labels.topology - show_label: true - type: single-step-form - label: - text: labels.mysql - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/mysql - show_label: true - type: single-step-form - - computed: setValueFromDbDetails|/spec/monitor/prometheus/exporter/resources|/spec/verticalScaling/exporter/resources - label: - text: labels.exporter - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/exporter/properties/resources - type: resource-input-form - if: ifRequestTypeEqualsTo|VerticalScaling - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/storage/resources/requests/storage - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/mysql - type: input - validationRuleObject: - func: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/mysql - - label: - text: Mode +# common + - type: input + label: op_req_name + if: + type: function + name: showAndInitName + validation: + type: required + schema: schema/properties/metadata/properties/name + - type: select + label: Namespace + if: + type: function + name: showAndInitNamespace + init: + type: func + value: initNamespace + disable: isNamespaceDisabled + loader: getNamespaces + validation: + type: required + hasGroup: isRancherManaged + schema: schema/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/metadata/properties/namespace + - type: select + label: Database Ref + if: + type: function + name: showAndInitDatabaseRef + loader: + name: getDbs + watchPaths: + - schema/properties/metadata/properties/namespace + init: + type: func + value: initDatabaseRef + validation: + type: required + disable: isDatabaseRefDisabled + refresh: true + watcher: + func: onDbChange + paths: + - schema/properties/spec/properties/databaseRef/properties/name + schema: schema/properties/spec/properties/databaseRef/properties/name + - type: label-element + label: config_ops_request + if: + type: function + name: showConfigureOpsrequestLabel + - type: radio + label: Type of Ops Request + if: + type: function + name: showAndInitOpsRequestType options: - - text: Offline - value: Offline - - text: Online - value: Online - required: true - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/mode - type: select - if: ifRequestTypeEqualsTo|VolumeExpansion - label: - text: Volume Expansion Form - type: single-step-form - - elements: - - discriminator: - reconfigurationType: - type: string + - 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 + init: + type: func + value: getRequestTypeFromRoute + disable: isDbDetailsLoading + watcher: + func: onRequestTypeChange + paths: + - schema/properties/spec/properties/type + isHorizontal: true + schema: schema/properties/spec/properties/type +# UpdateVersion + - type: block-layout + showLabels: true + label: Version + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|UpdateVersion + elements: + - type: select-compare + label: Target Version + subtitle: Select the desired MySQL version to which you want to update your database. + init: + type: func + value: setValueFromDbDetails|/spec/version + loader: getDbVersions + schema: schema/properties/spec/properties/updateVersion/properties/targetVersion + - type: info + label: '' + loader: + name: getVersionInfo + watchPaths: + - temp/properties/filteredVersion + if: + type: function + name: isVersionEmpty +# Horizontal Scale + - type: block-layout + label: Horizontal Scaling Form + showLabels: true + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|HorizontalScaling elements: - - label: - text: labels.reconfigurationType - onChange: onReconfigurationTypeChange - options: - - text: Select New Config Secret - value: selectNewConfigSecret - - text: Apply Config - value: applyConfig - - text: Remove - value: remove - required: true - schema: - $ref: discriminator#/properties/reconfigurationType - type: radio - - elements: - - add_new_button: - label: labels.createConfig - target: _blank - url: - function: createSecretUrl - computed: setValueFromDbDetails|/spec/configSecret/name - fetch: getConfigSecrets - label: - text: labels.configSecret - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret/properties/name - type: select - if: ifReconfigurationTypeEqualsTo|selectNewConfigSecret - label: - text: Configuration config secret - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret - type: single-step-form - - addFormLabel: labels.applyConfig.label - element: - discriminator: - configArray: - emitAs: applyConfig - type: array + - type: horizontal-layout + if: + type: function + name: ifDbTypeEqualsTo|cluster|horizontalScaling elements: - - label: - text: labels.applyConfig.key - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/key - type: input - - label: - text: labels.applyConfig.value - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/value - type: editor - type: single-step-form - if: ifReconfigurationTypeEqualsTo|applyConfig - label: - text: labels.applyConfig.label - onChange: onApplyconfigChange - required: true - schema: - $ref: discriminator#/properties/applyConfig - tableContents: - - inTableColumn: true - label: - text: labels.applyConfig.key - path: key - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.applyConfig.value - path: value - type: value - typeOfValue: code - type: single-step-form-array - - if: returnFalse - label: - text: labels.removeCustomConfig - schema: - $ref: schema#/properties/spec/properties/configuration/properties/removeCustomConfig - type: switch - label: - text: labels.configuration - schema: - $ref: schema#/properties/spec/properties/configuration - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|Reconfigure - label: - text: Reconfigure Form - type: single-step-form - - discriminator: - tlsOperation: - default: update - type: string - elements: - - computed: initTlsOperation - if: hasTlsField - label: - text: labels.tlsOperation - onChange: onTlsOperationChange - options: - - text: Update - value: update - - text: Rotate - value: rotate - - text: Remove - value: remove - schema: - $ref: discriminator#/properties/tlsOperation - type: radio - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/remove - type: switch - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/rotateCertificates - type: switch - - elements: - - computed: setValueFromDbDetails|/spec/tls/requireSSL - label: - text: labels.require_ssl_question - schema: - $ref: schema#/properties/spec/properties/tls/properties/requireSSL - type: switch - - computed: initIssuerRefApiGroup - disabled: true - label: - text: labels.api_group - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup - type: input - - computed: setValueFromDbDetails|/spec/tls/issuerRef/kind - label: - text: labels.kind - options: - - text: Issuer - value: Issuer - - text: ClusterIssuer - value: ClusterIssuer - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/kind - type: select - - allowUserDefinedOption: true - computed: setValueFromDbDetails|/spec/tls/issuerRef/name - fetch: getIssuerRefsName - label: - text: labels.name - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/name - type: select - if: showIssuerRefAndCertificates - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef - type: single-step-form - - alias: reusable_certificates - chart: - name: uibytebuildersdev-component-certificates - version: v0.29.0 - computed: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates - functionCallbacks: - getAliasOptions: - $ref: functions#/getAliasOptions - if: showIssuerRefAndCertificates - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/spec/properties/tls/properties/certificates - type: reusable-element - if: ifRequestTypeEqualsTo|ReconfigureTLS - label: - text: labels.tls - schema: - $ref: schema#/properties/spec/properties/tls - type: single-step-form - - label: - text: labels.timeout - options: - - text: 5 minutes - value: 5m - - text: 10 minutes - value: 10m - - text: 30 minutes - value: 30m - - text: 1 hour - value: 1h - - text: 2 hours - value: 2h - - text: 5 hours - value: 5h - - text: 10 hours - value: 10h - schema: - $ref: schema#/properties/spec/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: labels.apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/spec/properties/apply - type: radio - type: single-step-form - id: basic - title: steps.0.label -type: multi-step-form + - type: input-compare + label: Replicas + header: Replica + subtitle: Define the total number of replicas for the database. Increasing replicas improves fault tolerance and load distribution , while reducing replicas conserves resources + init: + type: func + value: setValueFromDbDetails|/spec/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/member + - type: info + 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. +# vertical Scale + - type: block-layout + if: + type: function + name: ifRequestTypeEqualsTo|VerticalScaling + elements: + - type: block-layout + label: MySQL vertical scaling + showLabels: false + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines + init: + type: func + value: setMachine + watcher: + func: onMachineChange|mysql|/spec/podTemplate/spec/resources + paths: + - temp/properties/machine + schema: temp/properties/machine + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/mysql/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired + schema: temp/topologyKey + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired + schema: temp/topologyValue + - type: block-layout + label: Exporter + showLabels: true + hideBlock: true + elements: + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setExporter|cpu + type: input + 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 + watcher: + func: onExporterResourceChange|memory + paths: + - schema/properties/spec/properties/verticalScaling/properties/exporter/properties/resources/properties/limits/properties/memory +# Volume Expansion + - type: block-layout + label: Volume Expansion Form + if: + type: function + name: ifRequestTypeEqualsTo|VolumeExpansion + elements: + - type: horizontal-layout + elements: + - type: block-layout + elements: + - type: label-element + 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: select + label: Mode + options: + - text: Offline + value: Offline + - text: Online + value: Online + validation: + type: required + schema: schema/properties/spec/properties/volumeExpansion/properties/mode + - type: block-layout + label: MySQL volume expansion + showLabels: true + fixedBlock: true + elements: + - type: horizontal-layout + elements: + - type: input-compare + label: Storage Size + header: 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 + init: + type: func + value: setValueFromDbDetails|/spec/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/mysql + schema: schema/properties/spec/properties/volumeExpansion/properties/mysql +# Reconfigure + - type: block-layout + label: Reconfigure Form + if: + name: ifRequestTypeEqualsTo|Reconfigure + type: function + loader: + name: fetchConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + elements: + - type: block-layout + label: Configuration + elements: + - type: label-element + label: '' + subtitle: Select a new configuration secret, apply a custom configuration, or remove an existing setup to update your database settings + - type: tab-layout + label: New Config Secret + schema: temp/properties/reconfigurationType + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + elements: + - type: block-layout + label: Config Secret + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret + type: function + elements: + - type: label-element + label: Config Secret + subtitle: Select a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: schema/properties/spec/properties/configuration/properties/configSecret/properties/name + refresh: true + label: Config Secret + loader: + name: getConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/createSecret/properties/status + init: + type: func + value: setValueFromDbDetails|/spec/configSecret/name + watcher: + func: onCreateSecretChange + paths: + - temp/properties/createSecret/properties/status + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|create + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + - type: block-layout + label: Create a New Config Secret + showLabels: true + if: + type: function + name: isCreateSecret + hasButton: + text: Save + hasCancel: cancelCreateSecret + action: createNewConfigSecret + elements: + - type: input + label: Secret Name + schema: temp/properties/createSecret/properties/name + validation: + type: required + - type: array-object-form + label: String Data + schema: temp/properties/createSecret/properties/data + buttonClass: is-light is-outlined + validation: + type: required + elements: + - type: select + label: Key + schema: key + loader: + name: onSelectedSecretChange + watchPaths: + - temp/properties/createSecret/properties/data + validation: + type: required + - type: textarea + label: Value + schema: value + - type: multi-file-editor + editorHeight: 500px + readonly: true + if: + type: function + name: isNotCreateSecret + loader: + name: onNewConfigSecretChange + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + schema: temp/properties/newConfigSecret + - type: block-layout + label: ApplyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig + type: function + elements: + - type: label-element + 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). + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfiguration + refresh: true + label: Configuration + loader: getConfigSecretsforAppyConfig + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|apply + watchPaths: + - temp/properties/selectedConfiguration + - type: multi-file-editor + editorHeight: 500px + schema: temp/properties/applyConfig + loader: + name: setApplyConfig + watchPaths: + - temp/properties/selectedConfiguration + watcher: + func: onApplyconfigChange + paths: + - temp/properties/applyConfig + - type: block-layout + label: Remove + if: + name: ifReconfigurationTypeEqualsTo|remove + type: function + elements: + - type: label-element + label: Remove + subtitle: Selected a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfigurationRemove + refresh: true + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|remove + watchPaths: + - temp/properties/selectedConfigurationRemove + - type: multi-file-editor + editorHeight: 500px + readonly: true + init: + type: func + value: onRemoveConfigChange + watcher: + func: onRemoveConfigChange + paths: + - temp/properties/selectedConfigurationRemove + schema: temp/properties/removeConfig +# Reconfigure TLS + - type: block-layout + label: TLS + if: + name: ifRequestTypeEqualsTo|ReconfigureTLS + type: function + elements: + - type: radio + label: TLS Operation + if: + name: hasTlsField + type: function + options: + - text: Update + value: update + - text: Rotate + value: rotate + - text: Remove + value: remove + init: + type: func + value: initTlsOperation + schema: temp/properties/tlsOperation + watcher: + func: onTlsOperationChange + paths: + - temp/properties/tlsOperation + - type: switch + label: Remove TLS + fullwidth: true + if: + name: isTlsEnabled + type: function + schema: schema/properties/spec/properties/tls/properties/remove + - type: switch + label: Rotate Certificates + fullwidth: true + schema: schema/properties/spec/properties/tls/properties/rotateCertificates + if: + name: isTlsEnabled + type: function + - type: block-layout + label: Require SSL + if: + name: showIssuerRefAndCertificates + type: function + elements: + - type: switch + label: Require SSL + fullwidth: true + init: + type: func + value: setValueFromDbDetails|/spec/tls/requireSSL + schema: schema/properties/spec/properties/tls/properties/requireSSL + - type: block-layout + label: Issuer Reference + showLabels: true + if: + name: showIssuerRefAndCertificates + type: function + elements: + - type: input + label: API Group + init: + type: func + value: initIssuerRefApiGroup + watcher: + func: initIssuerRefApiGroup + paths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + disable: true + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup + - type: select + label: Kind + options: + - text: Issuer + value: Issuer + - text: ClusterIssuer + value: ClusterIssuer + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/kind + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - type: select + label: Name + loader: + name: getIssuerRefsName + watchPaths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - schema/properties/metadata/properties/namespace + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/name + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/name + - type: block-layout + label: Certificates + showLabels: false + if: + name: showIssuerRefAndCertificates + type: function + loader: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates + elements: + - type: array-object-form + label: Certificates + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/tls/properties/certificates + elements: + - type: select + label: Alias + loader: fetchAliasOptions + disable: disableAlias + schema: alias + validation: + type: required + - type: input + label: Secret Name + schema: secretName + - type: input + label: Duration + schema: duration + - type: input + label: Renew Before + schema: renewBefore + - type: array-item-form + label: Organizations + buttonClass: is-light is-outlined + schema: subject/properties/organizations + element: + type: input + label: Organization + - type: array-item-form + label: Countries + buttonClass: is-light is-outlined + schema: subject/properties/countries + element: + type: input + label: Country + - type: array-item-form + label: Organizational Units + buttonClass: is-light is-outlined + schema: subject/properties/organizationalUnits + element: + type: input + label: Organizational Unit + - type: array-item-form + label: Provinces + buttonClass: is-light is-outlined + schema: subject/properties/provinces + element: + type: input + label: Province + - type: array-item-form + label: DNS Names + buttonClass: is-light is-outlined + schema: dnsNames + element: + type: input + label: DNS Name + - type: array-item-form + label: IP Addresses + buttonClass: is-light is-outlined + schema: ipAddresses + element: + type: input + label: IP Address +# common + - type: block-layout + label: OpsRequest Options + showLabels: true + elements: + - type: time-picker + label: Timeout + schema: 'schema/properties/spec/properties/timeout' + subtitle: Specify the maximum time allowed for the operation to complete before it times out + - type: radio + label: Apply + schema: 'schema/properties/spec/properties/apply' + init: + type: func + value: setApplyToIfReady + options: + - text: IfReady (OpsRequest will be applied if database is ready) + value: IfReady + - text: Always (OpsRequest will always be applied) + value: Always diff --git a/charts/opskubedbcom-mysqlopsrequest-editor/ui/functions.js b/charts/opskubedbcom-mysqlopsrequest-editor/ui/functions.js index 064d165e51..2944819438 100644 --- a/charts/opskubedbcom-mysqlopsrequest-editor/ui/functions.js +++ b/charts/opskubedbcom-mysqlopsrequest-editor/ui/functions.js @@ -1,3 +1,4 @@ +const { axios, useOperator, store, useToast } = window.vueHelpers || {} const machines = { 'db.t.micro': { resources: { @@ -304,186 +305,246 @@ const machineList = [ 'db.r.24xlarge', ] -async function fetchJsons({ axios, itemCtx }) { - let ui = {} - let language = {} - let functions = {} - const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart +let machinesFromPreset = [] +const configSecretKeys = ['kubedb-user.cnf'] - 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}`, +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 ) - // 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 isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found } -} -function returnFalse() { - return false -} + async function getNamespaces() { + if (storeGet('/route/params/actions')) return [] + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, + }) -async function getNamespaces({ axios, storeGet }) { - if (storeGet('/route/params/group') === 'kubedb.com') return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + const resources = (resp && resp.data && resp.data.items) || [] - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } - const resources = (resp && resp.data && resp.data.items) || [] + async function getDbs() { + if (storeGet('/route/params/actions')) return [] + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + const namespace = getValue(model, '/metadata/namespace') + // watchDependency('model#/metadata/namespace') -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - if (storeGet('/route/params/group') === 'kubedb.com') return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/mysqls`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/namespace') + const resources = (resp && resp.data && resp.data.items) || [] - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/mysqls`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } - const resources = (resp && resp.data && resp.data.items) || [] + async function getDbDetails() { + machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + 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') -async function getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) { - 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) - 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 || {}) - setDiscriminatorValue('/dbDetails', resp.data || {}) + return resp.data || {} + } else return {} + } - return resp.data || {} - } else return {} -} + let presetVersions = [] + setDiscriminatorValue('/filteredVersion', []) + async function getDbVersions() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -async function getDbVersions({ axios, storeGet, getValue, discriminator }) { - 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` - 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 presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { try { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + 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.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.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.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) - presets.status = String(e.status) + return [] } } - try { - const presetVersions = presets.admin?.databases?.MySQL?.versions?.available || [] - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null, updateConstraints: null }, - }, - }, - } + function getVersionInfo() { + const filteredVersion = getValue(discriminator, '/filteredVersion') + if (filteredVersion.length) return '' - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/catalog.kubedb.com/v1alpha1/mysqlversions`, - { - params: queryParams, - }, - ) - - const resources = (resp && resp.data && resp.data.items) || [] + let txt = 'No versions from this list can be selected as the target version: [ ' - 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.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.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.includes(item.metadata?.name)) && - isVersionWithinConstraints(item.spec?.version, limit) - ) + presetVersions.forEach((v, idx) => { + txt = `${txt}"${v}"` + if (idx !== presetVersions.length - 1) txt = txt + ', ' + else txt = txt + ' ]' }) - return filteredMySQLVersions.map((item) => { + return txt + } + + function getVersion() { + return filteredVersion.map((item) => { const name = (item.metadata && item.metadata.name) || '' const specVersion = (item.spec && item.spec.version) || '' return { @@ -491,301 +552,334 @@ async function getDbVersions({ axios, storeGet, getValue, discriminator }) { value: name, } }) - } catch (e) { - console.log(e) - return [] } -} -function versionCompare(v1, v2) { - const arr1 = v1.split('.').map(Number) - const arr2 = v2.split('.').map(Number) + 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 + 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 + if (num1 > num2) return 1 // v1 is higher + if (num1 < num2) return -1 // v2 is higher + } + return 0 // versions are equal } - 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 + 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 } - return true -} -function ifRequestTypeEqualsTo({ model, getValue, watchDependency }, type) { - const selectedType = getValue(model, '/spec/type') - watchDependency('model#/spec/type') + function ifRequestTypeEqualsTo(type) { + const selectedType = getValue(model, '/spec/type') + // watchDependency('model#/spec/type') - return selectedType === type -} + return selectedType === type + } -function onRequestTypeChange({ model, getValue, commit }) { - 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 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', + } -function disableOpsRequest({ itemCtx, discriminator, getValue, watchDependency }) { - if (itemCtx.value === 'HorizontalScaling') { - const dbType = getDbType({ - discriminator, - getValue, - watchDependency, + Object.keys(reqTypeMapping).forEach((key) => { + if (key !== selectedType) commit('wizard/model$delete', `/spec/${reqTypeMapping[key]}`) }) + } - if (dbType === 'standalone') return true - else return false - } else return false -} + function disableOpsRequest() { + if (itemCtx.value === 'HorizontalScaling') { + const dbType = getDbType() -function getDbTls({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + if (dbType === 'standalone') return true + else return false + } else return false + } - const { spec } = dbDetails || {} - return spec?.tls || undefined -} + function getDbTls() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') -function getDbType({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + const { spec } = dbDetails || {} + return spec?.tls || undefined + } - const { spec } = dbDetails || {} - const { topology } = spec || {} - const { mode } = topology || {} + function getDbType() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') - if (mode) { - verd = 'cluster' - } else { - verd = 'standalone' - } + const { spec } = dbDetails || {} + const { topology } = spec || {} + const { mode } = topology || {} - return verd -} + const verd = mode ? 'cluster' : 'standalone' -function initNamespace({ route }) { - const { namespace } = route.query || {} - return namespace || null -} + return verd + } -function initDatabaseRef({ route, watchDependency }) { - watchDependency('model#/metadata/namespace') - const { name } = route.params || {} - return name -} + function initNamespace() { + const { namespace } = route.query || {} + return namespace || null + } -function asDatabaseOperation(route) { - return route.params.actions -} + function initDatabaseRef() { + // watchDependency('model#/metadata/namespace') + const { name } = route.params || {} + return name + } -function generateOpsRequestNameForClusterUI(getValue, model, route) { - const dbName = getValue(model, '/spec/databaseRef/name') + function asDatabaseOperation() { + return !!route.params.actions + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + function generateOpsRequestNameForClusterUI(getValue, model, route) { + const dbName = getValue(model, '/spec/databaseRef/name') - const resources = route.params.resource || '' - const resource = resources.slice(0, -1) + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' - const opsName = dbName ? dbName : resource - return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` -} + const resources = route.params.resource || '' + const resource = resources.slice(0, -1) -function showAndInitName({ route, commit, getValue, model, watchDependency }) { - watchDependency('model#/spec/type') - watchDependency('model#/spec/databaseRef/name') - const ver = asDatabaseOperation(route) + const opsName = dbName ? dbName : resource + return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + function showAndInitName() { + // watchDependency('model#/spec/type') + // watchDependency('model#/spec/databaseRef/name') + const ver = asDatabaseOperation() - 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, - }) + 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 } - return !ver -} -function showAndInitNamespace({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/metadata/namespace', - value: `${route.query.namespace}`, - force: true, - }) + + function showAndInitNamespace() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/metadata/namespace', + value: `${route.query.namespace}`, + force: true, + }) + } + + return !ver } - return !ver -} -function showAndInitDatabaseRef({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/spec/databaseRef/name', - value: `${route.params.name}`, - force: true, - }) + function showAndInitDatabaseRef() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/spec/databaseRef/name', + value: `${route.params.name}`, + force: true, + }) + } + + return !ver } - return !ver -} -function showConfigureOpsrequestLabel({ route }) { - return !asDatabaseOperation(route) -} -function showAndInitOpsRequestType({ route, commit }) { - const ver = asDatabaseOperation(route) - const opMap = { - upgrade: 'UpdateVersion', - updateVersion: 'UpdateVersion', - horizontalscaling: 'HorizontalScaling', - verticalscaling: 'VerticalScaling', - volumeexpansion: 'VolumeExpansion', - restart: 'Restart', - reconfiguretls: 'ReconfigureTLS', - reconfigure: 'Reconfigure', - } - if (ver) { - const operation = route.params.actions - - const match = /^(.*)-opsrequest-(.*)$/.exec(operation) - const opstype = match[2] - commit('wizard/model$update', { - path: '/spec/type', - value: opMap[opstype], - force: true, - }) + function showConfigureOpsrequestLabel() { + return !asDatabaseOperation() } - return !ver -} + 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, + }) + } + } -// vertical scaling -function ifDbTypeEqualsTo({ discriminator, getValue, watchDependency, commit }, value, opsReqType) { - const verd = getDbType({ - discriminator, - getValue, - watchDependency, - }) + return !ver + } - return value === verd -} + // vertical scaling + function ifDbTypeEqualsTo(value, opsReqType) { + const verd = getDbType() -// machine profile stuffs -let machinesFromPreset = [] + return value === verd + } -function getMachines({ storeGet }) { - const presets = storeGet('/kubedbuiPresets') || {} - const avlMachines = presets.admin?.machineProfiles?.available || [] - let arr = [] - if (avlMachines.length) { - arr = avlMachines.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - 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 } - } else return { text: machine, value: machine } - } - }) - } else { - arr = machineList - .map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + // 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 } } + } }) - .filter((val) => !!val) + } 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 } - return arr -} -function setMachine({ getValue, discriminator, storeGet }) { - const dbDetails = getValue(discriminator, '/dbDetails') - const annotations = dbDetails?.metadata?.annotations || {} - const machine = annotations['kubernetes.io/instance-type'] || 'custom' + 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'] - machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] - - const machinePresets = machinesFromPreset.find((item) => item.id === machine) - if (machinePresets) return machine - else return 'custom' -} + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = instance || {} + } -function onMachineChange({ getValue, discriminator, commit, model }, type, valPath) { - let selectedMachine = '' - selectedMachine = getValue(discriminator, '/machine') - const machine = machinesFromPreset.find((item) => item.id === selectedMachine) + const machine = parsedInstance || 'custom' - let obj = {} - if (selectedMachine !== 'custom') { - if (machine) obj = { limits: { ...machine?.limits }, requests: { ...machine?.limits } } - else obj = machines[selectedMachine]?.resources - } else { - const val = getValue(discriminator, `/dbDetails${valPath}`) || {} - obj = Array.isArray(val) ? val[0]?.resources : { ...val } + 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 } } - const path = `/spec/verticalScaling/${type}/resources` + 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 }, + } + } - if (obj && Object.keys(obj).length) - commit('wizard/model$update', { - path: path, - value: obj, - force: true, - }) + const path = `/spec/verticalScaling/${type}/resources` - // update metadata.annotations - const annotations = getValue(model, '/metadata/annotations') || {} - if (selectedMachine === 'custom') commit('wizard/model$delete', '/metadata/annotations') - else { - annotations['kubernetes.io/instance-type'] = selectedMachine + 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', @@ -793,529 +887,1006 @@ function onMachineChange({ getValue, discriminator, commit, model }, type, valPa force: true, }) } -} -function isMachineCustom({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/machine') - const machine = getValue(discriminator, '/machine') - return machine === 'custom' -} + function isMachineCustom() { + // watchDependency('discriminator#/machine') + const machine = getValue(discriminator, '/machine') + return machine === 'custom' + } -// for config secret -async function getConfigSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + // Fetch and store database Infos + // for secret configurations in reconfigure + let configSecrets = [] + let secretConfigData = [] - const secrets = (resp && resp.data && resp.data.items) || [] + 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 filteredSecrets = secrets + 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') - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return filteredSecrets -} + 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) + } + } -function createSecretUrl({ storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 + } - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/secrets/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/secrets/create` + async function getConfigSecretsforAppyConfig() { + const secrets = secretConfigData.map((item) => { + return { text: item.componentName, value: item.componentName } + }) + return secrets } -} -function isEqualToValueFromType({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/valueFromType') - const valueFrom = getValue(discriminator, '/valueFromType') - return valueFrom === value -} + function getSelectedConfigurationData(type) { + type = type ? type + '/' : '' + const path = `/${type}selectedConfiguration` + const selectedConfiguration = getValue(discriminator, path) -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + if (!selectedConfiguration) { + return [] + } - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + const configuration = secretConfigData.find( + (item) => item.componentName === selectedConfiguration, + ) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, + 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 + }) + } }) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) - } + // Set the value to the model + commit('wizard/model$update', { + path: `/temp/${type}applyConfig`, + value: result, + force: true, + }) - return ans -} -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + return result + } - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` + 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` - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }) + const selectedConfiguration = + configType === 'create' ? getValue(model, path) : getValue(discriminator, path) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + if (selectedConfiguration) + return { subtitle: ` You have selected ${selectedConfiguration} secret` } + else return { subtitle: 'No secret selected' } } - return ans -} -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - group, - version, - resource, -) { - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/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) + 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) } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + 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])) + + 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() } - }) -} -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - 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, + 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 + ) + } -// reconfiguration type -function ifReconfigurationTypeEqualsTo({ discriminator, getValue, watchDependency }, value) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - watchDependency('discriminator#/reconfigurationType') + function isCreateSecret(type) { + type = type ? type + '/' : '' + const selectedSecret = getValue(model, `spec/configuration/${type}configSecret/name`) + const res = selectedSecret === 'Create' - return reconfigurationType === value -} + if (res === true) { + commit('wizard/temp$update', { + path: `${type}createSecret/status`, + value: 'pending', + }) + } + return res + } -function onApplyconfigChange({ discriminator, getValue, commit }) { - const applyconfig = getValue(discriminator, '/applyConfig') + function isNotCreateSecret(type) { + return !isCreateSecret(type) + } - const configObj = {} + 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`) - if (applyconfig) { - applyconfig.forEach((item) => { - const { key, value } = item - configObj[key] = value - }) + const configFound = configSecrets.find((item) => item === name) + return configFound ? { text: name, value: name } : '' + } } - commit('wizard/model$update', { - path: '/spec/configuration/applyConfig', - value: configObj, - force: true, - }) -} + 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', + }) + } -function onReconfigurationTypeChange({ commit, discriminator, getValue, setDiscriminatorValue }) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - setDiscriminatorValue('/applyConfig', []) - if (reconfigurationType === 'remove') { - commit('wizard/model$delete', `/spec/configuration`) + 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) { + 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/removeCustomConfig`, - value: true, - force: true, + path: `/spec/configuration/${type}applyConfig`, + value: tempConfigObj, }) - } 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({ discriminator, getValue, watchDependency }) { - const tls = getDbTls({ - discriminator, - getValue, - watchDependency, - }) + 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], + }) + }) + } else { + configObj.push({ name: '', content: '' }) + } + return configObj + } - return !!tls -} + function onRemoveConfigChange(type) { + type = type ? type + '/' : '' + const configPath = `/${type}selectedConfigurationRemove` + const selectedConfig = getValue(discriminator, configPath) -function initIssuerRefApiGroup({ getValue, model, watchDependency, discriminator }) { - const kind = getValue(model, '/spec/tls/issuerRef/kind') - watchDependency('model#/spec/tls/issuerRef/kind') + if (!selectedConfig) { + commit('wizard/model$delete', `/spec/configuration/${type}removeCustomConfig`) + return [{ name: '', content: '' }] + } + commit('wizard/model$update', { + path: `/spec/configuration/${type}removeCustomConfig`, + value: true, + }) - if (kind) { - const apiGroup = getValue(discriminator, '/dbDetails/spec/tls/issuerRef/apiGroup') - if (apiGroup) return apiGroup - return 'cert-manager.io' - } else return undefined -} + const configuration = secretConfigData.find((item) => item.componentName === selectedConfig) -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - 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` + if (!configuration.data) { + return [{ name: '', content: '' }] + } - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + const configObj = [] + // Decode base64 and format as array of objects with name and content + Object.keys(configuration.data).forEach((fileName) => { try { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + // Decode base64 string + const decodedString = atob(configuration.data[fileName]) + configObj.push({ + name: fileName, + content: decodedString, + }) } catch (e) { - console.log(e) - presets.status = String(e.status) + 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: '' }] } - let clusterIssuers = presets.admin?.clusterIssuers?.available || [] - if (presets.status === '404') { - const url = `/clusters/${owner}/${cluster}/proxy/cert-manager.io/v1/clusterissuers` - return getIssuer(url) + 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: '' }] } - return clusterIssuers } - async function getIssuer(url) { - try { - const resp = await axios.get(url) - const resources = (resp && resp.data && resp.data.items) || [] + function onSelectedSecretChange(index) { + const secretData = getValue(discriminator, 'createSecret/data') || [] + const selfSecrets = secretData.map((item) => item.key) - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + 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 } }, + }, }) - return resources + + const items = (resp && resp.data && resp.data.items) || [] + ans = items } catch (e) { console.log(e) - return [] } + + return ans } -} + async function getResourceList({ group, version, resource }) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function initTlsOperation() { - return 'update' -} -function onTlsOperationChange({ discriminator, getValue, commit }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` - commit('wizard/model$delete', '/spec/tls') + let ans = [] + try { + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) - if (tlsOperation === 'rotate') { - commit('wizard/model$update', { - path: '/spec/tls/rotateCertificates', - value: true, - force: true, + 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, }) - 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, + + 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, + } }) - commit('wizard/model$delete', '/spec/tls/certificates') - commit('wizard/model$delete', '/spec/tls/rotateCertificates') } -} + 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) + }) + } -function showIssuerRefAndCertificates({ discriminator, getValue, watchDependency }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') - watchDependency('discriminator#/tlsOperation') - const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } - return verd -} + // reconfiguration type + function ifReconfigurationTypeEqualsTo(value) { + const reconfigurationType = getValue(discriminator, '/reconfigurationType') + // watchDependency('discriminator#/reconfigurationType') -function isIssuerRefRequired({ discriminator, getValue, watchDependency }) { - const hasTls = hasTlsField({ - discriminator, - getValue, - watchDependency, - }) + return reconfigurationType === value + } - return !hasTls -} + function onReconfigurationTypeChange() { + const reconfigurationType = getValue(discriminator, '/reconfigurationType') + setDiscriminatorValue('/applyConfig', []) + if (reconfigurationType === 'remove') { + commit('wizard/model$delete', `/spec/configuration`) -function getRequestTypeFromRoute({ route, model, discriminator, getValue, watchDependency }) { - const isDbloading = isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) - const { query } = route || {} - const { requestType } = query || {} - return isDbloading ? '' : requestType || '' -} + 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() -// ************************************** Set db details ***************************************** + return !!tls + } -function isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - watchDependency('model#/spec/databaseRef/name') - const dbDetails = getValue(discriminator, '/dbDetails') - const dbName = getValue(model, '/spec/databaseRef/name') + function initIssuerRefApiGroup() { + const kind = getValue(model, '/spec/tls/issuerRef/kind') + // watchDependency('model#/spec/tls/issuerRef/kind') - return !dbDetails || !dbName -} + if (kind) { + const apiGroup = getValue(discriminator, '/dbDetails/spec/tls/issuerRef/apiGroup') + if (apiGroup) return apiGroup + return 'cert-manager.io' + } else return undefined + } -function setValueFromDbDetails( - { discriminator, getValue, watchDependency, commit }, - path, - commitPath, -) { - watchDependency('discriminator#/dbDetails') + 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') - const retValue = getValue(discriminator, `/dbDetails${path}`) + 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 [] + } - if (commitPath && retValue) { + 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') - // computed called when tls fields is not visible - if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined + commit('wizard/model$delete', '/spec/tls') - // 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, - }) + 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') + } } - return retValue || undefined -} + function showIssuerRefAndCertificates() { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // watchDependency('discriminator#/tlsOperation') + const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' -function setConfigFiles({ model, getValue, watchDependency }) { - watchDependency('model#/resources/secret_config/stringData') - const configFiles = getValue(model, '/resources/secret_config/stringData') + return verd + } - const files = [] + function isIssuerRefRequired() { + const hasTls = hasTlsField() + return hasTls ? false : '' + } - for (const item in configFiles) { - const obj = {} - obj.key = item - obj.value = configFiles[item] - files.push(obj) + function getRequestTypeFromRoute() { + const isDbloading = isDbDetailsLoading() + const { query } = route || {} + const { requestType } = query || {} + return isDbloading ? '' : requestType || '' } - return files -} + // ************************************** Set db details ***************************************** -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} + function isDbDetailsLoading() { + // watchDependency('discriminator#/dbDetails') + // watchDependency('model#/spec/databaseRef/name') + const dbDetails = getValue(discriminator, '/dbDetails') + const dbName = getValue(model, '/spec/databaseRef/name') -function isNamespaceDisabled({ route }) { - const { namespace } = route.query || {} - return !!namespace -} + return !dbDetails || !dbName + } -function isDatabaseRefDisabled({ route }) { - const { name } = route.params || {} - return !!name -} + function setValueFromDbDetails(path, commitPath) { + // watchDependency('discriminator#/dbDetails') -function onNamespaceChange({ commit }) { - commit('wizard/model$delete', '/spec/type') -} + const retValue = getValue(discriminator, `/dbDetails${path}`) -function onDbChange({ commit, axios, storeGet, model, getValue, setDiscriminatorValue }) { - commit('wizard/model$delete', '/spec/type') - getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) -} + if (commitPath && retValue) { + const tlsOperation = getValue(discriminator, '/tlsOperation') -function setApplyToIfReady() { - return 'IfReady' -} + // computed called when tls fields is not visible + if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined -function isVerticalScaleTopologyRequired({ watchDependency, getValue, discriminator, commit }) { - watchDependency('discriminator#/topologyKey') - watchDependency('discriminator#/topologyValue') + // 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, + }) + } - const key = getValue(discriminator, '/topologyKey') - const value = getValue(discriminator, '/topologyValue') - const path = `/spec/verticalScaling/mysql/topology` + return retValue || undefined + } - if (key || value) { - commit('wizard/model$update', { - path: path, - value: { key, value }, - force: true, + 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 true - } else { - commit('wizard/model$delete', path) - return false + return data || 'No Data Found' } -} -function checkVolume({ model, discriminator, getValue }, initpath, path) { - const volume = getValue(discriminator, `/dbDetails${initpath}`) - const input = getValue(model, path) + function setExporter(type) { + let path = `/dbDetails/spec/monitor/prometheus/exporter/resources/limits/${type}` + const limitVal = getValue(discriminator, path) - try { - const sizeInBytes = parseSize(volume) - const inputSizeInBytes = parseSize(input) + if (!limitVal) { + path = `/dbDetails/spec/monitor/prometheus/exporter/resources/requests/${type}` + const reqVal = getValue(discriminator, path) - if (inputSizeInBytes >= sizeInBytes) return true - else return 'Cannot expand to lower volume!' - } catch (err) { - return err.message || 'Invalid' + if (reqVal) return reqVal + } + return limitVal } -} -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 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, + }) + } -return { - isRancherManaged, - fetchJsons, - returnFalse, - getNamespaces, - getDbs, - getDbDetails, - getDbVersions, - ifRequestTypeEqualsTo, - onRequestTypeChange, - getDbTls, - getDbType, - initNamespace, - initDatabaseRef, - - showAndInitName, - showAndInitNamespace, - showAndInitDatabaseRef, - showConfigureOpsrequestLabel, - showAndInitOpsRequestType, - - ifDbTypeEqualsTo, - getConfigSecrets, - createSecretUrl, - isEqualToValueFromType, - disableOpsRequest, - 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, + return { + 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/charts/opskubedbcom-perconaxtradbopsrequest-editor/ui/create-ui.yaml b/charts/opskubedbcom-perconaxtradbopsrequest-editor/ui/create-ui.yaml index e3ed2f6a64..9017defae8 100644 --- a/charts/opskubedbcom-perconaxtradbopsrequest-editor/ui/create-ui.yaml +++ b/charts/opskubedbcom-perconaxtradbopsrequest-editor/ui/create-ui.yaml @@ -1,411 +1,630 @@ -steps: -- form: - discriminator: - dbDetails: - type: object +type: multi-step-form +step: + - type: single-step-form + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - schema: - $ref: discriminator#/properties/dbDetails - type: input - - if: showAndInitName - label: - text: labels.op_req_name - required: true - schema: - $ref: schema#/properties/metadata/properties/name - type: input - - computed: initNamespace - disabled: isNamespaceDisabled - fetch: getNamespaces - hasGroup: isRancherManaged - if: showAndInitNamespace - label: - text: labels.namespace - onChange: onNamespaceChange - required: true - schema: - $ref: schema#/properties/metadata/properties/namespace - type: select - - computed: initDatabaseRef - disabled: isDatabaseRefDisabled - fetch: getDbs - if: showAndInitDatabaseRef - label: - text: labels.databaseRef - onChange: onDbChange - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/databaseRef/properties/name - type: select - - if: showConfigureOpsrequestLabel - label: - text: labels.config_ops_request - type: label-element - - computed: getRequestTypeFromRoute - disabled: isDbDetailsLoading - hasDescription: true - if: showAndInitOpsRequestType - individualItemDisabilityCheck: disableOpsRequest - label: - text: labels.ops_request_type - onChange: onRequestTypeChange - options: - - description: options.HorizontalScaling.description - text: options.HorizontalScaling.text - value: HorizontalScaling - - description: options.VerticalScaling.description - text: options.VerticalScaling.text - value: VerticalScaling - - description: options.VolumeExpansion.description - text: options.VolumeExpansion.text - value: VolumeExpansion - - description: options.Restart.description - text: options.Restart.text - value: Restart - - description: options.Reconfigure.description - text: options.Reconfigure.text - value: Reconfigure - - description: options.ReconfigureTLS.description - text: options.ReconfigureTLS.text - value: ReconfigureTLS - schema: - $ref: schema#/properties/spec/properties/type - type: radio - - elements: - - computed: setValueFromDbDetails|/spec/version - fetch: getDbVersions - label: - text: labels.targetVersion - schema: - $ref: schema#/properties/spec/properties/updateVersion/properties/targetVersion - type: select - if: ifRequestTypeEqualsTo|UpdateVersion - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/replicas - label: - text: Member - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/member - type: input - - computed: setValueFromDbDetails|/spec/replicas - label: - text: labels.memberWeight - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/memberWeight - type: input - if: ifRequestTypeEqualsTo|HorizontalScaling - label: - text: Horizontal Scaling Form - type: single-step-form - - elements: - - discriminator: - machine: - default: "" - type: string - elements: - - computed: setMachine - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|perconaxtradb|/spec/podTemplate/spec/resources - schema: - $ref: discriminator#/machine - type: select - - if: isMachineCustom - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/perconaxtradb/properties/resources - type: resource-input-form - - label: - text: labels.node_selection_policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/perconaxtradb/properties/nodeSelectionPolicy - type: select - - discriminator: - topologyKey: - default: "" - type: string - topologyValue: - default: "" - type: string - elements: - - label: - text: labels.key - required: isVerticalScaleTopologyRequired - schema: - $ref: discriminator#/topologyKey - type: input - - label: - text: labels.value - required: isVerticalScaleTopologyRequired - schema: - $ref: discriminator#/topologyValue - type: input - label: - text: labels.topology - show_label: true - type: single-step-form - label: - text: Perconaxtradb - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/perconaxtradb - show_label: true - type: single-step-form - - computed: setValueFromDbDetails|/spec/coordinator/resources - label: - text: Coordinator - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/coordinator/properties/resources - type: resource-input-form - if: ifRequestTypeEqualsTo|VerticalScaling - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/storage/resources/requests/storage - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/perconaxtradb - type: input - validationRuleObject: - func: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/perconaxtradb - - label: - text: Mode +# common + - type: input + label: op_req_name + if: + type: function + name: showAndInitName + validation: + type: required + schema: schema/properties/metadata/properties/name + - type: select + label: Namespace + if: + type: function + name: showAndInitNamespace + init: + type: func + value: initNamespace + disable: isNamespaceDisabled + loader: getNamespaces + validation: + type: required + hasGroup: isRancherManaged + schema: schema/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/metadata/properties/namespace + - type: select + label: Database Ref + if: + type: function + name: showAndInitDatabaseRef + loader: + name: getDbs + watchPaths: + - schema/properties/metadata/properties/namespace + init: + type: func + value: initDatabaseRef + validation: + type: required + disable: isDatabaseRefDisabled + refresh: true + watcher: + paths: + - schema/properties/spec/properties/databaseRef/properties/name + func: onDbChange + schema: schema/properties/spec/properties/databaseRef/properties/name + - type: label-element + label: config_ops_request + if: + type: function + name: showConfigureOpsrequestLabel + - type: radio + label: Type of Ops Request + if: + type: function + name: showAndInitOpsRequestType options: - - text: Offline - value: Offline - - text: Online - value: Online - required: true - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/mode - type: select - if: ifRequestTypeEqualsTo|VolumeExpansion - label: - text: Volume Expansion Form - type: single-step-form - - elements: - - discriminator: - reconfigurationType: - type: string + - 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 + init: + type: func + value: getRequestTypeFromRoute + disable: isDbDetailsLoading + watcher: + func: onRequestTypeChange + paths: + - schema/properties/spec/properties/type + isHorizontal: true + schema: schema/properties/spec/properties/type +# Horizontal Scale + - type: block-layout + label: Horizontal Scaling Form + showLabels: true + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|HorizontalScaling elements: - - label: - text: labels.reconfigurationType - onChange: onReconfigurationTypeChange - options: - - text: Select New Config Secret - value: selectNewConfigSecret - - text: Apply Config - value: applyConfig - - text: Remove - value: remove - required: true - schema: - $ref: discriminator#/properties/reconfigurationType - type: radio - - elements: - - add_new_button: - label: labels.createConfig - target: _blank - url: - function: createSecretUrl - computed: setValueFromDbDetails|/spec/configSecret/name - fetch: getConfigSecrets - label: - text: labels.configSecret - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret/properties/name - type: select - if: ifReconfigurationTypeEqualsTo|selectNewConfigSecret - label: - text: Configuration config secret - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret - type: single-step-form - - addFormLabel: labels.applyConfig.label - element: - discriminator: - configArray: - emitAs: applyConfig - type: array + - type: input-compare + label: Member + header: Member + subtitle: Define the total number of members for the database cluster. Increasing members improves fault tolerance and load distribution, while reducing members conserves resources + init: + type: func + value: setValueFromDbDetails|/spec/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/member + - type: input-compare + label: Member Weight + header: Member Weight + subtitle: Specify the weight for each member in the cluster to control load distribution and priority + init: + type: func + value: setValueFromDbDetails|/spec/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/memberWeight +# vertical Scale + - type: block-layout + if: + type: function + name: ifRequestTypeEqualsTo|VerticalScaling + elements: + - type: block-layout + label: PerconaXtraDB Vertical Scaling elements: - - label: - text: labels.applyConfig.key - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/key - type: input - - label: - text: labels.applyConfig.value - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/value - type: editor - type: single-step-form - if: ifReconfigurationTypeEqualsTo|applyConfig - label: - text: labels.applyConfig.label - onChange: onApplyconfigChange - required: true - schema: - $ref: discriminator#/properties/applyConfig - tableContents: - - inTableColumn: true - label: - text: labels.applyConfig.key - path: key - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.applyConfig.value - path: value - type: value - typeOfValue: code - type: single-step-form-array - - if: returnFalse - label: - text: labels.removeCustomConfig - schema: - $ref: schema#/properties/spec/properties/configuration/properties/removeCustomConfig - type: switch - label: - text: labels.configuration - schema: - $ref: schema#/properties/spec/properties/configuration - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|Reconfigure - label: - text: Reconfigure Form - type: single-step-form - - discriminator: - tlsOperation: - default: update - type: string - elements: - - computed: initTlsOperation - if: hasTlsField - label: - text: labels.tlsOperation - onChange: onTlsOperationChange - options: - - text: Update - value: update - - text: Rotate - value: rotate - - text: Remove - value: remove - schema: - $ref: discriminator#/properties/tlsOperation - type: radio - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/remove - type: switch - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/rotateCertificates - type: switch - - elements: - - computed: initIssuerRefApiGroup - disabled: true - label: - text: labels.api_group - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup - type: input - - computed: setValueFromDbDetails|/spec/tls/issuerRef/kind - label: - text: labels.kind - options: - - text: Issuer - value: Issuer - - text: ClusterIssuer - value: ClusterIssuer - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/kind - sortable: true - type: select - - allowUserDefinedOption: true - computed: setValueFromDbDetails|/spec/tls/issuerRef/name - fetch: getIssuerRefsName - label: - text: labels.name - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/name - sortable: true - type: select - if: showIssuerRefAndCertificates - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef - type: single-step-form - - alias: reusable_certificates - chart: - name: uibytebuildersdev-component-certificates - version: v0.29.0 - computed: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates - functionCallbacks: - getAliasOptions: - $ref: functions#/getAliasOptions - if: showIssuerRefAndCertificates - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/spec/properties/tls/properties/certificates - type: reusable-element - if: ifRequestTypeEqualsTo|ReconfigureTLS - label: - text: labels.tls - schema: - $ref: schema#/properties/spec/properties/tls - type: single-step-form - - label: - text: labels.timeout - options: - - text: 5 minutes - value: 5m - - text: 10 minutes - value: 10m - - text: 30 minutes - value: 30m - - text: 1 hour - value: 1h - - text: 2 hours - value: 2h - - text: 5 hours - value: 5h - - text: 10 hours - value: 10h - schema: - $ref: schema#/properties/spec/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: labels.apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/spec/properties/apply - type: radio - type: single-step-form - id: basic - title: steps.0.label -type: multi-step-form + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines|perconaxtradb + init: + type: func + value: setMachine|perconaxtradb + watcher: + func: onMachineChange|perconaxtradb|/spec/podTemplate/spec/resources + paths: + - temp/properties/machine + schema: temp/properties/machine + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/perconaxtradb/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|perconaxtradb + schema: temp/topologyKey-perconaxtradb + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|perconaxtradb + schema: temp/topologyValue-perconaxtradb + - type: horizontal-layout + showLabels: true + label: Coordinator + elements: + - type: input + label: CPU Requests + schema: schema/properties/spec/properties/verticalScaling/properties/coordinator/properties/resources/properties/requests/cpu + init: + type: func + value: setValueFromDbDetails|/spec/coordinator/resources/requests/cpu|/spec/verticalScaling/coordinator/resources/requests/cpu + - type: input + label: CPU Limits + schema: schema/properties/spec/properties/verticalScaling/properties/coordinator/properties/resources/properties/limits/cpu + init: + type: func + value: setValueFromDbDetails|/spec/coordinator/resources/limits/cpu|/spec/verticalScaling/coordinator/resources/limits/cpu + - type: input + label: Memory Requests + schema: schema/properties/spec/properties/verticalScaling/properties/coordinator/properties/resources/properties/requests/memory + init: + type: func + value: setValueFromDbDetails|/spec/coordinator/resources/requests/memory|/spec/verticalScaling/coordinator/resources/requests/memory + - type: input + label: Memory Limits + schema: schema/properties/spec/properties/verticalScaling/properties/coordinator/properties/resources/properties/limits/memory + init: + type: func + value: setValueFromDbDetails|/spec/coordinator/resources/limits/memory|/spec/verticalScaling/coordinator/resources/limits/memory + - type: block-layout + label: Exporter + showLabels: true + hideBlock: true + elements: + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setExporter|cpu + type: input + 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 + watcher: + func: onExporterResourceChange|memory + paths: + - schema/properties/spec/properties/verticalScaling/properties/exporter/properties/resources/properties/limits/properties/memory +# Volume Expansion + - type: block-layout + label: Volume Expansion Form + if: + type: function + name: ifRequestTypeEqualsTo|VolumeExpansion + elements: + - type: horizontal-layout + elements: + - type: block-layout + elements: + - type: label-element + label: Mode (Required) + 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 downntime for added reliability during the volume expansion. + - type: select + label: Mode + options: + - text: Offline + value: Offline + - text: Online + value: Online + validation: + type: required + schema: schema/properties/spec/properties/volumeExpansion/properties/mode + - type: block-layout + label: PerconaXtraDB volume expansion + showLabels: true + fixedBlock: true + elements: + - type: horizontal-layout + elements: + - type: input-compare + header: PerconaXtraDB + subtitle: How much extra storage does your database need? Specify the size(e.g. 2Gi for 2 gigabytes) so we can allocate it correctly + label: Storage Size + init: + type: func + value: setValueFromDbDetails|/spec/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/perconaxtradb + schema: schema/properties/spec/properties/volumeExpansion/properties/perconaxtradb + - type: info + hasIcon: true + label: Volume expansion increases the available storage for your database. Make sure the new size is larger than the current size. +# Reconfigure + - type: block-layout + label: Reconfigure Form + if: + name: ifRequestTypeEqualsTo|Reconfigure + type: function + loader: + name: fetchConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + elements: + - type: block-layout + label: Configuration + elements: + - type: label-element + label: '' + subtitle: Select a new configuration secret, apply a custom configuration, or remove an existing setup to update your database settings + - type: tab-layout + label: New Config Secret + schema: temp/properties/reconfigurationType + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + elements: + - type: block-layout + label: Config Secret + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret + type: function + elements: + - type: label-element + label: Config Secret + subtitle: Select a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: schema/properties/spec/properties/configuration/properties/configSecret/properties/name + refresh: true + label: Config Secret + loader: + name: getConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/createSecret/properties/status + init: + type: func + value: setValueFromDbDetails|/spec/configSecret/name + watcher: + func: onCreateSecretChange + paths: + - temp/properties/createSecret/properties/status + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|create + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + - type: block-layout + label: Create a New Config Secret + showLabels: true + if: + type: function + name: isCreateSecret + hasButton: + text: Save + hasCancel: cancelCreateSecret + action: createNewConfigSecret + elements: + - type: input + label: Secret Name + schema: temp/properties/createSecret/properties/name + validation: + type: required + - type: array-object-form + label: String Data + schema: temp/properties/createSecret/properties/data + buttonClass: is-light is-outlined + validation: + type: required + elements: + - type: select + label: Key + schema: key + loader: + name: onSelectedSecretChange + watchPaths: + - temp/properties/createSecret/properties/data + validation: + type: required + - type: textarea + label: Value + schema: value + - type: multi-file-editor + editorHeight: 500px + readonly: true + if: + type: function + name: isNotCreateSecret + loader: + name: onNewConfigSecretChange + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + schema: temp/properties/newConfigSecret + - type: block-layout + label: ApplyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig + type: function + elements: + - type: label-element + 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). + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfiguration + refresh: true + label: Configuration + loader: getConfigSecretsforAppyConfig + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|apply + watchPaths: + - temp/properties/selectedConfiguration + - type: multi-file-editor + editorHeight: 500px + schema: temp/properties/applyConfig + loader: + name: setApplyConfig + watchPaths: + - temp/properties/selectedConfiguration + watcher: + func: onApplyconfigChange + paths: + - temp/properties/applyConfig + - type: block-layout + label: Remove + if: + name: ifReconfigurationTypeEqualsTo|remove + type: function + elements: + - type: label-element + label: Remove + subtitle: Selected a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfigurationRemove + refresh: true + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|remove + watchPaths: + - temp/properties/selectedConfigurationRemove + - type: multi-file-editor + editorHeight: 500px + readonly: true + init: + type: func + value: onRemoveConfigChange + watcher: + func: onRemoveConfigChange + paths: + - temp/properties/selectedConfigurationRemove + schema: temp/properties/removeConfig +# Reconfigure TLS + - type: block-layout + label: TLS + if: + name: ifRequestTypeEqualsTo|ReconfigureTLS + type: function + elements: + - type: radio + label: TLS Operation + schema: temp/properties/tlsOperation + if: + name: hasTlsField + type: function + options: + - text: Update + value: update + - text: Rotate + value: rotate + - text: Remove + value: remove + init: + type: func + value: initTlsOperation + watcher: + func: onTlsOperationChange + paths: + - temp/properties/tlsOperation + - type: switch + label: Remove TLS + fullwidth: true + if: + name: isTlsEnabled + type: function + schema: schema/properties/spec/properties/tls/properties/remove + - type: switch + label: Rotate Certificates + fullwidth: true + schema: schema/properties/spec/properties/tls/properties/rotateCertificates + if: + name: isTlsEnabled + type: function + - type: block-layout + label: Issuer Reference + showLabels: true + if: + name: showIssuerRefAndCertificates + type: function + elements: + - type: input + label: API Group + init: + type: func + value: initIssuerRefApiGroup + watcher: + func: initIssuerRefApiGroup + paths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + disable: true + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup + - type: select + label: Kind + options: + - text: Issuer + value: Issuer + - text: ClusterIssuer + value: ClusterIssuer + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/kind + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - type: select + label: Name + loader: + name: getIssuerRefsName + watchPaths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - schema/properties/metadata/properties/namespace + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/name + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/name + - type: block-layout + label: Certificates + showLabels: false + if: + name: showIssuerRefAndCertificates + type: function + loader: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates + elements: + - type: array-object-form + label: Certificates + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/tls/properties/certificates + elements: + - type: select + label: Alias + loader: fetchAliasOptions + disable: disableAlias + schema: alias + validation: + type: required + - type: input + label: Secret Name + schema: secretName + - type: input + label: Duration + schema: duration + - type: input + label: Renew Before + schema: renewBefore + - type: array-item-form + label: Organizations + buttonClass: is-light is-outlined + schema: subject/properties/organizations + element: + type: input + label: Organization + - type: array-item-form + label: Countries + buttonClass: is-light is-outlined + schema: subject/properties/countries + element: + type: input + label: Country + - type: array-item-form + label: Organizational Units + buttonClass: is-light is-outlined + schema: subject/properties/organizationalUnits + element: + type: input + label: Organizational Unit + - type: array-item-form + label: Provinces + buttonClass: is-light is-outlined + schema: subject/properties/provinces + element: + type: input + label: Province + - type: array-item-form + label: DNS Names + buttonClass: is-light is-outlined + schema: dnsNames + element: + type: input + label: DNS Name + - type: array-item-form + label: IP Addresses + buttonClass: is-light is-outlined + schema: ipAddresses + element: + type: input + label: IP Address +# common + - type: block-layout + label: OpsRequest Options + showLabels: true + elements: + - type: time-picker + label: Timeout + schema: 'schema/properties/spec/properties/timeout' + subtitle: Specify the maximum time allowed for the scaling operation to complete. Use formats like 30sec, 1min(1 minute) or 2h(2 hours). + - type: radio + label: Apply + schema: 'schema/properties/spec/properties/apply' + init: + type: func + value: setApplyToIfReady + options: + - text: IfReady (OpsRequest will be applied if database is ready) + value: IfReady + - text: Always (OpsRequest will always be applied) + value: Always diff --git a/charts/opskubedbcom-perconaxtradbopsrequest-editor/ui/functions.js b/charts/opskubedbcom-perconaxtradbopsrequest-editor/ui/functions.js index 99561c4574..a36c71d3cf 100644 --- a/charts/opskubedbcom-perconaxtradbopsrequest-editor/ui/functions.js +++ b/charts/opskubedbcom-perconaxtradbopsrequest-editor/ui/functions.js @@ -1,3 +1,4 @@ +const { axios, useOperator, store, useToast } = window.vueHelpers || {} const machines = { 'db.t.micro': { resources: { @@ -304,996 +305,1504 @@ const machineList = [ 'db.r.24xlarge', ] -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 isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} +const configSecretKeys = ['kubedb-user.cnf'] +let machinesFromPreset = [] +let secretArray = [] -async function getNamespaces({ axios, storeGet }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') +export const useFunc = (model) => { + const route = store.state?.route + const toast = useToast() - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + const { getValue, storeGet, discriminator, setDiscriminatorValue, commit } = useOperator( + model, + store.state, + ) - const resources = (resp && resp.data && resp.data.items) || [] + showAndInitOpsRequestType() + async function fetchJsons({ axios, itemCtx }) { + let ui = {} + let language = {} + let functions = {} + const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, + 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) } - }) -} - -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - 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}/perconaxtradbs`, - { - 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, + ui: ui.data || {}, + language: language.data || {}, + functions, } - }) -} + } -async function getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) { - 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') + function returnFalse() { + return false + } - if (namespace && name) { - const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/perconaxtradbs/${name}` - const resp = await axios.get(url) + function isTlsEnabled() { + const dbDetails = getValue(discriminator, '/dbDetails') + return ( + (dbDetails?.spec?.sslMode && + dbDetails?.spec?.sslMode !== 'disabled' && + dbDetails?.spec?.sslMode !== 'disable') || + dbDetails?.spec?.tls + ) + } - setDiscriminatorValue('/dbDetails', resp.data || {}) + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } - return resp.data || {} - } else return {} -} + async function getNamespaces() { + if (storeGet('/route/params/actions')) return [] + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -async function getDbVersions({ axios, storeGet, getValue, discriminator }) { - 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 url = `/clusters/${owner}/${cluster}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/kubedb-ui-presets` + const resources = (resp && resp.data && resp.data.items) || [] - 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) - } + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) } - try { - const presetVersions = presets.admin?.databases?.PerconaXtraDB?.versions?.available || [] - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null, updateConstraints: null }, - }, - }, - } + 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/catalog.kubedb.com/v1alpha1/perconaxtradbversions`, + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/perconaxtradbs`, { - params: queryParams, + params: { filter: { items: { metadata: { name: null } } } }, }, ) 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 allowed = found?.spec?.updateConstraints?.allowlist || [] - 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 filteredPerconaXtraDBVersions = 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.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.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.includes(item.metadata?.name)) && - isVersionWithinConstraints(item.spec?.version, limit) - ) - }) - - return filteredPerconaXtraDBVersions.map((item) => { + return resources.map((item) => { const name = (item.metadata && item.metadata.name) || '' - const specVersion = (item.spec && item.spec.version) || '' return { - text: `${name} (${specVersion})`, + text: name, value: name, } }) - } catch (e) { - console.log(e) - return [] } -} -function versionCompare(v1, v2) { - const arr1 = v1.split('.').map(Number) - const arr2 = v2.split('.').map(Number) + async function getDbDetails() { + machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] - for (let i = 0; i < Math.max(arr1.length, arr2.length); i++) { - const num1 = arr1[i] || 0 - const num2 = arr2[i] || 0 + 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}/perconaxtradbs/${name}` + const resp = await axios.get(url) - if (num1 > num2) return 1 // v1 is higher - if (num1 < num2) return -1 // v2 is higher + setDiscriminatorValue('/dbDetails', resp.data || {}) + + return resp.data || {} + } else return {} } - 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 + 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 { + const presetVersions = presets.admin?.databases?.PerconaXtraDB?.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/perconaxtradbversions`, + { + 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 allowed = found?.spec?.updateConstraints?.allowlist || [] + 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 filteredPerconaXtraDBVersions = 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.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.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.includes(item.metadata?.name)) && + isVersionWithinConstraints(item.spec?.version, limit) + ) + }) + return filteredPerconaXtraDBVersions.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 [] + } } - return true -} -function ifRequestTypeEqualsTo({ model, getValue, watchDependency }, type) { - const selectedType = getValue(model, '/spec/type') - watchDependency('model#/spec/type') + function versionCompare(v1, v2) { + const arr1 = v1.split('.').map(Number) + const arr2 = v2.split('.').map(Number) - return selectedType === type -} + for (let i = 0; i < Math.max(arr1.length, arr2.length); i++) { + const num1 = arr1[i] || 0 + const num2 = arr2[i] || 0 -function onRequestTypeChange({ model, getValue, commit }) { - 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]}`) - }) -} + if (num1 > num2) return 1 // v1 is higher + if (num1 < num2) return -1 // v2 is higher + } + return 0 // versions are equal + } -function disableOpsRequest({ itemCtx, discriminator, getValue, watchDependency }) { - if (itemCtx.value === 'HorizontalScaling') { - const dbType = getDbType({ - discriminator, - getValue, - watchDependency, + 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]}`) }) + } - if (dbType === 'Standalone') return true - else return false - } else return false -} + function getDbTls() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') -function getDbTls({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + const { spec } = dbDetails || {} + return spec?.tls || undefined + } - const { spec } = dbDetails || {} - return spec?.tls || undefined -} + function getDbType() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') -function getDbType({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + const { spec } = dbDetails || {} + const { mode } = spec || {} - const { spec } = dbDetails || {} - const { mode } = spec || {} + return mode || 'Standalone' + } - return mode || 'Standalone' -} + function disableOpsRequest() { + return false + } -function initNamespace({ route }) { - const { namespace } = route.query || {} - return namespace || null -} + function initNamespace() { + const { namespace } = route.query || {} + return namespace || null + } -function initDatabaseRef({ route, watchDependency }) { - watchDependency('model#/metadata/namespace') - const { name } = route.params || {} - return name -} + function initDatabaseRef() { + // watchDependency('model#/metadata/namespace') + const { name } = route.params || {} + return name + } -function asDatabaseOperation(route) { - return !!route.params.actions -} + function asDatabaseOperation() { + return !!route.params.actions + } -function generateOpsRequestNameForClusterUI(getValue, model, route) { - const dbName = getValue(model, '/spec/databaseRef/name') + 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 selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' - const resources = route.params.resource || '' - const resource = resources.slice(0, -1) + 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 : ''}` -} + const opsName = dbName ? dbName : resource + return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` + } -function showAndInitName({ route, commit, getValue, model, watchDependency }) { - watchDependency('model#/spec/type') - watchDependency('model#/spec/databaseRef/name') - const ver = asDatabaseOperation(route) + 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() : '' + 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, - }) + 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 } - return !ver -} -function showAndInitNamespace({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/metadata/namespace', - value: `${route.query.namespace}`, - force: true, - }) + + function showAndInitNamespace() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/metadata/namespace', + value: `${route.query.namespace}`, + force: true, + }) + } + + return !ver } - return !ver -} -function showAndInitDatabaseRef({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/spec/databaseRef/name', - value: `${route.params.name}`, - force: true, - }) + function showAndInitDatabaseRef() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/spec/databaseRef/name', + value: `${route.params.name}`, + force: true, + }) + } + + return !ver } - return !ver -} -function showConfigureOpsrequestLabel({ route }) { - return !asDatabaseOperation(route) -} -function showAndInitOpsRequestType({ route, commit }) { - const ver = asDatabaseOperation(route) - const opMap = { - upgrade: 'UpdateVersion', - updateVersion: 'UpdateVersion', - horizontalscaling: 'HorizontalScaling', - verticalscaling: 'VerticalScaling', - volumeexpansion: 'VolumeExpansion', - restart: 'Restart', - reconfiguretls: 'ReconfigureTLS', - reconfigure: 'Reconfigure', - } - if (ver) { - const operation = route.params.actions - const match = /^(.*)-opsrequest-(.*)$/.exec(operation) - const opstype = match[2] - commit('wizard/model$update', { - path: '/spec/type', - value: opMap[opstype], - force: true, - }) + function showConfigureOpsrequestLabel() { + return !asDatabaseOperation() } - return !ver -} + 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, + }) + } + } -// vertical scaling -function ifDbTypeEqualsTo({ discriminator, getValue, watchDependency, commit }, value, opsReqType) { - const verd = getDbType({ - discriminator, - getValue, - watchDependency, - }) + return !ver + } - return value === verd -} + // // vertical scaling + function ifDbTypeEqualsTo(value, opsReqType) { + const verd = getDbType() -// machine profile stuffs -let machinesFromPreset = [] + return value === verd + } -function getMachines({ storeGet }) { - const presets = storeGet('/kubedbuiPresets') || {} - const avlMachines = presets.admin?.machineProfiles?.available || [] - let arr = [] - if (avlMachines.length) { - arr = avlMachines.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - 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 } - } else return { text: machine, value: machine } - } - }) - } else { - arr = machineList - .map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + // // 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 } } + } }) - .filter((val) => !!val) + } 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 } - return arr -} -function setMachine({ getValue, discriminator, storeGet }) { - const dbDetails = getValue(discriminator, '/dbDetails') - const annotations = dbDetails?.metadata?.annotations || {} - const machine = annotations['kubernetes.io/instance-type'] || 'custom' + 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' - machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] + 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 } + } - const machinePresets = machinesFromPreset.find((item) => item.id === machine) - if (machinePresets) return machine - else return 'custom' -} + 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 }, + } + } -function onMachineChange({ getValue, discriminator, commit, model }, type, valPath) { - let selectedMachine = '' - selectedMachine = getValue(discriminator, '/machine') - const machine = machinesFromPreset.find((item) => item.id === selectedMachine) + const path = `/spec/verticalScaling/${type}/resources` - let obj = {} - if (selectedMachine !== 'custom') { - if (machine) obj = { limits: { ...machine?.limits }, requests: { ...machine?.limits } } - else obj = machines[selectedMachine]?.resources - } else { - const val = getValue(discriminator, `/dbDetails${valPath}`) || {} - obj = Array.isArray(val) ? val[0]?.resources : { ...val } - } + if (obj && Object.keys(obj).length) + commit('wizard/model$update', { + path: path, + value: obj, + force: true, + }) - const path = `/spec/verticalScaling/${type}/resources` + // update metadata.annotations + const annotations = getValue(model, '/metadata/annotations') || {} + const instance = annotations['kubernetes.io/instance-type'] + let parsedInstance = {} + try { + if (instance) parsedInstance = instance + } catch (e) { + console.log(e) + parsedInstance = {} + } - if (obj && Object.keys(obj).length) - commit('wizard/model$update', { - path: path, - value: obj, - force: true, - }) + parsedInstance = selectedMachine.machine + annotations['kubernetes.io/instance-type'] = JSON.stringify(parsedInstance) - // update metadata.annotations - const annotations = getValue(model, '/metadata/annotations') || {} - if (selectedMachine === 'custom') commit('wizard/model$delete', '/metadata/annotations') - else { - annotations['kubernetes.io/instance-type'] = selectedMachine if (machinesFromPreset.length) commit('wizard/model$update', { path: '/metadata/annotations', value: annotations, force: true, }) + + if (!parsedInstance || (parsedInstance && Object.keys(parsedInstance).length === 0)) + commit('wizard/model$delete', '/metadata/annotations') } -} -function isMachineCustom({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/machine') - const machine = getValue(discriminator, '/machine') - return machine === 'custom' -} + function isMachineCustom(path) { + // watchDependency(`discriminator#${path}`) + const machine = getValue(discriminator, `${path}`) + return machine === 'custom' + } -// for config secret -async function getConfigSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + // Fetch and store database Infos + // for secret configurations in reconfigure + let configSecrets = [] + let secretConfigData = [] - const secrets = (resp && resp.data && resp.data.items) || [] + 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 filteredSecrets = secrets + 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') - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return filteredSecrets -} + 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) + } + } -function createSecretUrl({ storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 + } - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/secrets/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/secrets/create` + async function getConfigSecretsforAppyConfig() { + const secrets = secretConfigData.map((item) => { + return { text: item.componentName, value: item.componentName } + }) + return secrets } -} -function isEqualToValueFromType({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/valueFromType') - const valueFrom = getValue(discriminator, '/valueFromType') - return valueFrom === value -} + function getSelectedConfigurationData(type) { + type = type ? type + '/' : '' + const path = `/${type}selectedConfiguration` + const selectedConfiguration = getValue(discriminator, path) -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + if (!selectedConfiguration) { + return [] + } - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + const configuration = secretConfigData.find( + (item) => item.componentName === selectedConfiguration, + ) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, + 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 + }) + } }) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + // Set the value to the model + commit('wizard/model$update', { + path: `/temp/${type}applyConfig`, + value: result, + force: true, + }) + + return result } - return ans -} -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` + const selectedConfiguration = + configType === 'create' ? getValue(model, path) : getValue(discriminator, path) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, + 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 + } }) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + // Convert data object back to YAML string + return yaml.dump(data) } - return ans -} -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - group, - version, - resource, -) { - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/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) - }) + 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])) + + 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 resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + function decodeError(msg, defaultMsg) { + if (typeof msg === 'string') { + return msg || defaultMsg } - }) -} -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) - - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) + return ( + (msg.response && msg.response.data && msg.response.data.message) || + (msg.response && msg.response.data) || + (msg.status && msg.status.status) || + defaultMsg + ) } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + 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 + } -// reconfiguration type -function ifReconfigurationTypeEqualsTo({ discriminator, getValue, watchDependency }, value) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - watchDependency('discriminator#/reconfigurationType') + function isNotCreateSecret(type) { + return !isCreateSecret(type) + } - return reconfigurationType === value -} + 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`) -function onApplyconfigChange({ discriminator, getValue, commit }) { - const applyconfig = getValue(discriminator, '/applyConfig') + const configFound = configSecrets.find((item) => item === name) + return configFound ? { text: name, value: name } : '' + } + } - const configObj = {} - if (applyconfig) { - applyconfig.forEach((item) => { - const { key, value } = item - configObj[key] = value + 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', }) } - commit('wizard/model$update', { - path: '/spec/configuration/applyConfig', - value: configObj, - force: true, - }) -} - -function onReconfigurationTypeChange({ commit, discriminator, getValue, setDiscriminatorValue }) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - setDiscriminatorValue('/applyConfig', []) - if (reconfigurationType === 'remove') { - commit('wizard/model$delete', `/spec/configuration`) + 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) { + 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/removeCustomConfig`, - value: true, - force: true, + path: `/spec/configuration/${type}applyConfig`, + value: tempConfigObj, }) - } 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({ discriminator, getValue, watchDependency }) { - const tls = getDbTls({ - discriminator, - getValue, - watchDependency, - }) + 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], + }) + }) + } else { + configObj.push({ name: '', content: '' }) + } + return configObj + } - return !!tls -} + function onRemoveConfigChange(type) { + type = type ? type + '/' : '' + const configPath = `/${type}selectedConfigurationRemove` + const selectedConfig = getValue(discriminator, configPath) -function initIssuerRefApiGroup({ getValue, model, watchDependency, discriminator }) { - const kind = getValue(model, '/spec/tls/issuerRef/kind') - watchDependency('model#/spec/tls/issuerRef/kind') + if (!selectedConfig) { + commit('wizard/model$delete', `/spec/configuration/${type}removeCustomConfig`) + return [{ name: '', content: '' }] + } + commit('wizard/model$update', { + path: `/spec/configuration/${type}removeCustomConfig`, + value: true, + }) - if (kind) { - const apiGroup = getValue(discriminator, '/dbDetails/spec/tls/issuerRef/apiGroup') - if (apiGroup) return apiGroup - return 'cert-manager.io' - } else return undefined -} + const configuration = secretConfigData.find((item) => item.componentName === selectedConfig) -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - 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` + if (!configuration.data) { + return [{ name: '', content: '' }] + } - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + const configObj = [] + // Decode base64 and format as array of objects with name and content + Object.keys(configuration.data).forEach((fileName) => { try { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + // Decode base64 string + const decodedString = atob(configuration.data[fileName]) + configObj.push({ + name: fileName, + content: decodedString, + }) } catch (e) { - console.log(e) - presets.status = String(e.status) + 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: '' }] } - let clusterIssuers = presets.admin?.clusterIssuers?.available || [] - if (presets.status === '404') { - const url = `/clusters/${owner}/${cluster}/proxy/cert-manager.io/v1/clusterissuers` - return getIssuer(url) + 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: '' }] } - return clusterIssuers } - async function getIssuer(url) { - try { - const resp = await axios.get(url) - const resources = (resp && resp.data && resp.data.items) || [] + function onSelectedSecretChange(index) { + const secretData = getValue(discriminator, 'createSecret/data') || [] + const selfSecrets = secretData.map((item) => item.key) - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + 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 + } + + 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 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 } }, + }, }) - return resources + + const items = (resp && resp.data && resp.data.items) || [] + ans = items } catch (e) { console.log(e) - return [] } + + return ans } -} + async function getResourceList({ group, version, resource }) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function initTlsOperation() { - return 'update' -} -function onTlsOperationChange({ discriminator, getValue, commit }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` - commit('wizard/model$delete', '/spec/tls') + let ans = [] + try { + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) - if (tlsOperation === 'rotate') { - commit('wizard/model$update', { - path: '/spec/tls/rotateCertificates', - value: true, - force: true, + 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, }) - 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, + + 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, + } }) - commit('wizard/model$delete', '/spec/tls/certificates') - commit('wizard/model$delete', '/spec/tls/rotateCertificates') } -} + async function unNamespacedResourceNames(group, version, resource) { + let resources = await getResourceList({ + group, + version, + resource, + }) -function showIssuerRefAndCertificates({ discriminator, getValue, watchDependency }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') - watchDependency('discriminator#/tlsOperation') - const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } - return verd -} + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -function isIssuerRefRequired({ discriminator, getValue, watchDependency }) { - const hasTls = hasTlsField({ - discriminator, - getValue, - watchDependency, - }) + // reconfiguration type + function ifReconfigurationTypeEqualsTo(value) { + const reconfigurationType = getValue(discriminator, '/reconfigurationType') - return !hasTls -} + const watchPath = `discriminator#/reconfigurationType` + // watchDependency(watchPath) + return reconfigurationType === value + } -function getRequestTypeFromRoute({ route, model, discriminator, getValue, watchDependency }) { - const isDbloading = isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) - const { query } = route || {} - const { requestType } = query || {} - return isDbloading ? '' : requestType || '' -} + function onReconfigurationTypeChange() { + setDiscriminatorValue(`/applyConfig`, []) + const reconfigurationType = getValue(discriminator, '/reconfigurationType') + 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`) + } + } -// ************************************** Set db details ***************************************** + // for tls + function hasTlsField() { + const tls = getDbTls() -function isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - watchDependency('model#/spec/databaseRef/name') - const dbDetails = getValue(discriminator, '/dbDetails') - const dbName = getValue(model, '/spec/databaseRef/name') + return !!tls + } - return !dbDetails || !dbName -} + function initIssuerRefApiGroup() { + const kind = getValue(model, '/spec/tls/issuerRef/kind') + // watchDependency('model#/spec/tls/issuerRef/kind') -function setResource({ discriminator, getValue, watchDependency, storeGet }, path) { - watchDependency('discriminator#/dbDetails') - const containers = getValue(discriminator, `/dbDetails${path}`) || [] - const kind = getValue(discriminator, '/dbDetails/kind') - const resource = containers.filter((ele) => ele.name === kind.toLowerCase()) - return resource[0].resources -} + if (kind) { + return 'cert-manager.io' + } else return undefined + } -function setValueFromDbDetails( - { discriminator, getValue, watchDependency, commit }, - path, - commitPath, -) { - watchDependency('discriminator#/dbDetails') + 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') - const retValue = getValue(discriminator, `/dbDetails${path}`) + 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 [] + } + } + } - if (commitPath && retValue) { + function initTlsOperation() { + return 'update' + } + function onTlsOperationChange() { const tlsOperation = getValue(discriminator, '/tlsOperation') - // computed called when tls fields is not visible - if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined + commit('wizard/model$delete', '/spec/tls') - // 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, - }) + if (tlsOperation === 'rotate') { + commit('wizard/model$update', { + path: '/spec/tls/rotateCertificates', + value: true, + force: true, + }) + } else if (tlsOperation === 'remove') { + commit('wizard/model$update', { + path: '/spec/tls/remove', + value: true, + force: true, + }) + } } - return retValue || undefined -} + function showIssuerRefAndCertificates() { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // watchDependency('discriminator#/tlsOperation') + const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} + return verd + } -function isNamespaceDisabled({ route }) { - const { namespace } = route.query || {} - return !!namespace -} + function isIssuerRefRequired() { + const hasTls = hasTlsField() + return hasTls ? false : '' + } -function isDatabaseRefDisabled({ route }) { - const { name } = route.params || {} - return !!name -} + function getRequestTypeFromRoute() { + const isDbloading = isDbDetailsLoading() + const { query } = route || {} + const { requestType } = query || {} + return isDbloading ? '' : requestType || '' + } -function onNamespaceChange({ commit }) { - commit('wizard/model$delete', '/spec/type') -} + function isDbDetailsLoading() { + // watchDependency('discriminator#/dbDetails') + // watchDependency('model#/spec/databaseRef/name') + const dbDetails = getValue(discriminator, '/dbDetails') + const dbName = getValue(model, '/spec/databaseRef/name') -function onDbChange({ commit, axios, storeGet, model, getValue, setDiscriminatorValue }) { - commit('wizard/model$delete', '/spec/type') - getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) -} + return !dbDetails || !dbName + } -function setApplyToIfReady() { - return 'IfReady' -} + function setValueFromDbDetails(path, commitPath) { + const retValue = getValue(discriminator, `/dbDetails${path}`) -function isVerticalScaleTopologyRequired({ watchDependency, getValue, discriminator, commit }) { - watchDependency('discriminator#/topologyKey') - watchDependency('discriminator#/topologyValue') + if (commitPath) { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // computed called when tls fields is not visible + if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined - const key = getValue(discriminator, '/topologyKey') - const value = getValue(discriminator, '/topologyValue') - const path = `/spec/verticalScaling/perconaxtradb/topology` + // 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 + } - if (key || value) { - commit('wizard/model$update', { - path: path, - value: { key, value }, - force: true, + 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/perconaxtradb/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 true - } else { - commit('wizard/model$delete', path) - return false + return data || 'No Data Found' } -} -function checkVolume({ model, discriminator, getValue }, initpath, path) { - const volume = getValue(discriminator, `/dbDetails${initpath}`) - const input = getValue(model, path) + function setExporter(type) { + let path = `/dbDetails/spec/monitor/prometheus/exporter/resources/limits/${type}` + const limitVal = getValue(discriminator, path) - try { - const sizeInBytes = parseSize(volume) - const inputSizeInBytes = parseSize(input) + if (!limitVal) { + path = `/dbDetails/spec/monitor/prometheus/exporter/resources/requests/${type}` + const reqVal = getValue(discriminator, path) - if (inputSizeInBytes >= sizeInBytes) return true - else return 'Cannot expand to lower volume!' - } catch (err) { - return err.message || 'Invalid' + if (reqVal) return reqVal + } + return limitVal } -} -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 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, + }) + } -return { - setResource, - fetchJsons, - returnFalse, - getNamespaces, - getDbs, - getDbDetails, - getDbVersions, - ifRequestTypeEqualsTo, - onRequestTypeChange, - getDbTls, - getDbType, - initNamespace, - initDatabaseRef, - isRancherManaged, - showAndInitName, - showAndInitNamespace, - showAndInitDatabaseRef, - showConfigureOpsrequestLabel, - showAndInitOpsRequestType, - - ifDbTypeEqualsTo, - getConfigSecrets, - createSecretUrl, - isEqualToValueFromType, - disableOpsRequest, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - ifReconfigurationTypeEqualsTo, - onReconfigurationTypeChange, - onApplyconfigChange, - hasTlsField, - initIssuerRefApiGroup, - getIssuerRefsName, - initTlsOperation, - onTlsOperationChange, - showIssuerRefAndCertificates, - isIssuerRefRequired, - getRequestTypeFromRoute, - isDbDetailsLoading, - setValueFromDbDetails, - getAliasOptions, - isNamespaceDisabled, - isDatabaseRefDisabled, - onNamespaceChange, - onDbChange, - setApplyToIfReady, - isVerticalScaleTopologyRequired, - getMachines, - setMachine, - onMachineChange, - isMachineCustom, - checkVolume, + return { + setExporter, + onExporterResourceChange, + fetchAliasOptions, + validateNewCertificates, + disableAlias, + isRancherManaged, + fetchJsons, + returnFalse, + getNamespaces, + getDbs, + getDbDetails, + getDbVersions, + ifRequestTypeEqualsTo, + onRequestTypeChange, + getDbTls, + getDbType, + disableOpsRequest, + initNamespace, + initDatabaseRef, + showAndInitName, + showAndInitNamespace, + showAndInitDatabaseRef, + showConfigureOpsrequestLabel, + showAndInitOpsRequestType, + ifDbTypeEqualsTo, + getConfigSecrets, + createSecretUrl, + getSelectedConfigSecret, + getSelectedConfigSecretValue, + isEqualToValueFromType, + getNamespacedResourceList, + getResourceList, + resourceNames, + unNamespacedResourceNames, + ifReconfigurationTypeEqualsTo, + onReconfigurationTypeChange, + onApplyconfigChange, + hasTlsField, + initIssuerRefApiGroup, + getIssuerRefsName, + initTlsOperation, + onTlsOperationChange, + showIssuerRefAndCertificates, + isIssuerRefRequired, + getRequestTypeFromRoute, + isDbDetailsLoading, + setValueFromDbDetails, + getAliasOptions, + isNamespaceDisabled, + isDatabaseRefDisabled, + onDbChange, + onNamespaceChange, + setApplyToIfReady, + isVerticalScaleTopologyRequired, + getMachines, + setMachine, + onMachineChange, + isMachineCustom, + checkVolume, + fetchConfigSecrets, + getConfigSecretsforAppyConfig, + getSelectedConfigurationData, + getSelectedConfigurationName, + getSelectedConfigurationValueForRemove, + createNewConfigSecret, + decodeError, + isCreateSecret, + isNotCreateSecret, + onCreateSecretChange, + cancelCreateSecret, + setApplyConfig, + onRemoveConfigChange, + onNewConfigSecretChange, + onSelectedSecretChange, + isTlsEnabled, + } } diff --git a/charts/opskubedbcom-pgbounceropsrequest-editor/ui/create-ui.yaml b/charts/opskubedbcom-pgbounceropsrequest-editor/ui/create-ui.yaml index 95eb81e9cf..70501199f7 100644 --- a/charts/opskubedbcom-pgbounceropsrequest-editor/ui/create-ui.yaml +++ b/charts/opskubedbcom-pgbounceropsrequest-editor/ui/create-ui.yaml @@ -1,296 +1,420 @@ -steps: -- form: - discriminator: - dbDetails: - type: object +type: multi-step-form +step: + - type: single-step-form + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - schema: - $ref: discriminator#/properties/dbDetails - type: input - - if: showAndInitName - label: - text: labels.op_req_name - required: true - schema: - $ref: schema#/properties/metadata/properties/name - type: input - - computed: initNamespace - disabled: isNamespaceDisabled - fetch: getNamespaces - hasGroup: isRancherManaged - if: showAndInitNamespace - label: - text: labels.namespace - onChange: onNamespaceChange - required: true - schema: - $ref: schema#/properties/metadata/properties/namespace - type: select - - computed: initDatabaseRef - disabled: isDatabaseRefDisabled - fetch: getDbs - if: showAndInitDatabaseRef - label: - text: labels.databaseRef - onChange: onDbChange - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/databaseRef/properties/name - type: select - - if: showConfigureOpsrequestLabel - label: - text: labels.config_ops_request - type: label-element - - computed: getRequestTypeFromRoute - disabled: isDbDetailsLoading - hasDescription: true - if: showAndInitOpsRequestType - individualItemDisabilityCheck: disableOpsRequest - label: - text: labels.ops_request_type - onChange: onRequestTypeChange - options: - - description: options.UpdateVersion.description - text: options.UpdateVersion.text - value: UpdateVersion - - description: options.HorizontalScaling.description - text: options.HorizontalScaling.text - value: HorizontalScaling - - description: options.VerticalScaling.description - text: options.VerticalScaling.text - value: VerticalScaling - - description: options.Restart.description - text: options.Restart.text - value: Restart - - description: options.Reconfigure.description - text: options.Reconfigure.text - value: Reconfigure - schema: - $ref: schema#/properties/spec/properties/type - type: radio - - elements: - - computed: setValueFromDbDetails|/spec/version - fetch: getDbVersions - label: - text: labels.targetVersion - schema: - $ref: schema#/properties/spec/properties/updateVersion/properties/targetVersion - type: select - if: ifRequestTypeEqualsTo|UpdateVersion - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/replicas - label: - text: Replicas - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/replicas - type: input - if: ifRequestTypeEqualsTo|HorizontalScaling - label: - text: Horizontal Scaling Form - type: single-step-form - - elements: - - discriminator: - machine: - default: "" - type: string +# common + - type: input + label: op_req_name + if: + type: function + name: showAndInitName + validation: + type: required + schema: schema/properties/metadata/properties/name + - type: select + label: Namespace + if: + type: function + name: showAndInitNamespace + init: + type: func + value: initNamespace + disable: isNamespaceDisabled + loader: getNamespaces + validation: + type: required + hasGroup: isRancherManaged + schema: schema/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/metadata/properties/namespace + - type: select + label: Database Ref + if: + type: function + name: showAndInitDatabaseRef + loader: + name: getDbs + watchPaths: + - schema/properties/metadata/properties/namespace + init: + type: func + value: initDatabaseRef + validation: + type: required + disable: isDatabaseRefDisabled + refresh: true + watcher: + func: onDbChange + paths: + - schema/properties/spec/properties/databaseRef/properties/name + schema: schema/properties/spec/properties/databaseRef/properties/name + - type: label-element + label: config_ops_request + if: + type: function + name: showConfigureOpsrequestLabel + - type: radio + label: Type of Ops Request + if: + type: function + name: showAndInitOpsRequestType + 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: Restart your database + text: Restart + value: Restart + - description: Reconfigure your database + text: Reconfigure + value: Reconfigure + init: + type: func + value: getRequestTypeFromRoute + disable: isDbDetailsLoading + watcher: + func: isDbDetailsLoading + paths: + - temp/dbDetails + - schema/properties/spec/properties/databaseRef/properties/name + isHorizontal: true + schema: schema/properties/spec/properties/type +# UpdateVersion + - type: block-layout + showLabels: true + label: Version + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|UpdateVersion elements: - - computed: setMachine - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|pgbouncer|/spec/podTemplate/spec/resources - schema: - $ref: discriminator#/machine - type: select - - if: isMachineCustom - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/pgbouncer/properties/resources - type: resource-input-form - - label: - text: Node Selection Policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/pgbouncer/properties/nodeSelectionPolicy - type: select - - elements: - - label: - text: key - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/pgbouncer/properties/topology/properties/key - type: input - - label: - text: value - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/pgbouncer/properties/topology/properties/value - type: input - label: - text: Topology - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/pgbouncer/properties/topology - show_label: true - type: single-step-form - label: - text: PgBouncer - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/pgbouncer - show_label: true - type: single-step-form - - elements: - - computed: setResource|/spec/podTemplate/spec/containers - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/exporter/properties/resources - type: resource-input-form - label: - text: Exporter - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/exporter - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|VerticalScaling - type: single-step-form - - elements: - - discriminator: - reconfigurationType: - type: string + - type: select-compare + label: Target Version + subtitle: Select the desired PgBouncer version to which you want to update your database. + init: + type: func + value: setValueFromDbDetails|/spec/version + loader: getDbVersions + schema: schema/properties/spec/properties/updateVersion/properties/targetVersion + - type: info + label: '' + loader: + name: getVersionInfo + watchPaths: + - temp/properties/filteredVersion + if: + type: function + name: isVersionEmpty +# Horizontal Scale + - type: block-layout + label: Horizontal Scaling Form + showLabels: true + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|HorizontalScaling elements: - - label: - text: labels.reconfigurationType - onChange: onReconfigurationTypeChange - options: - - text: Select New Config Secret - value: selectNewConfigSecret - - text: Apply Config - value: applyConfig - - text: Remove - value: remove - required: true - schema: - $ref: discriminator#/properties/reconfigurationType - type: radio - - elements: - - add_new_button: - label: labels.createConfig - target: _blank - url: - function: createSecretUrl - computed: setValueFromDbDetails|/spec/configuration/pgbouncer/configSecret/name - fetch: getConfigSecrets - label: - text: labels.configSecret - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/configuration/properties/pgbouncer/properties/configSecret/properties/name - type: select - if: ifReconfigurationTypeEqualsTo|selectNewConfigSecret - label: - text: Configuration config secret - schema: - $ref: schema#/properties/spec/properties/configuration/properties/pgbouncer/properties/configSecret - type: single-step-form - - addFormLabel: labels.applyConfig.label - element: - discriminator: - configArray: - emitAs: applyConfig - type: array + - type: horizontal-layout elements: - - label: - text: labels.applyConfig.key - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/key - type: input - - label: - text: labels.applyConfig.value - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/value - type: editor - type: single-step-form - if: ifReconfigurationTypeEqualsTo|applyConfig - label: - text: labels.applyConfig.label - onChange: onApplyconfigChange - required: true - schema: - $ref: discriminator#/properties/applyConfig - tableContents: - - inTableColumn: true - label: - text: labels.applyConfig.key - path: key - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.applyConfig.value - path: value - type: value - typeOfValue: code - type: single-step-form-array - - if: returnFalse - label: - text: labels.removeCustomConfig - schema: - $ref: schema#/properties/spec/properties/configuration/properties/pgbouncer/properties/removeCustomConfig - type: switch - label: - text: labels.configuration - schema: - $ref: schema#/properties/spec/properties/configuration - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|Reconfigure - label: - text: Reconfigure Form - type: single-step-form - - label: - text: labels.timeout - options: - - text: 5 minutes - value: 5m - - text: 10 minutes - value: 10m - - text: 30 minutes - value: 30m - - text: 1 hour - value: 1h - - text: 2 hours - value: 2h - - text: 5 hours - value: 5h - - text: 10 hours - value: 10h - schema: - $ref: schema#/properties/spec/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: labels.apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/spec/properties/apply - type: radio - type: single-step-form - id: basic - title: steps.0.label -type: multi-step-form + - type: input-compare + label: Replicas + header: Replica + subtitle: Define the total number of replicas for the database. Increasing replicas improves fault tolerance and load distribution, while reducing replicas conserves resources + init: + type: func + value: setValueFromDbDetails|/spec/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/replicas + - type: info + 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. +# vertical Scale + - type: block-layout + if: + type: function + name: ifRequestTypeEqualsTo|VerticalScaling + elements: + - type: block-layout + label: PgBouncer Vertical Scaling + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines|pgbouncer + init: + type: func + value: setMachine|pgbouncer + watcher: + func: onMachineChange|pgbouncer|/spec/podTemplate/spec/resources + paths: + - temp/properties/machine + schema: temp/properties/machine + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/pgbouncer/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|pgbouncer + schema: temp/topologyKey-pgbouncer + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|pgbouncer + schema: temp/topologyValue-pgbouncer + - type: block-layout + label: Exporter + showLabels: true + hideBlock: true + elements: + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setExporter|cpu + type: input + 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 + watcher: + func: onExporterResourceChange|memory + paths: + - schema/properties/spec/properties/verticalScaling/properties/exporter/properties/resources/properties/limits/properties/memory +# Reconfigure + - type: block-layout + label: Reconfigure Form + if: + name: ifRequestTypeEqualsTo|Reconfigure + type: function + loader: + name: fetchConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + elements: + - type: block-layout + label: Configuration + elements: + - type: label-element + label: '' + subtitle: Select a new configuration secret, apply a custom configuration, or remove an existing setup to update your database settings + - type: tab-layout + label: New Config Secret + schema: temp/properties/reconfigurationType + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + elements: + - type: block-layout + label: Config Secret + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret + type: function + elements: + - type: label-element + label: Config Secret + subtitle: Select a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: schema/properties/spec/properties/configuration/properties/configSecret/properties/name + refresh: true + label: Config Secret + loader: + name: getConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/createSecret/properties/status + init: + type: func + value: setValueFromDbDetails|/spec/configSecret/name + watcher: + func: onCreateSecretChange + paths: + - temp/properties/createSecret/properties/status + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|create + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + - type: block-layout + label: Create a New Config Secret + showLabels: true + if: + type: function + name: isCreateSecret + hasButton: + text: Save + hasCancel: cancelCreateSecret + action: createNewConfigSecret + elements: + - type: input + label: Secret Name + schema: temp/properties/createSecret/properties/name + validation: + type: required + - type: array-object-form + label: String Data + schema: temp/properties/createSecret/properties/data + buttonClass: is-light is-outlined + validation: + type: required + elements: + - type: select + label: Key + schema: key + loader: + name: onSelectedSecretChange + watchPaths: + - temp/properties/createSecret/properties/data + validation: + type: required + - type: textarea + label: Value + schema: value + - type: multi-file-editor + editorHeight: 500px + readonly: true + if: + type: function + name: isNotCreateSecret + loader: + name: onNewConfigSecretChange + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + schema: temp/properties/newConfigSecret + - type: block-layout + label: ApplyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig + type: function + elements: + - type: label-element + 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). + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfiguration + refresh: true + label: Configuration + loader: getConfigSecretsforAppyConfig + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|apply + watchPaths: + - temp/properties/selectedConfiguration + - type: multi-file-editor + editorHeight: 500px + schema: temp/properties/applyConfig + loader: + name: setApplyConfig + watchPaths: + - temp/properties/selectedConfiguration + watcher: + func: onApplyconfigChange + paths: + - temp/properties/applyConfig + - type: block-layout + label: Remove + if: + name: ifReconfigurationTypeEqualsTo|remove + type: function + elements: + - type: label-element + label: Remove + subtitle: Selected a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfigurationRemove + refresh: true + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|remove + watchPaths: + - temp/properties/selectedConfigurationRemove + - type: multi-file-editor + editorHeight: 500px + readonly: true + init: + type: func + value: onRemoveConfigChange + watcher: + func: onRemoveConfigChange + paths: + - temp/properties/selectedConfigurationRemove + schema: temp/properties/removeConfig +# common + - type: block-layout + label: OpsRequest Options + showLabels: true + elements: + - type: time-picker + label: Timeout + subtitle: Specify the maximum time allowed for the operation to complete before it times out + schema: 'schema/properties/spec/properties/timeout' + - type: radio + label: Apply + schema: 'schema/properties/spec/properties/apply' + init: + type: func + value: setApplyToIfReady + options: + - text: IfReady (OpsRequest will be applied if database is ready) + value: IfReady + - text: Always (OpsRequest will always be applied) + value: Always diff --git a/charts/opskubedbcom-pgbounceropsrequest-editor/ui/functions.js b/charts/opskubedbcom-pgbounceropsrequest-editor/ui/functions.js index d2d4f75b26..4fb56dd623 100644 --- a/charts/opskubedbcom-pgbounceropsrequest-editor/ui/functions.js +++ b/charts/opskubedbcom-pgbounceropsrequest-editor/ui/functions.js @@ -1,3 +1,4 @@ +const { axios, useOperator, store, useToast } = window.vueHelpers || {} const machines = { 'db.t.micro': { resources: { @@ -304,181 +305,222 @@ const machineList = [ 'db.r.24xlarge', ] -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, - } -} +let machinesFromPreset = [] +let secretArray = [] +const configSecretKeys = ['kubedb-user.ini'] -function returnFalse() { - return false -} +export const useFunc = (model) => { + const route = store.state?.route + const toast = useToast() -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} - -async function getNamespaces({ axios, storeGet }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + const { getValue, storeGet, discriminator, setDiscriminatorValue, commit } = useOperator( + model, + store.state, + ) - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + showAndInitOpsRequestType() + async function fetchJsons({ axios, itemCtx }) { + let ui = {} + let language = {} + let functions = {} + const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart - const resources = (resp && resp.data && resp.data.items) || [] + 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 resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' return { - text: name, - value: name, + ui: ui.data || {}, + language: language.data || {}, + functions, } - }) -} + } + + function returnFalse() { + return false + } -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/namespace') + 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/kubedb.com/v1alpha2/namespaces/${namespace}/pgbouncers`, - { + 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) || [] + const resources = (resp && resp.data && resp.data.items) || [] - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -async function getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) { - 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') + async function getDbs() { + if (storeGet('/route/params/actions')) return [] + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - if (namespace && name) { - const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/pgbouncers/${name}` - const resp = await axios.get(url) + const namespace = getValue(model, '/metadata/namespace') + // watchDependency('model#/metadata/namespace') - setDiscriminatorValue('/dbDetails', resp.data || {}) + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/pgbouncers`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) - return resp.data || {} - } else return {} -} + const resources = (resp && resp.data && resp.data.items) || [] -async function getDbVersions({ axios, storeGet, getValue, discriminator }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 url = `/clusters/${owner}/${cluster}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/kubedb-ui-presets` + 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') - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + if (namespace && name) { + const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/pgbouncers/${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 { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + presetVersions = presets.admin?.databases?.PgBouncer?.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/pgbouncerversions`, + { + 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 allowed = found?.spec?.updateConstraints?.allowlist || [] + 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 filteredPgBouncerVersions = 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.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.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.includes(item.metadata?.name)) && + isVersionWithinConstraints(item.spec?.version, limit) + ) + }) + setDiscriminatorValue('/filteredVersion', filteredPgBouncerVersions) + return filteredPgBouncerVersions.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) - presets.status = String(e.status) + return [] } } - try { - const presetVersions = presets.admin?.databases?.PgBouncer?.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/pgbouncerversions`, - { - params: queryParams, - }, - ) + function getVersionInfo() { + const filteredVersion = getValue(discriminator, '/filteredVersion') + if (filteredVersion.length) return '' - const resources = (resp && resp.data && resp.data.items) || [] + let txt = 'No versions from this list can be selected as the target version: [ ' - 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 allowed = found?.spec?.updateConstraints?.allowlist || [] - 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 filteredPgBouncerVersions = 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.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.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.includes(item.metadata?.name)) && - isVersionWithinConstraints(item.spec?.version, limit) - ) + presetVersions.forEach((v, idx) => { + txt = `${txt}"${v}"` + if (idx !== presetVersions.length - 1) txt = txt + ', ' + else txt = txt + ' ]' }) - return filteredPgBouncerVersions.map((item) => { + return txt + } + + function getVersion() { + return filteredVersion.map((item) => { const name = (item.metadata && item.metadata.name) || '' const specVersion = (item.spec && item.spec.version) || '' return { @@ -486,291 +528,331 @@ async function getDbVersions({ axios, storeGet, getValue, discriminator }) { value: name, } }) - } catch (e) { - console.log(e) - return [] } -} -function versionCompare(v1, v2) { - const arr1 = v1.split('.').map(Number) - const arr2 = v2.split('.').map(Number) + 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 + 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 + if (num1 > num2) return 1 // v1 is higher + if (num1 < num2) return -1 // v2 is higher + } + return 0 // versions are equal } - 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 + 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 } - return true -} -function ifRequestTypeEqualsTo({ model, getValue, watchDependency }, type) { - const selectedType = getValue(model, '/spec/type') - watchDependency('model#/spec/type') + function ifRequestTypeEqualsTo(type) { + const selectedType = getValue(model, '/spec/type') + // watchDependency('model#/spec/type') - return selectedType === type -} + return selectedType === type + } -function onRequestTypeChange({ model, getValue, commit }) { - 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 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', + } -function disableOpsRequest({ itemCtx, discriminator, getValue, watchDependency }) { - if (itemCtx.value === 'HorizontalScaling') { - const dbType = getDbType({ - discriminator, - getValue, - watchDependency, + Object.keys(reqTypeMapping).forEach((key) => { + if (key !== selectedType) commit('wizard/model$delete', `/spec/${reqTypeMapping[key]}`) }) + } - if (dbType === 'Standalone') return true - else return false - } else return false -} + function getDbTls() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') -function getDbTls({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + const { spec } = dbDetails || {} + return spec?.tls || undefined + } - const { spec } = dbDetails || {} - return spec?.tls || undefined -} + function getDbType() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') + const { spec } = dbDetails || {} + const { topology } = spec || {} + if (topology) return 'Topology' + else return 'Combined' + } -function getDbType({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') - const { spec } = dbDetails || {} - const { topology } = spec || {} - if (topology) return 'Topology' - else return 'Combined' -} + function disableOpsRequest() { + if (itemCtx.value === 'HorizontalScaling') { + const dbType = getDbType({ + discriminator, + getValue, + }) -function initNamespace({ route }) { - const { namespace } = route.query || {} - return namespace || null -} + if (dbType === 'Standalone') return true + else return false + } else return false + } -function initDatabaseRef({ route, watchDependency }) { - watchDependency('model#/metadata/namespace') - const { name } = route.params || {} - return name -} + function initNamespace() { + const { namespace } = route.query || {} + return namespace || null + } -function asDatabaseOperation(route) { - return !!route.params.actions -} + function initDatabaseRef() { + // watchDependency('model#/metadata/namespace') + const { name } = route.params || {} + return name + } -function generateOpsRequestNameForClusterUI(getValue, model, route) { - const dbName = getValue(model, '/spec/databaseRef/name') + function asDatabaseOperation() { + return !!route.params.actions + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + function generateOpsRequestNameForClusterUI(getValue, model, route) { + const dbName = getValue(model, '/spec/databaseRef/name') - const resources = route.params.resource || '' - const resource = resources.slice(0, -1) + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' - const opsName = dbName ? dbName : resource - return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` -} + const resources = route.params.resource || '' + const resource = resources.slice(0, -1) -function showAndInitName({ route, commit, getValue, model, watchDependency }) { - watchDependency('model#/spec/type') - watchDependency('model#/spec/databaseRef/name') - const ver = asDatabaseOperation(route) + const opsName = dbName ? dbName : resource + return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + function showAndInitName() { + // watchDependency('model#/spec/type') + // watchDependency('model#/spec/databaseRef/name') + const ver = asDatabaseOperation() - 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, - }) + 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 } - return !ver -} -function showAndInitNamespace({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/metadata/namespace', - value: `${route.query.namespace}`, - force: true, - }) + + function showAndInitNamespace() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/metadata/namespace', + value: `${route.query.namespace}`, + force: true, + }) + } + + return !ver } - return !ver -} -function showAndInitDatabaseRef({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/spec/databaseRef/name', - value: `${route.params.name}`, - force: true, - }) + function showAndInitDatabaseRef() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/spec/databaseRef/name', + value: `${route.params.name}`, + force: true, + }) + } + + return !ver } - return !ver -} -function showConfigureOpsrequestLabel({ route }) { - return !asDatabaseOperation(route) -} -function showAndInitOpsRequestType({ route, commit }) { - const ver = asDatabaseOperation(route) - const opMap = { - upgrade: 'UpdateVersion', - updateVersion: 'UpdateVersion', - horizontalscaling: 'HorizontalScaling', - verticalscaling: 'VerticalScaling', - volumeexpansion: 'VolumeExpansion', - restart: 'Restart', - reconfiguretls: 'ReconfigureTLS', - reconfigure: 'Reconfigure', - } - if (ver) { - const operation = route.params.actions - const match = /^(.*)-opsrequest-(.*)$/.exec(operation) - const opstype = match[2] - commit('wizard/model$update', { - path: '/spec/type', - value: opMap[opstype], - force: true, - }) + function showConfigureOpsrequestLabel() { + return !asDatabaseOperation() } - return !ver -} + 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, + }) + } + } -// vertical scaling -function ifDbTypeEqualsTo({ discriminator, getValue, watchDependency, commit }, value, opsReqType) { - const verd = getDbType({ - discriminator, - getValue, - watchDependency, - }) - return value === verd -} + return !ver + } -// machine profile stuffs -let machinesFromPreset = [] + // vertical scaling + function ifDbTypeEqualsTo(value, opsReqType) { + const verd = getDbType() + return value === verd + } -function getMachines({ storeGet }) { - const presets = storeGet('/kubedbuiPresets') || {} - const avlMachines = presets.admin?.machineProfiles?.available || [] - let arr = [] - if (avlMachines.length) { - arr = avlMachines.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - 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 } - } else return { text: machine, value: machine } - } - }) - } else { - arr = machineList - .map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + // 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 } } + } }) - .filter((val) => !!val) + } 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 } - return arr -} - -function setMachine({ getValue, discriminator, storeGet }) { - const dbDetails = getValue(discriminator, '/dbDetails') - const annotations = dbDetails?.metadata?.annotations || {} - const machine = annotations['kubernetes.io/instance-type'] || 'custom' - machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] + 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'] - const machinePresets = machinesFromPreset.find((item) => item.id === machine) - if (machinePresets) return machine - else return 'custom' -} + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = instance || {} + } -function onMachineChange({ getValue, discriminator, commit, model }, type, valPath) { - let selectedMachine = '' - selectedMachine = getValue(discriminator, '/machine') - const machine = machinesFromPreset.find((item) => item.id === selectedMachine) + const machine = parsedInstance || 'custom' - let obj = {} - if (selectedMachine !== 'custom') { - if (machine) obj = { limits: { ...machine?.limits }, requests: { ...machine?.limits } } - else obj = machines[selectedMachine]?.resources - } else { - const val = getValue(discriminator, `/dbDetails${valPath}`) || {} - obj = Array.isArray(val) ? val[0]?.resources : { ...val } + 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 } } - const path = `/spec/verticalScaling/${type}/resources` + 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 }, + } + } - if (obj && Object.keys(obj).length) - commit('wizard/model$update', { - path: path, - value: obj, - force: true, - }) + const path = `/spec/verticalScaling/${type}/resources` - // update metadata.annotations - const annotations = getValue(model, '/metadata/annotations') || {} - if (selectedMachine === 'custom') commit('wizard/model$delete', '/metadata/annotations') - else { - annotations['kubernetes.io/instance-type'] = selectedMachine + 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', @@ -778,478 +860,920 @@ function onMachineChange({ getValue, discriminator, commit, model }, type, valPa force: true, }) } -} -function isMachineCustom({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/machine') - const machine = getValue(discriminator, '/machine') - return machine === 'custom' -} -// for config secret -async function getConfigSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + function isMachineCustom() { + // watchDependency('discriminator#/machine') + const machine = getValue(discriminator, '/machine') + return machine === 'custom' + } - const secrets = (resp && resp.data && resp.data.items) || [] + // Fetch and store database Infos + // for secret configurations in reconfigure + let configSecrets = [] + let secretConfigData = [] - const filteredSecrets = secrets + 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') - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return filteredSecrets -} + 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') -function createSecretUrl({ storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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.ini'], + }, + }, + ) + configSecrets = resp?.data?.response?.availableSecrets || [] + secretConfigData = resp?.data?.response?.configurations || [] + } catch (e) { + console.log(e) + } + } - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/secrets/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/secrets/create` + 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 } -} -function isEqualToValueFromType({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/valueFromType') - const valueFrom = getValue(discriminator, '/valueFromType') - return valueFrom === value -} + async function getConfigSecretsforAppyConfig() { + const secrets = secretConfigData.map((item) => { + return { text: item.componentName, value: item.componentName } + }) + return secrets + } -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function getSelectedConfigurationData(type) { + type = type ? type + '/' : '' + const path = `/${type}selectedConfiguration` + const selectedConfiguration = getValue(discriminator, path) - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + if (!selectedConfiguration) { + return [] + } - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, + 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, }) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + return result } - return ans -} -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` + const selectedConfiguration = + configType === 'create' ? getValue(model, path) : getValue(discriminator, path) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, + 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 + } }) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + // Convert data object back to YAML string + return yaml.dump(data) } - return ans -} -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - group, - version, - resource, -) { - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/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) - }) + 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])) + + 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 resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + function decodeError(msg, defaultMsg) { + if (typeof msg === 'string') { + return msg || defaultMsg } - }) -} -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) - - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) + return ( + (msg.response && msg.response.data && msg.response.data.message) || + (msg.response && msg.response.data) || + (msg.status && msg.status.status) || + defaultMsg + ) } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + 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 + } -// reconfiguration type -function ifReconfigurationTypeEqualsTo({ discriminator, getValue, watchDependency }, value) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - watchDependency('discriminator#/reconfigurationType') + function isNotCreateSecret(type) { + return !isCreateSecret(type) + } - return reconfigurationType === value -} + 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`) -function onApplyconfigChange({ discriminator, getValue, commit }) { - const applyconfig = getValue(discriminator, '/applyConfig') + const configFound = configSecrets.find((item) => item === name) + return configFound ? { text: name, value: name } : '' + } + } - const configObj = {} - if (applyconfig) { - applyconfig.forEach((item) => { - const { key, value } = item - configObj[key] = value + 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', }) } - commit('wizard/model$update', { - path: '/spec/configuration/applyConfig', - value: configObj, - force: true, - }) -} - -function onReconfigurationTypeChange({ commit, discriminator, getValue, setDiscriminatorValue }) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - setDiscriminatorValue('/applyConfig', []) - if (reconfigurationType === 'remove') { - commit('wizard/model$delete', `/spec/configuration`) + 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) { + 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/pgbouncer/removeCustomConfig`, - value: true, - force: true, + path: `/spec/configuration/${type}applyConfig`, + value: tempConfigObj, }) - } 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({ discriminator, getValue, watchDependency }) { - const tls = getDbTls({ - discriminator, - getValue, - watchDependency, - }) + 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], + }) + }) + } else { + configObj.push({ name: '', content: '' }) + } + return configObj + } - return !!tls -} + function onRemoveConfigChange(type) { + type = type ? type + '/' : '' + const configPath = `/${type}selectedConfigurationRemove` + const selectedConfig = getValue(discriminator, configPath) -function initIssuerRefApiGroup({ getValue, model, watchDependency, discriminator }) { - const kind = getValue(model, '/spec/tls/issuerRef/kind') - watchDependency('model#/spec/tls/issuerRef/kind') + if (!selectedConfig) { + commit('wizard/model$delete', `/spec/configuration/${type}removeCustomConfig`) + return [{ name: '', content: '' }] + } + commit('wizard/model$update', { + path: `/spec/configuration/${type}removeCustomConfig`, + value: true, + }) - if (kind) { - const apiGroup = getValue(discriminator, '/dbDetails/spec/tls/issuerRef/apiGroup') - if (apiGroup) return apiGroup - return 'cert-manager.io' - } else return undefined -} + const configuration = secretConfigData.find((item) => item.componentName === selectedConfig) -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - 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` + if (!configuration.data) { + return [{ name: '', content: '' }] + } - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + const configObj = [] + // Decode base64 and format as array of objects with name and content + Object.keys(configuration.data).forEach((fileName) => { try { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + // Decode base64 string + const decodedString = atob(configuration.data[fileName]) + configObj.push({ + name: fileName, + content: decodedString, + }) } catch (e) { - console.log(e) - presets.status = String(e.status) + 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: '' }] } - let clusterIssuers = presets.admin?.clusterIssuers?.available || [] - if (presets.status === '404') { - const url = `/clusters/${owner}/${cluster}/proxy/cert-manager.io/v1/clusterissuers` - return getIssuer(url) + 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: '' }] } - return clusterIssuers } - async function getIssuer(url) { - try { - const resp = await axios.get(url) - const resources = (resp && resp.data && resp.data.items) || [] + function onSelectedSecretChange(index) { + const secretData = getValue(discriminator, 'createSecret/data') || [] + const selfSecrets = secretData.map((item) => item.key) - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + 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 + } + + 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 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 } }, + }, }) - return resources + + const items = (resp && resp.data && resp.data.items) || [] + ans = items } catch (e) { console.log(e) - return [] } + + return ans } -} + async function getResourceList({ group, version, resource }) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function initTlsOperation() { - return 'update' -} -function onTlsOperationChange({ discriminator, getValue, commit }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` - commit('wizard/model$delete', '/spec/tls') + let ans = [] + try { + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) - if (tlsOperation === 'rotate') { - commit('wizard/model$update', { - path: '/spec/tls/rotateCertificates', - value: true, - force: true, + 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, }) - 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, + + 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, + } }) - commit('wizard/model$delete', '/spec/tls/certificates') - commit('wizard/model$delete', '/spec/tls/rotateCertificates') } -} + async function unNamespacedResourceNames(group, version, resource) { + let resources = await getResourceList({ + group, + version, + resource, + }) -function showIssuerRefAndCertificates({ discriminator, getValue, watchDependency }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') - watchDependency('discriminator#/tlsOperation') - const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } - return verd -} + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -function isIssuerRefRequired({ discriminator, getValue, watchDependency }) { - const hasTls = hasTlsField({ - discriminator, - getValue, - watchDependency, - }) + // reconfiguration type + function ifReconfigurationTypeEqualsTo(value) { + const reconfigurationType = getValue(discriminator, '/reconfigurationType') - return !hasTls -} + const watchPath = 'discriminator#/reconfigurationType' + // watchDependency(watchPath) + return reconfigurationType === value + } -function getRequestTypeFromRoute({ route, model, discriminator, getValue, watchDependency }) { - const isDbloading = isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) - const { query } = route || {} - const { requestType } = query || {} - return isDbloading ? '' : requestType || '' -} + function onReconfigurationTypeChange() { + setDiscriminatorValue('/applyConfig', []) + const reconfigurationType = getValue(discriminator, '/reconfigurationType') + if (reconfigurationType === 'remove') { + commit('wizard/model$delete', `/spec/configuration`) -// ************************************** Set db details ***************************************** + commit('wizard/model$update', { + path: `/spec/configuration/pgbouncer/removeCustomConfig`, + value: true, + force: true, + }) + } else { + commit('wizard/model$delete', `/spec/configuration/pgbouncer/configSecret`) + commit('wizard/model$delete', `/spec/configuration/pgbouncer/applyConfig`) + commit('wizard/model$delete', `/spec/configuration/pgbouncer/removeCustomConfig`) + } + } -function isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - watchDependency('model#/spec/databaseRef/name') - const dbDetails = getValue(discriminator, '/dbDetails') - const dbName = getValue(model, '/spec/databaseRef/name') + // for tls + function hasTlsField() { + const tls = getDbTls() - return !dbDetails || !dbName -} + return !!tls + } + + function initIssuerRefApiGroup() { + const kind = getValue(model, '/spec/tls/issuerRef/kind') + // watchDependency('model#/spec/tls/issuerRef/kind') + + if (kind) { + return 'cert-manager.io' + } else return undefined + } -function setValueFromDbDetails( - { discriminator, getValue, watchDependency, commit }, - path, - commitPath, -) { - watchDependency('discriminator#/dbDetails') + 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') - const retValue = getValue(discriminator, `/dbDetails${path}`) + 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 [] + } - if (commitPath && retValue) { + 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') - // computed called when tls fields is not visible - if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined + commit('wizard/model$delete', '/spec/tls') - // 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, - }) + if (tlsOperation === 'rotate') { + commit('wizard/model$update', { + path: '/spec/tls/rotateCertificates', + value: true, + force: true, + }) + } else if (tlsOperation === 'remove') { + commit('wizard/model$update', { + path: '/spec/tls/remove', + value: true, + force: true, + }) + } } - return retValue || undefined -} + function showIssuerRefAndCertificates() { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // watchDependency('discriminator#/tlsOperation') + const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' -function setResource({ discriminator, getValue, watchDependency }, path) { - watchDependency('discriminator#/dbDetails') - const containers = getValue(discriminator, `/dbDetails${path}`) || [] - // for standalone - if (!containers.length) - return getValue(discriminator, '/dbDetails/spec/podTemplate/spec/resources') || {} + return verd + } - const kind = getValue(discriminator, '/dbDetails/kind') - const resource = containers.filter((ele) => ele.name === kind.toLowerCase()) - return resource[0].resources -} + function isIssuerRefRequired() { + const hasTls = hasTlsField() + return hasTls ? false : '' + } -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} + function getRequestTypeFromRoute() { + const isDbloading = isDbDetailsLoading() + const { query } = route || {} + const { requestType } = query || {} + return isDbloading ? '' : requestType || '' + } -function isNamespaceDisabled({ route }) { - const { namespace } = route.query || {} - return !!namespace -} + function isDbDetailsLoading() { + // watchDependency('discriminator#/dbDetails') + // watchDependency('model#/spec/databaseRef/name') + const dbDetails = getValue(discriminator, '/dbDetails') + const dbName = getValue(model, '/spec/databaseRef/name') -function isDatabaseRefDisabled({ route }) { - const { name } = route.params || {} - return !!name -} + return !dbDetails || !dbName + } -function onNamespaceChange({ commit }) { - commit('wizard/model$delete', '/spec/type') -} + function setValueFromDbDetails(path, commitPath) { + const retValue = getValue(discriminator, `/dbDetails${path}`) -function onDbChange({ commit, axios, storeGet, model, getValue, setDiscriminatorValue }) { - commit('wizard/model$delete', '/spec/type') - getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) -} + if (commitPath) { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // computed called when tls fields is not visible + console.log('tlsOperation', tlsOperation) + console.log('commitPath', commitPath) + if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined -function setApplyToIfReady() { - return 'IfReady' -} + // 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, + }) + } + console.log({ retValue }) + return retValue || undefined + } -function isVerticalScaleTopologyRequired({ watchDependency, getValue, discriminator, commit }) { - watchDependency('discriminator#/topologyKey') - watchDependency('discriminator#/topologyValue') + function setResource(path) { + const containers = getValue(discriminator, `/dbDetails${path}`) || [] + // for standalone + if (!containers.length) + return getValue(discriminator, '/dbDetails/spec/podTemplate/spec/resources') || {} - const key = getValue(discriminator, '/topologyKey') - const value = getValue(discriminator, '/topologyValue') - const path = `/spec/verticalScaling/pgbouncer/topology` + const kind = getValue(discriminator, '/dbDetails/kind') + const resource = containers.filter((ele) => ele.name === kind.toLowerCase()) + return resource[0]?.resources || {} + } - if (key || value) { - commit('wizard/model$update', { - path: path, - value: { key, value }, - force: true, + 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/pgbouncer/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 getSelectedConfigSecret() { + const path = `/spec/configuration/pgbouncer/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() { + const path = `/spec/configuration/pgbouncer/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 true - } else { - commit('wizard/model$delete', path) - return false + 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 } -} -return { - setResource, - fetchJsons, - returnFalse, - getNamespaces, - getDbs, - getDbDetails, - getDbVersions, - ifRequestTypeEqualsTo, - onRequestTypeChange, - getDbTls, - getDbType, - initNamespace, - initDatabaseRef, - isRancherManaged, - showAndInitName, - showAndInitNamespace, - showAndInitDatabaseRef, - showConfigureOpsrequestLabel, - showAndInitOpsRequestType, - - ifDbTypeEqualsTo, - getConfigSecrets, - createSecretUrl, - isEqualToValueFromType, - disableOpsRequest, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - ifReconfigurationTypeEqualsTo, - onReconfigurationTypeChange, - onApplyconfigChange, - hasTlsField, - initIssuerRefApiGroup, - getIssuerRefsName, - initTlsOperation, - onTlsOperationChange, - showIssuerRefAndCertificates, - isIssuerRefRequired, - getRequestTypeFromRoute, - isDbDetailsLoading, - setValueFromDbDetails, - getAliasOptions, - isNamespaceDisabled, - isDatabaseRefDisabled, - onNamespaceChange, - onDbChange, - setApplyToIfReady, - isVerticalScaleTopologyRequired, - getMachines, - setMachine, - onMachineChange, - isMachineCustom, + 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, + }) + } + + return { + setExporter, + onExporterResourceChange, + fetchAliasOptions: getAliasOptions, + isRancherManaged, + fetchJsons, + returnFalse, + getNamespaces, + getDbs, + getDbDetails, + getDbVersions, + getVersionInfo, + isVersionEmpty, + getVersion, + ifRequestTypeEqualsTo, + onRequestTypeChange, + getDbTls, + getDbType, + disableOpsRequest, + initNamespace, + initDatabaseRef, + showAndInitName, + showAndInitNamespace, + showAndInitDatabaseRef, + showConfigureOpsrequestLabel, + showAndInitOpsRequestType, + ifDbTypeEqualsTo, + getConfigSecrets, + createSecretUrl, + getSelectedConfigSecret, + getSelectedConfigSecretValue, + isEqualToValueFromType, + getNamespacedResourceList, + getResourceList, + resourceNames, + unNamespacedResourceNames, + ifReconfigurationTypeEqualsTo, + onReconfigurationTypeChange, + onApplyconfigChange, + hasTlsField, + initIssuerRefApiGroup, + getIssuerRefsName, + initTlsOperation, + onTlsOperationChange, + showIssuerRefAndCertificates, + isIssuerRefRequired, + getRequestTypeFromRoute, + isDbDetailsLoading, + setValueFromDbDetails, + setResource, + getAliasOptions, + isNamespaceDisabled, + isDatabaseRefDisabled, + onDbChange, + onNamespaceChange, + setApplyToIfReady, + isVerticalScaleTopologyRequired, + getMachines, + setMachine, + onMachineChange, + isMachineCustom, + fetchConfigSecrets, + getConfigSecretsforAppyConfig, + getSelectedConfigurationData, + getSelectedConfigurationName, + getSelectedConfigurationValueForRemove, + createNewConfigSecret, + decodeError, + isCreateSecret, + isNotCreateSecret, + onCreateSecretChange, + cancelCreateSecret, + setApplyConfig, + onRemoveConfigChange, + onNewConfigSecretChange, + onSelectedSecretChange, + } } diff --git a/charts/opskubedbcom-pgpoolopsrequest-editor/ui/create-ui.yaml b/charts/opskubedbcom-pgpoolopsrequest-editor/ui/create-ui.yaml index 7dea735f4a..7f44a673a9 100644 --- a/charts/opskubedbcom-pgpoolopsrequest-editor/ui/create-ui.yaml +++ b/charts/opskubedbcom-pgpoolopsrequest-editor/ui/create-ui.yaml @@ -1,368 +1,580 @@ -steps: -- form: - discriminator: - dbDetails: - type: object +type: multi-step-form +step: + - type: single-step-form + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - schema: - $ref: discriminator#/properties/dbDetails - type: input - - if: showAndInitName - label: - text: labels.op_req_name - required: true - schema: - $ref: schema#/properties/metadata/properties/name - type: input - - computed: initNamespace - disabled: isNamespaceDisabled - fetch: getNamespaces - hasGroup: isRancherManaged - if: showAndInitNamespace - label: - text: labels.namespace - onChange: onNamespaceChange - required: true - schema: - $ref: schema#/properties/metadata/properties/namespace - type: select - - computed: initDatabaseRef - disabled: isDatabaseRefDisabled - fetch: getDbs - if: showAndInitDatabaseRef - label: - text: labels.databaseRef - onChange: onDbChange - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/databaseRef/properties/name - type: select - - if: showConfigureOpsrequestLabel - label: - text: labels.config_ops_request - type: label-element - - computed: getRequestTypeFromRoute - disabled: isDbDetailsLoading - hasDescription: true - if: showAndInitOpsRequestType - individualItemDisabilityCheck: disableOpsRequest - label: - text: labels.ops_request_type - onChange: onRequestTypeChange - options: - - description: options.UpdateVersion.description - text: options.UpdateVersion.text - value: UpdateVersion - - description: options.HorizontalScaling.description - text: options.HorizontalScaling.text - value: HorizontalScaling - - description: options.VerticalScaling.description - text: options.VerticalScaling.text - value: VerticalScaling - - description: options.Restart.description - text: options.Restart.text - value: Restart - - description: options.Reconfigure.description - text: options.Reconfigure.text - value: Reconfigure - - description: options.ReconfigureTLS.description - text: options.ReconfigureTLS.text - value: ReconfigureTLS - schema: - $ref: schema#/properties/spec/properties/type - type: radio - - elements: - - computed: setValueFromDbDetails|/spec/version - fetch: getDbVersions - label: - text: labels.targetVersion - schema: - $ref: schema#/properties/spec/properties/updateVersion/properties/targetVersion - type: select - if: ifRequestTypeEqualsTo|UpdateVersion - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/replicas - label: - text: Node - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/node - type: input - if: ifRequestTypeEqualsTo|HorizontalScaling - label: - text: Horizontal Scaling Form - type: single-step-form - - elements: - - discriminator: - machine: - default: "" - type: string +# common + - type: input + label: op_req_name + if: + type: function + name: showAndInitName + validation: + type: required + schema: schema/properties/metadata/properties/name + - type: select + label: Namespace + if: + type: function + name: showAndInitNamespace + init: + type: func + value: initNamespace + disable: isNamespaceDisabled + loader: getNamespaces + validation: + type: required + hasGroup: isRancherManaged + schema: schema/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/metadata/properties/namespace + - type: select + label: Database Ref + if: + type: function + name: showAndInitDatabaseRef + loader: + name: getDbs + watchPaths: + - schema/properties/metadata/properties/namespace + init: + type: func + value: initDatabaseRef + validation: + type: required + disable: isDatabaseRefDisabled + refresh: true + watcher: + paths: + - schema/properties/spec/properties/databaseRef/properties/name + func: onDbChange + schema: schema/properties/spec/properties/databaseRef/properties/name + - type: label-element + label: config_ops_request + if: + type: function + name: showConfigureOpsrequestLabel + - type: radio + label: Type of Ops Request + if: + type: function + name: showAndInitOpsRequestType + 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: 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 + init: + type: func + value: getRequestTypeFromRoute + disable: isDbDetailsLoading + watcher: + func: onRequestTypeChange + paths: + - schema/properties/spec/properties/type + isHorizontal: true + schema: schema/properties/spec/properties/type +# UpdateVersion + - type: block-layout + showLabels: true + label: Version + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|UpdateVersion elements: - - computed: setMachine - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|node|/spec/podTemplate/spec/containers - schema: - $ref: discriminator#/machine - type: select - - if: isMachineCustom - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/resources - type: resource-input-form - - label: - text: Node Selection Policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/nodeSelectionPolicy - type: select - - elements: - - label: - text: key - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/topology/properties/key - type: input - - label: - text: value - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/topology/properties/value - type: input - label: - text: Topology - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/topology - show_label: true - type: single-step-form - label: - text: Node - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|VerticalScaling - type: single-step-form - - elements: - - discriminator: - reconfigurationType: - type: string + - type: select-compare + label: Target Version + subtitle: Select the desired PgPool version to which you want to update your database. + init: + type: func + value: setValueFromDbDetails|/spec/version + loader: getDbVersions + schema: schema/properties/spec/properties/updateVersion/properties/targetVersion + - type: info + label: '' + loader: + name: getVersionInfo + watchPaths: + - temp/properties/filteredVersion + if: + type: function + name: isVersionEmpty +# Horizontal Scale + - type: block-layout + label: Horizontal Scaling Form + showLabels: true + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|HorizontalScaling elements: - - label: - text: labels.reconfigurationType - onChange: onReconfigurationTypeChange - options: - - text: Select New Config Secret - value: selectNewConfigSecret - - text: Apply Config - value: applyConfig - - text: Remove - value: remove - required: true - schema: - $ref: discriminator#/properties/reconfigurationType - type: radio - - elements: - - add_new_button: - label: labels.createConfig - target: _blank - url: - function: createSecretUrl - computed: setValueFromDbDetails|/spec/configSecret/name - fetch: getConfigSecrets - label: - text: labels.configSecret - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret/properties/name - type: select - if: ifReconfigurationTypeEqualsTo|selectNewConfigSecret - label: - text: Configuration config secret - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret - type: single-step-form - - addFormLabel: labels.applyConfig.label - element: - discriminator: - configArray: - emitAs: applyConfig - type: array + - type: horizontal-layout elements: - - label: - text: labels.applyConfig.key - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/key - type: input - - label: - text: labels.applyConfig.value - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/value - type: editor - type: single-step-form - if: ifReconfigurationTypeEqualsTo|applyConfig - label: - text: labels.applyConfig.label - onChange: onApplyconfigChange - required: true - schema: - $ref: discriminator#/properties/applyConfig - tableContents: - - inTableColumn: true - label: - text: labels.applyConfig.key - path: key - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.applyConfig.value - path: value - type: value - typeOfValue: code - type: single-step-form-array - - if: returnFalse - label: - text: labels.removeCustomConfig - schema: - $ref: schema#/properties/spec/properties/configuration/properties/removeCustomConfig - type: switch - label: - text: labels.configuration - schema: - $ref: schema#/properties/spec/properties/configuration - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|Reconfigure - label: - text: Reconfigure Form - type: single-step-form - - discriminator: - tlsOperation: - default: update - type: string - elements: - - computed: initTlsOperation - if: hasTlsField - label: - text: labels.tlsOperation - onChange: onTlsOperationChange - options: - - text: Update - value: update - - text: Rotate - value: rotate - - text: Remove - value: remove - schema: - $ref: discriminator#/properties/tlsOperation - type: radio - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/remove - type: switch - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/rotateCertificates - type: switch - - elements: - - computed: initIssuerRefApiGroup - disabled: true - label: - text: labels.api_group - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup - type: input - - computed: setValueFromDbDetails|/spec/tls/issuerRef/kind - label: - text: labels.kind - options: - - text: Issuer - value: Issuer - - text: ClusterIssuer - value: ClusterIssuer - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/kind - sortable: true - type: select - - allowUserDefinedOption: true - computed: setValueFromDbDetails|/spec/tls/issuerRef/name - fetch: getIssuerRefsName - label: - text: labels.name - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/name - sortable: true - type: select - if: showIssuerRefAndCertificates - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef - type: single-step-form - - alias: reusable_certificates - chart: - name: uibytebuildersdev-component-certificates - version: v0.29.0 - computed: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates - functionCallbacks: - getAliasOptions: - $ref: functions#/getAliasOptions - if: showIssuerRefAndCertificates - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/spec/properties/tls/properties/certificates - type: reusable-element - if: ifRequestTypeEqualsTo|ReconfigureTLS - label: - text: labels.tls - schema: - $ref: schema#/properties/spec/properties/tls - type: single-step-form - - label: - text: labels.timeout - options: - - text: 5 minutes - value: 5m - - text: 10 minutes - value: 10m - - text: 30 minutes - value: 30m - - text: 1 hour - value: 1h - - text: 2 hours - value: 2h - - text: 5 hours - value: 5h - - text: 10 hours - value: 10h - schema: - $ref: schema#/properties/spec/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: labels.apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/spec/properties/apply - type: radio - type: single-step-form - id: basic - title: steps.0.label -type: multi-step-form + - type: input-compare + header: Node + label: Node + subtitle: Define the total number of PgPool nodes for your database. Increasing nodes improves fault tolerance and load distribution, while reducing nodes conserves resources + init: + type: func + value: setValueFromDbDetails|/spec/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/node + - type: info + hasIcon: true + label: Each PgPool node acts as a connection pooler and load balancer. For example, setting this to 3 creates three PgPool instances for better availability and load distribution. +# vertical Scale + - type: block-layout + if: + type: function + name: ifRequestTypeEqualsTo|VerticalScaling + elements: + - type: block-layout + label: Node Vertical Scaling + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines + init: + type: func + value: setMachine + watcher: + func: onMachineChange|node|/spec/podTemplate/spec/containers + paths: + - temp/properties/machine + schema: temp/properties/machine + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/node/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired + schema: temp/topologyKey + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired + schema: temp/topologyValue + - type: block-layout + label: Exporter + showLabels: true + hideBlock: true + elements: + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setExporter|cpu + type: input + 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 + watcher: + func: onExporterResourceChange|memory + paths: + - schema/properties/spec/properties/verticalScaling/properties/exporter/properties/resources/properties/limits/properties/memory +# Reconfigure + - type: block-layout + label: Reconfigure Form + if: + name: ifRequestTypeEqualsTo|Reconfigure + type: function + loader: + name: fetchConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + elements: + - type: block-layout + label: Configuration + elements: + - type: label-element + label: '' + subtitle: Select a new configuration secret, apply a custom configuration, or remove an existing setup to update your database settings + - type: tab-layout + label: New Config Secret + schema: temp/properties/reconfigurationType + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + elements: + - type: block-layout + label: Config Secret + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret + type: function + elements: + - type: label-element + label: Config Secret + subtitle: Select a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: schema/properties/spec/properties/configuration/properties/configSecret/properties/name + refresh: true + label: Config Secret + loader: + name: getConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/createSecret/properties/status + init: + type: func + value: setValueFromDbDetails|/spec/configSecret/name + watcher: + func: onCreateSecretChange + paths: + - temp/properties/createSecret/properties/status + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|create + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + - type: block-layout + label: Create a New Config Secret + showLabels: true + if: + type: function + name: isCreateSecret + hasButton: + text: Save + hasCancel: cancelCreateSecret + action: createNewConfigSecret + elements: + - type: input + label: Secret Name + schema: temp/properties/createSecret/properties/name + validation: + type: required + - type: array-object-form + label: String Data + schema: temp/properties/createSecret/properties/data + buttonClass: is-light is-outlined + validation: + type: required + elements: + - type: select + label: Key + schema: key + loader: + name: onSelectedSecretChange + watchPaths: + - temp/properties/createSecret/properties/data + validation: + type: required + - type: textarea + label: Value + schema: value + - type: multi-file-editor + editorHeight: 500px + readonly: true + if: + type: function + name: isNotCreateSecret + loader: + name: onNewConfigSecretChange + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + schema: temp/properties/newConfigSecret + - type: block-layout + label: ApplyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig + type: function + elements: + - type: label-element + 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). + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfiguration + refresh: true + label: Configuration + loader: getConfigSecretsforAppyConfig + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|apply + watchPaths: + - temp/properties/selectedConfiguration + - type: multi-file-editor + editorHeight: 500px + schema: temp/properties/applyConfig + loader: + name: setApplyConfig + watchPaths: + - temp/properties/selectedConfiguration + watcher: + func: onApplyconfigChange + paths: + - temp/properties/applyConfig + - type: block-layout + label: Remove + if: + name: ifReconfigurationTypeEqualsTo|remove + type: function + elements: + - type: label-element + label: Remove + subtitle: Selected a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfigurationRemove + refresh: true + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|remove + watchPaths: + - temp/properties/selectedConfigurationRemove + - type: multi-file-editor + editorHeight: 500px + readonly: true + init: + type: func + value: onRemoveConfigChange + watcher: + func: onRemoveConfigChange + paths: + - temp/properties/selectedConfigurationRemove + schema: temp/properties/removeConfig +# Reconfigure TLS + - type: block-layout + label: TLS + if: + name: ifRequestTypeEqualsTo|ReconfigureTLS + type: function + elements: + - type: radio + label: TLS Operation + if: + name: hasTlsField + type: function + options: + - text: Update + value: update + - text: Rotate + value: rotate + - text: Remove + value: remove + init: + type: func + value: initTlsOperation + schema: temp/properties/tlsOperation + watcher: + func: onTlsOperationChange + paths: + - temp/properties/tlsOperation + - type: switch + label: Remove TLS + fullwidth: true + if: + name: isTlsEnabled + type: function + schema: schema/properties/spec/properties/tls/properties/remove + - type: switch + label: Rotate Certificates + fullwidth: true + schema: schema/properties/spec/properties/tls/properties/rotateCertificates + if: + name: isTlsEnabled + type: function + - type: block-layout + label: Issuer Reference + showLabels: true + if: + name: showIssuerRefAndCertificates + type: function + elements: + - type: input + label: API Group + init: + type: func + value: initIssuerRefApiGroup + watcher: + func: initIssuerRefApiGroup + paths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + disable: true + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup + - type: select + label: Kind + options: + - text: Issuer + value: Issuer + - text: ClusterIssuer + value: ClusterIssuer + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/kind + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - type: select + label: Name + loader: + name: getIssuerRefsName + watchPaths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - schema/properties/metadata/properties/namespace + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/name + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/name + - type: block-layout + label: Certificates + showLabels: false + if: + name: showIssuerRefAndCertificates + type: function + loader: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates + elements: + - type: array-object-form + label: Certificates + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/tls/properties/certificates + elements: + - type: select + label: Alias + loader: fetchAliasOptions + disable: disableAlias + schema: alias + validation: + type: required + - type: input + label: Secret Name + schema: secretName + - type: input + label: Duration + schema: duration + - type: input + label: Renew Before + schema: renewBefore + - type: array-item-form + label: Organizations + buttonClass: is-light is-outlined + schema: subject/properties/organizations + element: + type: input + label: Organization + - type: array-item-form + label: Countries + buttonClass: is-light is-outlined + schema: subject/properties/countries + element: + type: input + label: Country + - type: array-item-form + label: Organizational Units + buttonClass: is-light is-outlined + schema: subject/properties/organizationalUnits + element: + type: input + label: Organizational Unit + - type: array-item-form + label: Provinces + buttonClass: is-light is-outlined + schema: subject/properties/provinces + element: + type: input + label: Province + - type: array-item-form + label: DNS Names + buttonClass: is-light is-outlined + schema: dnsNames + element: + type: input + label: DNS Name + - type: array-item-form + label: IP Addresses + buttonClass: is-light is-outlined + schema: ipAddresses + element: + type: input + label: IP Address +# common + - type: block-layout + label: OpsRequest Options + showLabels: true + elements: + - type: time-picker + label: Timeout + subtitle: Specify the maximum time allowed for the operation to complete before it times out + schema: 'schema/properties/spec/properties/timeout' + - type: radio + label: Apply + schema: 'schema/properties/spec/properties/apply' + init: + type: func + value: setApplyToIfReady + options: + - text: IfReady (OpsRequest will be applied if database is ready) + value: IfReady + - text: Always (OpsRequest will always be applied) + value: Always diff --git a/charts/opskubedbcom-pgpoolopsrequest-editor/ui/functions.js b/charts/opskubedbcom-pgpoolopsrequest-editor/ui/functions.js index b302f3fcae..11d5268070 100644 --- a/charts/opskubedbcom-pgpoolopsrequest-editor/ui/functions.js +++ b/charts/opskubedbcom-pgpoolopsrequest-editor/ui/functions.js @@ -1,3 +1,4 @@ +const { axios, useOperator, store, useToast } = window.vueHelpers || {} const machines = { 'db.t.micro': { resources: { @@ -304,181 +305,233 @@ const machineList = [ 'db.r.24xlarge', ] -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, - } -} +const configSecretKeys = ['kubedb-user.conf'] +let machinesFromPreset = [] +let secretArray = [] -function returnFalse() { - return false -} +export const useFunc = (model) => { + const route = store.state?.route + const toast = useToast() -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + const { getValue, storeGet, discriminator, setDiscriminatorValue, commit } = useOperator( + model, + store.state, + ) -async function getNamespaces({ axios, storeGet }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + showAndInitOpsRequestType() - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + async function fetchJsons({ axios, itemCtx }) { + let ui = {} + let language = {} + let functions = {} + const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart - const resources = (resp && resp.data && resp.data.items) || [] + 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 resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' return { - text: name, - value: name, + ui: ui.data || {}, + language: language.data || {}, + functions, } - }) -} + } -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function returnFalse() { + return false + } - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/namespace') + function isTlsEnabled() { + const dbDetails = getValue(discriminator, '/dbDetails') + return ( + (dbDetails?.spec?.sslMode && + dbDetails?.spec?.sslMode !== 'disabled' && + dbDetails?.spec?.sslMode !== 'disable') || + dbDetails?.spec?.tls + ) + } - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/pgpools`, - { + 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) || [] - const resources = (resp && resp.data && resp.data.items) || [] + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } - 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}/pgpools`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) -async function getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) { - 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') + const resources = (resp && resp.data && resp.data.items) || [] - if (namespace && name) { - const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/pgpools/${name}` - const resp = await axios.get(url) + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } - setDiscriminatorValue('/dbDetails', resp.data || {}) + async function getDbDetails() { + machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] - return resp.data || {} - } else return {} -} + 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}/pgpools/${name}` + const resp = await axios.get(url) -async function getDbVersions({ axios, storeGet, getValue, discriminator }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + setDiscriminatorValue('/dbDetails', resp.data || {}) - const url = `/clusters/${owner}/${cluster}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/kubedb-ui-presets` + return resp.data || {} + } else return {} + } - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + 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 { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + presetVersions = presets.admin?.databases?.Pgpool?.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/pgpoolversions`, + { + 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 allowed = found?.spec?.updateConstraints?.allowlist || [] + 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 filteredPgpoolVersions = 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.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.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.includes(item.metadata?.name)) && + isVersionWithinConstraints(item.spec?.version, limit) + ) + }) + setDiscriminatorValue('/filteredVersion', filteredPgpoolVersions) + return filteredPgpoolVersions.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) - presets.status = String(e.status) + return [] } } - try { - const presetVersions = presets.admin?.databases?.Pgpool?.versions?.available || [] - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null, updateConstraints: null }, - }, - }, - } + function getVersionInfo() { + const filteredVersion = getValue(discriminator, '/filteredVersion') + if (filteredVersion.length) return '' - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/catalog.kubedb.com/v1alpha1/pgpoolversions`, - { - params: queryParams, - }, - ) + let txt = 'No versions from this list can be selected as the target version: [ ' - 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 allowed = found?.spec?.updateConstraints?.allowlist || [] - 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 filteredPgpoolVersions = 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.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.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.includes(item.metadata?.name)) && - isVersionWithinConstraints(item.spec?.version, limit) - ) + presetVersions.forEach((v, idx) => { + txt = `${txt}"${v}"` + if (idx !== presetVersions.length - 1) txt = txt + ', ' + else txt = txt + ' ]' }) - return filteredPgpoolVersions.map((item) => { + return txt + } + + function getVersion() { + return filteredVersion.map((item) => { const name = (item.metadata && item.metadata.name) || '' const specVersion = (item.spec && item.spec.version) || '' return { @@ -486,767 +539,1284 @@ async function getDbVersions({ axios, storeGet, getValue, discriminator }) { value: name, } }) - } catch (e) { - console.log(e) - return [] } -} -function versionCompare(v1, v2) { - const arr1 = v1.split('.').map(Number) - const arr2 = v2.split('.').map(Number) + 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 + 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 + if (num1 > num2) return 1 // v1 is higher + if (num1 < num2) return -1 // v2 is higher + } + return 0 // versions are equal } - 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 + 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 } - return true -} -function ifRequestTypeEqualsTo({ model, getValue, watchDependency }, type) { - const selectedType = getValue(model, '/spec/type') - watchDependency('model#/spec/type') + function ifRequestTypeEqualsTo(type) { + const selectedType = getValue(model, '/spec/type') + // watchDependency('model#/spec/type') - return selectedType === type -} + return selectedType === type + } -function onRequestTypeChange({ model, getValue, commit }) { - 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 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', + } -function disableOpsRequest({ itemCtx, discriminator, getValue, watchDependency }) { - if (itemCtx.value === 'HorizontalScaling') { - const dbType = getDbType({ - discriminator, - getValue, - watchDependency, + Object.keys(reqTypeMapping).forEach((key) => { + if (key !== selectedType) commit('wizard/model$delete', `/spec/${reqTypeMapping[key]}`) }) + } - if (dbType === 'Standalone') return true - else return false - } else return false -} + function getDbTls() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') -function getDbTls({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + const { spec } = dbDetails || {} + return spec?.tls || undefined + } - const { spec } = dbDetails || {} - return spec?.tls || undefined -} + function getDbType() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') + const { spec } = dbDetails || {} + const { topology } = spec || {} + if (topology) return 'Topology' + else return 'Combined' + } -function getDbType({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') - const { spec } = dbDetails || {} - const { topology } = spec || {} - if (topology) return 'Topology' - else return 'Combined' -} + function disableOpsRequest() { + if (itemCtx.value === 'HorizontalScaling') { + const dbType = getDbType() -function initNamespace({ route }) { - const { namespace } = route.query || {} - return namespace || null -} + if (dbType === 'Standalone') return true + else return false + } else return false + } -function initDatabaseRef({ route, watchDependency }) { - watchDependency('model#/metadata/namespace') - const { name } = route.params || {} - return name -} + function initNamespace() { + const { namespace } = route.query || {} + return namespace || null + } -function asDatabaseOperation(route) { - return !!route.params.actions -} + function initDatabaseRef() { + // watchDependency('model#/metadata/namespace') + const { name } = route.params || {} + return name + } -function generateOpsRequestNameForClusterUI(getValue, model, route) { - const dbName = getValue(model, '/spec/databaseRef/name') + function asDatabaseOperation() { + return !!route.params.actions + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + function generateOpsRequestNameForClusterUI(getValue, model, route) { + const dbName = getValue(model, '/spec/databaseRef/name') - const resources = route.params.resource || '' - const resource = resources.slice(0, -1) + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' - const opsName = dbName ? dbName : resource - return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` -} + const resources = route.params.resource || '' + const resource = resources.slice(0, -1) -function showAndInitName({ route, commit, getValue, model, watchDependency }) { - watchDependency('model#/spec/type') - watchDependency('model#/spec/databaseRef/name') - const ver = asDatabaseOperation(route) + const opsName = dbName ? dbName : resource + return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + function showAndInitName() { + // watchDependency('model#/spec/type') + // watchDependency('model#/spec/databaseRef/name') + const ver = asDatabaseOperation() - 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, - }) + 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 } - return !ver -} -function showAndInitNamespace({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/metadata/namespace', - value: `${route.query.namespace}`, - force: true, - }) + + function showAndInitNamespace() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/metadata/namespace', + value: `${route.query.namespace}`, + force: true, + }) + } + + return !ver } - return !ver -} -function showAndInitDatabaseRef({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/spec/databaseRef/name', - value: `${route.params.name}`, - force: true, - }) + function showAndInitDatabaseRef() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/spec/databaseRef/name', + value: `${route.params.name}`, + force: true, + }) + } + + return !ver } - return !ver -} -function showConfigureOpsrequestLabel({ route }) { - return !asDatabaseOperation(route) -} -function showAndInitOpsRequestType({ route, commit }) { - const ver = asDatabaseOperation(route) - const opMap = { - upgrade: 'UpdateVersion', - updateVersion: 'UpdateVersion', - horizontalscaling: 'HorizontalScaling', - verticalscaling: 'VerticalScaling', - volumeexpansion: 'VolumeExpansion', - restart: 'Restart', - reconfiguretls: 'ReconfigureTLS', - reconfigure: 'Reconfigure', - } - if (ver) { - const operation = route.params.actions - const match = /^(.*)-opsrequest-(.*)$/.exec(operation) - const opstype = match[2] - commit('wizard/model$update', { - path: '/spec/type', - value: opMap[opstype], - force: true, - }) + function showConfigureOpsrequestLabel() { + return !asDatabaseOperation() } - return !ver -} + 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, + }) + } + } -// vertical scaling -function ifDbTypeEqualsTo({ discriminator, getValue, watchDependency, commit }, value, opsReqType) { - const verd = getDbType({ - discriminator, - getValue, - watchDependency, - }) - return value === verd -} + return !ver + } -// machine profile stuffs -let machinesFromPreset = [] + // vertical scaling + function ifDbTypeEqualsTo(value) { + const verd = getDbType() + return value === verd + } -function getMachines({ storeGet }) { - const presets = storeGet('/kubedbuiPresets') || {} - const avlMachines = presets.admin?.machineProfiles?.available || [] - let arr = [] - if (avlMachines.length) { - arr = avlMachines.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - 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 } - } else return { text: machine, value: machine } - } - }) - } else { - arr = machineList - .map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + // machine profile stuffs + + function getMachines() { + const presets = storeGet('/kubedbuiPresets') || {} + const dbDetails = getValue(discriminator, '/dbDetails') + const containers = dbDetails?.spec?.podTemplate?.spec?.containers || [] + const kind = dbDetails?.kind + const resource = containers.filter((ele) => ele.name === kind?.toLowerCase()) + const limits = resource[0]?.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 } } + } }) - .filter((val) => !!val) + } 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 } - return arr -} - -function setMachine({ getValue, discriminator, storeGet }) { - const dbDetails = getValue(discriminator, '/dbDetails') - const annotations = dbDetails?.metadata?.annotations || {} - const machine = annotations['kubernetes.io/instance-type'] || 'custom' - machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] + function setMachine() { + const dbDetails = getValue(discriminator, '/dbDetails') + const containers = dbDetails?.spec?.podTemplate?.spec?.containers || [] + const kind = dbDetails?.kind + const resource = containers.filter((ele) => ele.name === kind?.toLowerCase()) + const limits = resource[0]?.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 - else return '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({ getValue, discriminator, commit, model }, type, valPath) { - let selectedMachine = '' - selectedMachine = getValue(discriminator, '/machine') - const machine = machinesFromPreset.find((item) => item.id === selectedMachine) + 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 }, + } + } - let obj = {} - if (selectedMachine !== 'custom') { - if (machine) obj = { limits: { ...machine?.limits }, requests: { ...machine?.limits } } - else obj = machines[selectedMachine]?.resources - } else { - const val = getValue(discriminator, `/dbDetails${valPath}`) || {} - obj = Array.isArray(val) ? val[0]?.resources : { ...val } - } + const path = `/spec/verticalScaling/${type}/resources` - const path = `/spec/verticalScaling/${type}/resources` + if (obj && Object.keys(obj).length) + commit('wizard/model$update', { + path: path, + value: obj, + force: true, + }) - 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') || {} + const instance = annotations['kubernetes.io/instance-type'] + let parsedInstance = {} + try { + if (instance) parsedInstance = instance + } catch (e) { + console.log(e) + parsedInstance = {} + } + parsedInstance = selectedMachine.machine + annotations['kubernetes.io/instance-type'] = JSON.stringify(parsedInstance) - // update metadata.annotations - const annotations = getValue(model, '/metadata/annotations') || {} - if (selectedMachine === 'custom') commit('wizard/model$delete', '/metadata/annotations') - else { - annotations['kubernetes.io/instance-type'] = selectedMachine if (machinesFromPreset.length) commit('wizard/model$update', { path: '/metadata/annotations', value: annotations, force: true, }) + + if (!parsedInstance) commit('wizard/model$delete', '/metadata/annotations') } -} -function isMachineCustom({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/machine') - const machine = getValue(discriminator, '/machine') - return machine === 'custom' -} + function isMachineCustom() { + // watchDependency('discriminator#/machine') + const machine = getValue(discriminator, '/machine') + return machine === 'custom' + } -// for config secret -async function getConfigSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + // Fetch and store database Infos + // for secret configurations in reconfigure + let configSecrets = [] + let secretConfigData = [] - const secrets = (resp && resp.data && resp.data.items) || [] + 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 filteredSecrets = secrets + 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') - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return filteredSecrets -} + 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.conf'], + }, + }, + ) + configSecrets = resp?.data?.response?.availableSecrets || [] + secretConfigData = resp?.data?.response?.configurations || [] + } catch (e) { + console.log(e) + } + } -function createSecretUrl({ storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 + } - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/secrets/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/secrets/create` + async function getConfigSecretsforAppyConfig() { + const secrets = secretConfigData.map((item) => { + return { text: item.componentName, value: item.componentName } + }) + return secrets } -} -function isEqualToValueFromType({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/valueFromType') - const valueFrom = getValue(discriminator, '/valueFromType') - return valueFrom === value -} + function getSelectedConfigurationData(type) { + type = type ? type + '/' : '' + const path = `/${type}selectedConfiguration` + const selectedConfiguration = getValue(discriminator, path) -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + if (!selectedConfiguration) { + return [] + } - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + const configuration = secretConfigData.find( + (item) => item.componentName === selectedConfiguration, + ) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, + 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 + }) + } }) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + // Set the value to the model + commit('wizard/model$update', { + path: `/temp/${type}applyConfig`, + value: result, + force: true, + }) + + return result } - return ans -} -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` + const selectedConfiguration = + configType === 'create' ? getValue(model, path) : getValue(discriminator, path) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, + 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 + } }) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + // Convert data object back to YAML string + return yaml.dump(data) } - return ans -} -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - group, - version, - resource, -) { - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/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) - }) + 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])) + + 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 resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + function decodeError(msg, defaultMsg) { + if (typeof msg === 'string') { + return msg || defaultMsg } - }) -} -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) - - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) + return ( + (msg.response && msg.response.data && msg.response.data.message) || + (msg.response && msg.response.data) || + (msg.status && msg.status.status) || + defaultMsg + ) } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + 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 + } -// reconfiguration type -function ifReconfigurationTypeEqualsTo({ discriminator, getValue, watchDependency }, value) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - watchDependency('discriminator#/reconfigurationType') + function isNotCreateSecret(type) { + return !isCreateSecret(type) + } - return reconfigurationType === value -} + 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`) -function onApplyconfigChange({ discriminator, getValue, commit }) { - const applyconfig = getValue(discriminator, '/applyConfig') + const configFound = configSecrets.find((item) => item === name) + return configFound ? { text: name, value: name } : '' + } + } - const configObj = {} - if (applyconfig) { - applyconfig.forEach((item) => { - const { key, value } = item - configObj[key] = value + 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', }) } - commit('wizard/model$update', { - path: '/spec/configuration/applyConfig', - value: configObj, - force: true, - }) -} - -function onReconfigurationTypeChange({ commit, discriminator, getValue, setDiscriminatorValue }) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - setDiscriminatorValue('/applyConfig', []) - if (reconfigurationType === 'remove') { - commit('wizard/model$delete', `/spec/configuration`) + 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) { + 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/removeCustomConfig`, - value: true, - force: true, + path: `/spec/configuration/${type}applyConfig`, + value: tempConfigObj, }) - } 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({ discriminator, getValue, watchDependency }) { - const tls = getDbTls({ - discriminator, - getValue, - watchDependency, - }) + 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], + }) + }) + } else { + configObj.push({ name: '', content: '' }) + } + return configObj + } - return !!tls -} + function onRemoveConfigChange(type) { + type = type ? type + '/' : '' + const configPath = `/${type}selectedConfigurationRemove` + const selectedConfig = getValue(discriminator, configPath) -function initIssuerRefApiGroup({ getValue, model, watchDependency, discriminator }) { - const kind = getValue(model, '/spec/tls/issuerRef/kind') - watchDependency('model#/spec/tls/issuerRef/kind') + if (!selectedConfig) { + commit('wizard/model$delete', `/spec/configuration/${type}removeCustomConfig`) + return [{ name: '', content: '' }] + } + commit('wizard/model$update', { + path: `/spec/configuration/${type}removeCustomConfig`, + value: true, + }) - if (kind) { - const apiGroup = getValue(discriminator, '/dbDetails/spec/tls/issuerRef/apiGroup') - if (apiGroup) return apiGroup - return 'cert-manager.io' - } else return undefined -} + const configuration = secretConfigData.find((item) => item.componentName === selectedConfig) -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - 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` + if (!configuration.data) { + return [{ name: '', content: '' }] + } - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + const configObj = [] + // Decode base64 and format as array of objects with name and content + Object.keys(configuration.data).forEach((fileName) => { try { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + // Decode base64 string + const decodedString = atob(configuration.data[fileName]) + configObj.push({ + name: fileName, + content: decodedString, + }) } catch (e) { - console.log(e) - presets.status = String(e.status) + 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: '' }] } - let clusterIssuers = presets.admin?.clusterIssuers?.available || [] - if (presets.status === '404') { - const url = `/clusters/${owner}/${cluster}/proxy/cert-manager.io/v1/clusterissuers` - return getIssuer(url) + 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: '' }] } - return clusterIssuers } - async function getIssuer(url) { + 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 + } + + function isConfigSelected() { + const secretName = getValue(model, '/spec/configuration/configSecret/name') + return !!secretName + } + + function getSelectedConfigSecret() { + const path = `/spec/configuration/configSecret/name` + const selectedSecret = getValue(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() { + 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 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 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) - const resources = (resp && resp.data && resp.data.items) || [] + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + 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 } }, + }, }) - return resources + + const items = (resp && resp.data && resp.data.items) || [] + ans = items } catch (e) { console.log(e) - return [] } + + return ans } -} -function initTlsOperation() { - return 'update' -} -function onTlsOperationChange({ discriminator, getValue, commit }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + async function resourceNames(group, version, resource) { + const namespace = getValue(model, '/metadata/namespace') + // watchDependency('model#/metadata/namespace') - commit('wizard/model$delete', '/spec/tls') + let resources = await getNamespacedResourceList({ + namespace, + group, + version, + resource, + }) - if (tlsOperation === 'rotate') { - commit('wizard/model$update', { - path: '/spec/tls/rotateCertificates', - value: true, - force: true, + 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, + } }) - 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, + } + + 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, + } }) - commit('wizard/model$delete', '/spec/tls/certificates') - commit('wizard/model$delete', '/spec/tls/rotateCertificates') } -} -function showIssuerRefAndCertificates({ discriminator, getValue, watchDependency }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') - watchDependency('discriminator#/tlsOperation') - const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' + // reconfiguration type + function ifReconfigurationTypeEqualsTo(value) { + const reconfigurationType = getValue(discriminator, '/reconfigurationType') + // watchDependency('discriminator#/reconfigurationType') - return verd -} + return reconfigurationType === value + } -function isIssuerRefRequired({ discriminator, getValue, watchDependency }) { - const hasTls = hasTlsField({ - discriminator, - getValue, - watchDependency, - }) + function onReconfigurationTypeChange() { + const reconfigurationType = getValue(discriminator, '/reconfigurationType') + setDiscriminatorValue('/applyConfig', []) + if (reconfigurationType === 'remove') { + commit('wizard/model$delete', `/spec/configuration`) - return !hasTls -} + 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`) + } + } -function getRequestTypeFromRoute({ route, model, discriminator, getValue, watchDependency }) { - const isDbloading = isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) - const { query } = route || {} - const { requestType } = query || {} - return isDbloading ? '' : requestType || '' -} + // for tls + function hasTlsField() { + const tls = getDbTls() -// ************************************** Set db details ***************************************** + return !!tls + } -function isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - watchDependency('model#/spec/databaseRef/name') - const dbDetails = getValue(discriminator, '/dbDetails') - const dbName = getValue(model, '/spec/databaseRef/name') + function initIssuerRefApiGroup() { + const kind = getValue(model, '/spec/tls/issuerRef/kind') + // watchDependency('model#/spec/tls/issuerRef/kind') - return !dbDetails || !dbName -} + if (kind) { + const apiGroup = getValue(discriminator, '/dbDetails/spec/tls/issuerRef/apiGroup') + if (apiGroup) return apiGroup + return 'cert-manager.io' + } else return undefined + } -function setValueFromDbDetails( - { discriminator, getValue, watchDependency, commit }, - path, - commitPath, -) { - watchDependency('discriminator#/dbDetails') + 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') - const retValue = getValue(discriminator, `/dbDetails${path}`) + 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 [] + } - if (commitPath && retValue) { + 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') - // computed called when tls fields is not visible - if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined + commit('wizard/model$delete', '/spec/tls') - // 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, - }) + if (tlsOperation === 'rotate') { + commit('wizard/model$update', { + path: '/spec/tls/rotateCertificates', + value: true, + force: true, + }) + } else if (tlsOperation === 'remove') { + commit('wizard/model$update', { + path: '/spec/tls/remove', + value: true, + force: true, + }) + } } - return retValue || undefined -} + function showIssuerRefAndCertificates() { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // watchDependency('discriminator#/tlsOperation') + const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' -function setResource({ discriminator, getValue, watchDependency, storeGet }, path) { - watchDependency('discriminator#/dbDetails') - const containers = getValue(discriminator, `/dbDetails${path}`) || [] - const kind = getValue(discriminator, '/dbDetails/kind') - const resource = containers.filter((ele) => ele.name === kind.toLowerCase()) - return resource[0].resources -} + return verd + } -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} + function isIssuerRefRequired() { + const hasTls = hasTlsField() + return hasTls ? false : '' + } -function isNamespaceDisabled({ route }) { - const { namespace } = route.query || {} - return !!namespace -} + function getRequestTypeFromRoute() { + const isDbloading = isDbDetailsLoading() + const { query } = route || {} + const { requestType } = query || {} + return isDbloading ? '' : requestType || '' + } -function isDatabaseRefDisabled({ route }) { - const { name } = route.params || {} - return !!name -} + function isDbDetailsLoading() { + // watchDependency('discriminator#/dbDetails') + // watchDependency('model#/spec/databaseRef/name') + const dbDetails = getValue(discriminator, '/dbDetails') + const dbName = getValue(model, '/spec/databaseRef/name') -function onNamespaceChange({ commit }) { - commit('wizard/model$delete', '/spec/type') -} + return !dbDetails || !dbName + } -function onDbChange({ commit, axios, storeGet, model, getValue, setDiscriminatorValue }) { - commit('wizard/model$delete', '/spec/type') - getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) -} + function setValueFromDbDetails(path, commitPath) { + // watchDependency('discriminator#/dbDetails') -function setApplyToIfReady() { - return 'IfReady' -} + const retValue = getValue(discriminator, `/dbDetails${path}`) -function isVerticalScaleTopologyRequired({ watchDependency, getValue, discriminator, commit }) { - watchDependency('discriminator#/topologyKey') - watchDependency('discriminator#/topologyValue') + if (commitPath && retValue) { + const tlsOperation = getValue(discriminator, '/tlsOperation') - const key = getValue(discriminator, '/topologyKey') - const value = getValue(discriminator, '/topologyValue') - const path = `/spec/verticalScaling/pgpool/topology` + // computed called when tls fields is not visible + if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined - if (key || value) { - commit('wizard/model$update', { - path: path, - value: { key, value }, - force: true, - }) - return true - } else { - commit('wizard/model$delete', path) - return false + // 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 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' } -} -return { - setResource, - fetchJsons, - returnFalse, - getNamespaces, - getDbs, - getDbDetails, - getDbVersions, - ifRequestTypeEqualsTo, - onRequestTypeChange, - getDbTls, - getDbType, - initNamespace, - initDatabaseRef, - isRancherManaged, - showAndInitName, - showAndInitNamespace, - showAndInitDatabaseRef, - showConfigureOpsrequestLabel, - showAndInitOpsRequestType, - - ifDbTypeEqualsTo, - getConfigSecrets, - createSecretUrl, - isEqualToValueFromType, - disableOpsRequest, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - ifReconfigurationTypeEqualsTo, - onReconfigurationTypeChange, - onApplyconfigChange, - hasTlsField, - initIssuerRefApiGroup, - getIssuerRefsName, - initTlsOperation, - onTlsOperationChange, - showIssuerRefAndCertificates, - isIssuerRefRequired, - getRequestTypeFromRoute, - isDbDetailsLoading, - setValueFromDbDetails, - getAliasOptions, - isNamespaceDisabled, - isDatabaseRefDisabled, - onNamespaceChange, - onDbChange, - setApplyToIfReady, - isVerticalScaleTopologyRequired, - getMachines, - setMachine, - onMachineChange, - isMachineCustom, + function isVerticalScaleTopologyRequired() { + // watchDependency('discriminator#/topologyKey') + // watchDependency('discriminator#/topologyValue') + + const key = getValue(discriminator, '/topologyKey') + const value = getValue(discriminator, '/topologyValue') + const path = `/spec/verticalScaling/node/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 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 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, + }) + } + + return { + setExporter, + onExporterResourceChange, + fetchAliasOptions, + validateNewCertificates, + disableAlias, + fetchJsons, + returnFalse, + getNamespaces, + getDbs, + getDbDetails, + getDbVersions, + getVersionInfo, + isVersionEmpty, + getVersion, + ifRequestTypeEqualsTo, + onRequestTypeChange, + getDbTls, + getDbType, + initNamespace, + initDatabaseRef, + isRancherManaged, + showAndInitName, + showAndInitNamespace, + showAndInitDatabaseRef, + showConfigureOpsrequestLabel, + showAndInitOpsRequestType, + ifDbTypeEqualsTo, + getConfigSecrets, + isConfigSelected, + getSelectedConfigSecret, + getSelectedConfigSecretValue, + createSecretUrl, + isEqualToValueFromType, + disableOpsRequest, + getNamespacedResourceList, + getResourceList, + resourceNames, + unNamespacedResourceNames, + ifReconfigurationTypeEqualsTo, + onReconfigurationTypeChange, + onApplyconfigChange, + hasTlsField, + initIssuerRefApiGroup, + getIssuerRefsName, + initTlsOperation, + onTlsOperationChange, + showIssuerRefAndCertificates, + isIssuerRefRequired, + getRequestTypeFromRoute, + isDbDetailsLoading, + setValueFromDbDetails, + getAliasOptions, + isNamespaceDisabled, + isDatabaseRefDisabled, + onNamespaceChange, + onDbChange, + setApplyToIfReady, + isVerticalScaleTopologyRequired, + getMachines, + setMachine, + onMachineChange, + isMachineCustom, + objectToYaml, + fetchConfigSecrets, + getConfigSecretsforAppyConfig, + getSelectedConfigurationData, + getSelectedConfigurationName, + getSelectedConfigurationValueForRemove, + createNewConfigSecret, + decodeError, + isCreateSecret, + isNotCreateSecret, + onCreateSecretChange, + cancelCreateSecret, + setApplyConfig, + onRemoveConfigChange, + onNewConfigSecretChange, + onSelectedSecretChange, + isTlsEnabled, + } } diff --git a/charts/opskubedbcom-postgresopsrequest-editor/ui/create-ui.yaml b/charts/opskubedbcom-postgresopsrequest-editor/ui/create-ui.yaml index 1bd4fbed63..90b45f887d 100644 --- a/charts/opskubedbcom-postgresopsrequest-editor/ui/create-ui.yaml +++ b/charts/opskubedbcom-postgresopsrequest-editor/ui/create-ui.yaml @@ -1,435 +1,658 @@ -steps: -- form: - discriminator: - dbDetails: - type: object +type: multi-step-form +step: + - type: single-step-form + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - schema: - $ref: discriminator#/properties/dbDetails - type: input - - if: showAndInitName - label: - text: labels.op_req_name - required: true - schema: - $ref: schema#/properties/metadata/properties/name - type: input - - computed: initNamespace - disabled: isNamespaceDisabled - fetch: getNamespaces - hasGroup: isRancherManaged - if: showAndInitNamespace - label: - text: labels.namespace - onChange: onNamespaceChange - required: true - schema: - $ref: schema#/properties/metadata/properties/namespace - type: select - - computed: initDatabaseRef - disabled: isDatabaseRefDisabled - fetch: getDbs - if: showAndInitDatabaseRef - label: - text: labels.databaseRef - onChange: onDbChange - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/databaseRef/properties/name - type: select - - if: showConfigureOpsrequestLabel - label: - text: labels.config_ops_request - type: label-element - - computed: getRequestTypeFromRoute - disabled: isDbDetailsLoading - hasDescription: true - if: showAndInitOpsRequestType - individualItemDisabilityCheck: disableOpsRequest - label: - text: labels.ops_request_type - onChange: onRequestTypeChange - options: - - description: options.UpdateVersion.description - text: options.UpdateVersion.text - value: UpdateVersion - - description: options.HorizontalScaling.description - text: options.HorizontalScaling.text - value: HorizontalScaling - - description: options.VerticalScaling.description - text: options.VerticalScaling.text - value: VerticalScaling - - description: options.VolumeExpansion.description - text: options.VolumeExpansion.text - value: VolumeExpansion - - description: options.Restart.description - text: options.Restart.text - value: Restart - - description: options.Reconfigure.description - text: options.Reconfigure.text - value: Reconfigure - - description: options.ReconfigureTLS.description - text: options.ReconfigureTLS.text - value: ReconfigureTLS - schema: - $ref: schema#/properties/spec/properties/type - type: radio - - elements: - - computed: setValueFromDbDetails|/spec/version - fetch: getDbVersions - label: - text: labels.targetVersion - schema: - $ref: schema#/properties/spec/properties/updateVersion/properties/targetVersion - type: select - if: ifRequestTypeEqualsTo|UpdateVersion - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/replicas - if: ifDbTypeEqualsTo|cluster|horizontalScaling - label: - text: labels.replicas - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/replicas - type: input - if: ifRequestTypeEqualsTo|HorizontalScaling - label: - text: Horizontal Scaling Form - type: single-step-form - - elements: - - elements: - - discriminator: - machine: - default: "" - type: string - elements: - - computed: setMachine - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|postgres|/spec/podTemplate/spec/resources - schema: - $ref: discriminator#/machine - type: select - - if: isMachineCustom - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/postgres/properties/resources - type: resource-input-form - - label: - text: labels.node_selection_policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/postgres/properties/nodeSelectionPolicy - type: select - - discriminator: - topologyKey: - default: "" - type: string - topologyValue: - default: "" - type: string - elements: - - label: - text: labels.key - required: isVerticalScaleTopologyRequired - schema: - $ref: discriminator#/topologyKey - type: input - - label: - text: labels.value - required: isVerticalScaleTopologyRequired - schema: - $ref: discriminator#/topologyValue - type: input - label: - text: labels.topology - show_label: true - type: single-step-form - label: - text: labels.postgres - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/postgres - show_label: true - type: single-step-form - - computed: setValueFromDbDetails|/spec/monitor/prometheus/exporter/resources|/spec/verticalScaling/exporter/resources - label: - text: labels.exporter - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/exporter/properties/resources - type: resource-input-form - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/postgres - type: single-step-form - if: ifRequestTypeEqualsTo|VerticalScaling - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/storage/resources/requests/storage - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/postgres - type: input - validationRuleObject: - func: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/postgres - - label: - text: Mode +# common + - type: input + label: op_req_name + if: + type: function + name: showAndInitName + validation: + type: required + schema: schema/properties/metadata/properties/name + - type: select + label: Namespace + if: + type: function + name: showAndInitNamespace + init: + type: func + value: initNamespace + disable: isNamespaceDisabled + loader: getNamespaces + validation: + type: required + hasGroup: isRancherManaged + schema: schema/properties/metadata/properties/namespace + - type: select + label: Database Ref + if: + type: function + name: showAndInitDatabaseRef + loader: + name: getDbs + watchPaths: + - schema/properties/metadata/properties/namespace + init: + type: func + value: initDatabaseRef + validation: + type: required + disable: isDatabaseRefDisabled + refresh: true + watcher: + func: onDbChange + paths: + - schema/properties/spec/properties/databaseRef/properties/name + schema: schema/properties/spec/properties/databaseRef/properties/name + - type: label-element + label: config_ops_request + if: + type: function + name: showConfigureOpsrequestLabel + - type: radio + label: Type of Ops Request + if: + type: function + name: showAndInitOpsRequestType options: - - text: Offline - value: Offline - - text: Online - value: Online - required: true - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/mode - type: select - if: ifRequestTypeEqualsTo|VolumeExpansion - label: - text: Volume Expansion Form - type: single-step-form - - elements: - - discriminator: - reconfigurationType: - type: string + - 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 + init: + type: func + value: getRequestTypeFromRoute + disable: isDbDetailsLoading + watcher: + func: isDbDetailsLoading + paths: + - temp/dbDetails + - schema/properties/spec/properties/databaseRef/properties/name + isHorizontal: true + schema: schema/properties/spec/properties/type +# UpdateVersion + - type: block-layout + showLabels: true + label: Version + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|UpdateVersion elements: - - label: - text: labels.reconfigurationType - onChange: onReconfigurationTypeChange - options: - - text: Select New Config Secret - value: selectNewConfigSecret - - text: Apply Config - value: applyConfig - - text: Remove - value: remove - required: true - schema: - $ref: discriminator#/properties/reconfigurationType - type: radio - - elements: - - add_new_button: - label: labels.createConfig - target: _blank - url: - function: createSecretUrl - computed: setValueFromDbDetails|/spec/configSecret/name - fetch: getConfigSecrets - label: - text: labels.configSecret - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret/properties/name - type: select - if: ifReconfigurationTypeEqualsTo|selectNewConfigSecret - label: - text: Configuration config secret - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret - type: single-step-form - - addFormLabel: labels.applyConfig.label - element: - discriminator: - configArray: - emitAs: applyConfig - type: array + - type: select-compare + label: Target Version + subtitle: Select the desired Postgres version to which you want to update your database. + init: + type: func + value: setValueFromDbDetails|/spec/version + loader: getDbVersions + schema: schema/properties/spec/properties/updateVersion/properties/targetVersion + - type: info + label: '' + loader: + name: getVersionInfo + watchPaths: + - temp/properties/filteredVersion + if: + type: function + name: isVersionEmpty +# Horizontal Scale + - type: block-layout + label: Horizontal Scaling Form + showLabels: true + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|HorizontalScaling + elements: + - type: horizontal-layout + if: + type: function + name: ifDbTypeEqualsTo|cluster|horizontalScaling elements: - - label: - text: labels.applyConfig.key - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/key - type: input - - label: - text: labels.applyConfig.value - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/value - type: editor - type: single-step-form - if: ifReconfigurationTypeEqualsTo|applyConfig - label: - text: labels.applyConfig.label - onChange: onApplyconfigChange - required: true - schema: - $ref: discriminator#/properties/applyConfig - tableContents: - - inTableColumn: true - label: - text: labels.applyConfig.key - path: key - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.applyConfig.value - path: value - type: value - typeOfValue: code - type: single-step-form-array - - if: returnFalse - label: - text: labels.removeCustomConfig - schema: - $ref: schema#/properties/spec/properties/configuration/properties/removeCustomConfig - type: switch - label: - text: labels.configuration - schema: - $ref: schema#/properties/spec/properties/configuration - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|Reconfigure - label: - text: Reconfigure Form - type: single-step-form - - discriminator: - tlsOperation: - default: update - type: string - elements: - - computed: initTlsOperation - if: hasTlsField - label: - text: labels.tlsOperation - onChange: onTlsOperationChange - options: - - text: Update - value: update - - text: Rotate - value: rotate - - text: Remove - value: remove - schema: - $ref: discriminator#/properties/tlsOperation - type: radio - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/remove - type: switch - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/rotateCertificates - type: switch - - computed: setClientAuthMode - fetch: getClientAuthModes - label: - text: labels.client_auth_mode - schema: - $ref: schema#/properties/spec/properties/tls/properties/clientAuthMode - type: radio - - elements: - - computed: setSSLMode - label: - text: labels.ssl_mode - options: - - text: allow - value: allow - - text: prefer - value: prefer - - text: require - value: require - - text: verify-ca - value: verify-ca - - text: verify-full - value: verify-full - schema: - $ref: schema#/properties/spec/properties/tls/properties/sslMode - type: radio - - computed: initIssuerRefApiGroup - disabled: true - label: - text: labels.api_group - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup - type: input - - computed: setValueFromDbDetails|/spec/tls/issuerRef/kind - label: - text: labels.kind - options: - - text: Issuer - value: Issuer - - text: ClusterIssuer - value: ClusterIssuer - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/kind - type: select - - allowUserDefinedOption: true - computed: setValueFromDbDetails|/spec/tls/issuerRef/name - fetch: getIssuerRefsName - label: - text: labels.name - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/name - type: select - if: showIssuerRefAndCertificates - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef - type: single-step-form - - alias: reusable_certificates - chart: - name: uibytebuildersdev-component-certificates - version: v0.29.0 - computed: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates - functionCallbacks: - getAliasOptions: - $ref: functions#/getAliasOptions - if: showIssuerRefAndCertificates - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/spec/properties/tls/properties/certificates - type: reusable-element - if: ifRequestTypeEqualsTo|ReconfigureTLS - label: - text: labels.tls - schema: - $ref: schema#/properties/spec/properties/tls - type: single-step-form - - label: - text: labels.timeout - options: - - text: 5 minutes - value: 5m - - text: 10 minutes - value: 10m - - text: 30 minutes - value: 30m - - text: 1 hour - value: 1h - - text: 2 hours - value: 2h - - text: 5 hours - value: 5h - - text: 10 hours - value: 10h - schema: - $ref: schema#/properties/spec/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: labels.apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/spec/properties/apply - type: radio - type: single-step-form - id: basic - title: steps.0.label -type: multi-step-form + - type: input-compare + label: Replicas + header: Replica + subtitle: Define the total number of replicas for the database. Increasing replicas improves fault tolerance and load distribution , while reducing replicas conserves resources + init: + type: func + value: setValueFromDbDetails|/spec/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/replicas + - type: info + 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. +# vertical Scale + - type: block-layout + if: + type: function + name: ifRequestTypeEqualsTo|VerticalScaling + elements: + - type: block-layout + label: Postgres Vertical Scaling + showLabels: false + elements: + - type: machine-compare + label: Resources + loader: getMachines + init: + type: func + value: setMachine + watcher: + func: onMachineChange|postgres|/spec/podTemplate/spec/resources + paths: + - temp/properties/machine + schema: temp/properties/machine + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/postgres/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired + schema: temp/topologyKey + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired + schema: temp/topologyValue + - type: block-layout + label: Exporter + showLabels: true + hideBlock: true + elements: + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setExporter|cpu + type: input + 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 + watcher: + func: onExporterResourceChange|memory + paths: + - schema/properties/spec/properties/verticalScaling/properties/exporter/properties/resources/properties/limits/properties/memory +# Volume Expansion + - type: block-layout + label: Volume Expansion Form + if: + type: function + name: ifRequestTypeEqualsTo|VolumeExpansion + elements: + - type: horizontal-layout + elements: + - type: block-layout + elements: + - type: label-element + 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: select + label: Mode + options: + - text: Offline + value: Offline + - text: Online + value: Online + validation: + type: required + schema: schema/properties/spec/properties/volumeExpansion/properties/mode + - type: block-layout + label: Postgres volume expansion + showLabels: true + fixedBlock: true + elements: + - type: horizontal-layout + elements: + - type: input-compare + header: Storage Size + label: Storage Size + subtitle: How much extra storage does your database need? Specify the size(e.g. 2Gi for 2 gigabytes) so we can allocate it correctly + init: + type: func + value: setValueFromDbDetails|/spec/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/postgres + schema: schema/properties/spec/properties/volumeExpansion/properties/postgres + - type: info + 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. +# Reconfigure + - type: block-layout + label: Reconfigure Form + if: + name: ifRequestTypeEqualsTo|Reconfigure + type: function + loader: + name: fetchConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + elements: + - type: block-layout + label: Configuration + elements: + - type: label-element + label: '' + subtitle: Select a new configuration secret, apply a custom configuration, or remove an existing setup to update your database settings + - type: tab-layout + label: New Config Secret + schema: temp/properties/reconfigurationType + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + elements: + - type: block-layout + label: Config Secret + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret + type: function + elements: + - type: label-element + label: Config Secret + subtitle: Select a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: schema/properties/spec/properties/configuration/properties/configSecret/properties/name + refresh: true + label: Config Secret + loader: + name: getConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/createSecret/properties/status + init: + type: func + value: setValueFromDbDetails|/spec/configSecret/name + watcher: + func: onCreateSecretChange + paths: + - temp/properties/createSecret/properties/status + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|create + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + - type: block-layout + label: Create a New Config Secret + showLabels: true + if: + type: function + name: isCreateSecret + hasButton: + text: Save + hasCancel: cancelCreateSecret + action: createNewConfigSecret + elements: + - type: input + label: Secret Name + schema: temp/properties/createSecret/properties/name + validation: + type: required + - type: array-object-form + label: String Data + schema: temp/properties/createSecret/properties/data + buttonClass: is-light is-outlined + validation: + type: required + elements: + - type: select + label: Key + schema: key + loader: + name: onSelectedSecretChange + watchPaths: + - temp/properties/createSecret/properties/data + validation: + type: required + - type: textarea + label: Value + schema: value + - type: multi-file-editor + editorHeight: 500px + readonly: true + if: + type: function + name: isNotCreateSecret + loader: + name: onNewConfigSecretChange + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + schema: temp/properties/newConfigSecret + - type: block-layout + label: ApplyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig + type: function + elements: + - type: label-element + 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). + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfiguration + refresh: true + label: Configuration + loader: getConfigSecretsforAppyConfig + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|apply + watchPaths: + - temp/properties/selectedConfiguration + - type: multi-file-editor + editorHeight: 500px + schema: temp/properties/applyConfig + loader: + name: setApplyConfig + watchPaths: + - temp/properties/selectedConfiguration + watcher: + func: onApplyconfigChange + paths: + - temp/properties/applyConfig + - type: block-layout + label: Remove + if: + name: ifReconfigurationTypeEqualsTo|remove + type: function + elements: + - type: label-element + label: Remove + subtitle: Selected a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfigurationRemove + refresh: true + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|remove + watchPaths: + - temp/properties/selectedConfigurationRemove + - type: multi-file-editor + editorHeight: 500px + readonly: true + init: + type: func + value: onRemoveConfigChange + watcher: + func: onRemoveConfigChange + paths: + - temp/properties/selectedConfigurationRemove + schema: temp/properties/removeConfig + +# Reconfigure TLS + - type: block-layout + label: TLS + if: + name: ifRequestTypeEqualsTo|ReconfigureTLS + type: function + elements: + - type: radio + label: TLS Operation + if: + name: hasTlsField + type: function + options: + - text: Update + value: update + - text: Rotate + value: rotate + - text: Remove + value: remove + init: + type: func + value: initTlsOperation + schema: temp/properties/tlsOperation + - type: switch + label: Remove TLS + fullwidth: true + if: + name: isTlsEnabled + type: function + schema: schema/properties/spec/properties/tls/properties/remove + - type: switch + label: Rotate Certificates + fullwidth: true + schema: schema/properties/spec/properties/tls/properties/rotateCertificates + if: + name: isTlsEnabled + type: function + - type: radio + label: Client Auth Mode + init: + type: func + value: setClientAuthMode + loader: getClientAuthModes + schema: schema/properties/spec/properties/tls/properties/clientAuthMode + - type: block-layout + label: SSL Mode + showLabels: false + if: + name: showIssuerRefAndCertificates + type: function + elements: + - type: radio + label: SSL Mode + init: + type: func + value: setSSLMode + options: + - text: disable + value: disable + - text: allow + value: allow + - text: prefer + value: prefer + - text: require + value: require + - text: verify-ca + value: verify-ca + - text: verify-full + value: verify-full + schema: schema/properties/spec/properties/tls/properties/sslMode + - type: block-layout + label: Issuer Reference + showLabels: true + if: + name: showIssuerRefAndCertificates + type: function + elements: + - type: input + label: API Group + init: + type: func + value: initIssuerRefApiGroup + watcher: + func: initIssuerRefApiGroup + paths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + disable: true + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup + - type: select + label: Kind + options: + - text: Issuer + value: Issuer + - text: ClusterIssuer + value: ClusterIssuer + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/kind + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - type: select + label: Name + loader: + name: getIssuerRefsName + watchPaths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - schema/properties/metadata/properties/namespace + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/name + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/name + - type: block-layout + label: Certificates + showLabels: false + if: + name: showIssuerRefAndCertificates + type: function + loader: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates + elements: + - type: array-object-form + label: Certificates + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/tls/properties/certificates + elements: + - type: select + label: Alias + loader: fetchAliasOptions + disable: disableAlias + schema: alias + validation: + type: required + - type: input + label: Secret Name + schema: secretName + - type: input + label: Duration + schema: duration + - type: input + label: Renew Before + schema: renewBefore + - type: array-item-form + label: Organizations + buttonClass: is-light is-outlined + schema: subject/properties/organizations + element: + type: input + label: Organization + - type: array-item-form + label: Countries + buttonClass: is-light is-outlined + schema: subject/properties/countries + element: + type: input + label: Country + - type: array-item-form + label: Organizational Units + buttonClass: is-light is-outlined + schema: subject/properties/organizationalUnits + element: + type: input + label: Organizational Unit + - type: array-item-form + label: Provinces + buttonClass: is-light is-outlined + schema: subject/properties/provinces + element: + type: input + label: Province + - type: array-item-form + label: DNS Names + buttonClass: is-light is-outlined + schema: dnsNames + element: + type: input + label: DNS Name + - type: array-item-form + label: IP Addresses + buttonClass: is-light is-outlined + schema: ipAddresses + element: + type: input + label: IP Address +# common + - type: block-layout + label: OpsRequest Options + showLabels: true + elements: + - type: time-picker + label: Timeout + schema: 'schema/properties/spec/properties/timeout' + subtitle: Specify the maximum time allowed for the operation to complete before it times out + - type: radio + label: Apply + schema: 'schema/properties/spec/properties/apply' + init: + type: func + value: setApplyToIfReady + options: + - text: IfReady (OpsRequest will be applied if database is ready) + value: IfReady + - text: Always (OpsRequest will always be applied) + value: Always \ No newline at end of file diff --git a/charts/opskubedbcom-postgresopsrequest-editor/ui/functions.js b/charts/opskubedbcom-postgresopsrequest-editor/ui/functions.js index 5879ff2c53..626405c913 100644 --- a/charts/opskubedbcom-postgresopsrequest-editor/ui/functions.js +++ b/charts/opskubedbcom-postgresopsrequest-editor/ui/functions.js @@ -1,3 +1,4 @@ +const { axios, useOperator, store, useToast } = window.vueHelpers || {} const machines = { 'db.t.micro': { resources: { @@ -303,182 +304,232 @@ const machineList = [ 'db.r.16xlarge', 'db.r.24xlarge', ] +const configSecretKeys = ['user.conf'] +let machinesFromPreset = [] -async function fetchJsons({ axios, itemCtx }) { - let ui = {} - let language = {} - let functions = {} - const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart +export const useFunc = (model) => { + const route = store.state?.route + const toast = useToast() - 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) - } + const { getValue, storeGet, discriminator, setDiscriminatorValue, commit } = useOperator( + model, + store.state, + ) - return { - ui: ui.data || {}, - language: language.data || {}, - functions, + 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 returnFalse() { + return false + } -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function isTlsEnabled() { + const dbDetails = getValue(discriminator, '/dbDetails') + return ( + (dbDetails?.spec?.sslMode && + dbDetails?.spec?.sslMode !== 'disabled' && + dbDetails?.spec?.sslMode !== 'disable') || + dbDetails?.spec?.tls + ) + } -async function getNamespaces({ axios, storeGet }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + async function getNamespaces() { + if (storeGet('/route/params/actions')) return [] + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - const resources = (resp && resp.data && resp.data.items) || [] + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, + }) - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + const resources = (resp && resp.data && resp.data.items) || [] -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/namespace') + async function getDbs() { + 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/kubedb.com/v1alpha2/namespaces/${namespace}/postgreses`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + const namespace = getValue(model, '/metadata/namespace') + // watchDependency('model#/metadata/namespace') - const resources = (resp && resp.data && resp.data.items) || [] + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/postgreses`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + const resources = (resp && resp.data && resp.data.items) || [] -async function getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) { - 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') + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } - if (namespace && name) { - const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/postgreses/${name}` - const resp = await axios.get(url) + async function getDbDetails() { + machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] - setDiscriminatorValue('/dbDetails', resp.data || {}) + 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') - return resp.data || {} - } else return {} -} + if (namespace && name) { + const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/postgreses/${name}` + const resp = await axios.get(url) -async function getDbVersions({ axios, storeGet, getValue, discriminator }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + setDiscriminatorValue('/dbDetails', resp.data || {}) - const url = `/clusters/${owner}/${cluster}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/kubedb-ui-presets` + return resp.data || {} + } else return {} + } - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + 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 { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + presetVersions = presets.admin?.databases?.Postgres?.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/postgresversions`, + { + 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 allowed = found?.spec?.updateConstraints?.allowlist || [] + 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 filteredPostgresVersions = 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.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.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.includes(item.metadata?.name)) && + isVersionWithinConstraints(item.spec?.version, limit) + ) + }) + setDiscriminatorValue('/filteredVersion', filteredPostgresVersions) + return filteredPostgresVersions.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) - presets.status = String(e.status) + return [] } } - try { - const presetVersions = presets.admin?.databases?.Postgres?.versions?.available || [] - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null, updateConstraints: null }, - }, - }, - } + function getVersionInfo() { + const filteredVersion = getValue(discriminator, '/filteredVersion') + if (filteredVersion.length) return '' - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/catalog.kubedb.com/v1alpha1/postgresversions`, - { - params: queryParams, - }, - ) - - const resources = (resp && resp.data && resp.data.items) || [] + let txt = 'No versions from this list can be selected as the target version: [ ' - 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 allowed = found?.spec?.updateConstraints?.allowlist || [] - 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 filteredPostgresVersions = 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.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.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.includes(item.metadata?.name)) && - isVersionWithinConstraints(item.spec?.version, limit) - ) + presetVersions.forEach((v, idx) => { + txt = `${txt}"${v}"` + if (idx !== presetVersions.length - 1) txt = txt + ', ' + else txt = txt + ' ]' }) - return filteredPostgresVersions.map((item) => { + return txt + } + + function getVersion() { + return filteredVersion.map((item) => { const name = (item.metadata && item.metadata.name) || '' const specVersion = (item.spec && item.spec.version) || '' return { @@ -486,853 +537,1397 @@ async function getDbVersions({ axios, storeGet, getValue, discriminator }) { value: name, } }) - } catch (e) { - console.log(e) - return [] } -} -function versionCompare(v1, v2) { - const arr1 = v1.split('.').map(Number) - const arr2 = v2.split('.').map(Number) + function isVersionEmpty() { + const val = getValue(discriminator, '/filteredVersion') + return val.length === 0 + } - for (let i = 0; i < Math.max(arr1.length, arr2.length); i++) { - const num1 = arr1[i] || 0 - const num2 = arr2[i] || 0 + function versionCompare(v1, v2) { + const arr1 = v1.split('.').map(Number) + const arr2 = v2.split('.').map(Number) - if (num1 > num2) return 1 // v1 is higher - if (num1 < num2) return -1 // v2 is higher - } - return 0 // versions are equal -} + for (let i = 0; i < Math.max(arr1.length, arr2.length); i++) { + const num1 = arr1[i] || 0 + const num2 = arr2[i] || 0 -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 + if (num1 > num2) return 1 // v1 is higher + if (num1 < num2) return -1 // v2 is higher + } + return 0 // versions are equal } - return true -} -function ifRequestTypeEqualsTo({ model, getValue, watchDependency }, type) { - const selectedType = getValue(model, '/spec/type') - watchDependency('model#/spec/type') + 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 + } - return selectedType === type -} -function onRequestTypeChange({ model, getValue, commit }) { - 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 ifRequestTypeEqualsTo(type) { + const selectedType = getValue(model, '/spec/type') + // watchDependency('model#/spec/type') -function getDbTls({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + return selectedType === type + } - const { spec } = dbDetails || {} - return spec?.tls || undefined -} + 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', + } -function getDbType({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const postgresDetails = getValue(discriminator, '/dbDetails') + Object.keys(reqTypeMapping).forEach((key) => { + if (key !== selectedType) commit('wizard/model$delete', `/spec/${reqTypeMapping[key]}`) + }) + } - const { spec } = postgresDetails || {} - const { standbyMode } = spec || {} + function getDbTls() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') - if (standbyMode) { - verd = 'cluster' - } else { - verd = 'standalone' + const { spec } = dbDetails || {} + return spec?.tls || undefined } - return verd -} + function getDbType() { + // watchDependency('discriminator#/dbDetails') + const postgresDetails = getValue(discriminator, '/dbDetails') -function disableOpsRequest({ itemCtx, discriminator, getValue, watchDependency }) { - if (itemCtx.value === 'HorizontalScaling') { - const dbType = getDbType({ - discriminator, - getValue, - watchDependency, - }) + const { spec } = postgresDetails || {} + const { standbyMode } = spec || {} + let verd = '' - if (dbType === 'standalone') return true - else return false - } else return false -} + if (standbyMode) { + verd = 'cluster' + } else { + verd = 'standalone' + } -function initNamespace({ route }) { - const { namespace } = route.query || {} - return namespace || null -} + return verd + } -function initDatabaseRef({ route, watchDependency }) { - watchDependency('model#/metadata/namespace') - const { name } = route.params || {} - return name -} + function disableOpsRequest() { + if (itemCtx.value === 'HorizontalScaling') { + const dbType = getDbType() -function asDatabaseOperation(route) { - return !!route.params.actions -} + if (dbType === 'standalone') return true + else return false + } else return false + } -function generateOpsRequestNameForClusterUI(getValue, model, route) { - const dbName = getValue(model, '/spec/databaseRef/name') + function initNamespace() { + const { namespace } = route.query || {} + return namespace || null + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + function initDatabaseRef() { + // watchDependency('model#/metadata/namespace') + const { name } = route.params || {} + return name + } - const resources = route.params.resource || '' - const resource = resources.slice(0, -1) + function asDatabaseOperation() { + return !!route.params.actions + } - const opsName = dbName ? dbName : resource - return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` -} + function generateOpsRequestNameForClusterUI(getValue, model, route) { + const dbName = getValue(model, '/spec/databaseRef/name') -function showAndInitName({ route, commit, getValue, model, watchDependency }) { - watchDependency('model#/spec/type') - watchDependency('model#/spec/databaseRef/name') - const ver = asDatabaseOperation(route) + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + const resources = route.params.resource || '' + const resource = resources.slice(0, -1) - 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, - }) + const opsName = dbName ? dbName : resource + return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` } - return !ver -} -function showAndInitNamespace({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/metadata/namespace', - value: `${route.query.namespace}`, - force: true, - }) + + 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 } - return !ver -} -function showAndInitDatabaseRef({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/spec/databaseRef/name', - value: `${route.params.name}`, - force: true, - }) + function showAndInitNamespace() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/metadata/namespace', + value: `${route.query.namespace}`, + force: true, + }) + } + + return !ver } - return !ver -} -function showConfigureOpsrequestLabel({ route }) { - return !asDatabaseOperation(route) -} -function showAndInitOpsRequestType({ route, commit }) { - const ver = asDatabaseOperation(route) - const opMap = { - upgrade: 'UpdateVersion', - updateVersion: 'UpdateVersion', - horizontalscaling: 'HorizontalScaling', - verticalscaling: 'VerticalScaling', - volumeexpansion: 'VolumeExpansion', - restart: 'Restart', - reconfiguretls: 'ReconfigureTLS', - reconfigure: 'Reconfigure', - } - if (ver) { - const operation = route.params.actions - const match = /^(.*)-opsrequest-(.*)$/.exec(operation) - const opstype = match[2] - commit('wizard/model$update', { - path: '/spec/type', - value: opMap[opstype], - force: true, - }) + function showAndInitDatabaseRef() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/spec/databaseRef/name', + value: `${route.params.name}`, + force: true, + }) + } + + return !ver } - return !ver -} + function showConfigureOpsrequestLabel() { + return !asDatabaseOperation() + } -// vertical scaling -function ifDbTypeEqualsTo({ discriminator, getValue, watchDependency, commit }, value, opsReqType) { - const verd = getDbType({ - discriminator, - getValue, - watchDependency, - }) + 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 value === verd -} + return !ver + } -// machine profile stuffs -let machinesFromPreset = [] + // vertical scaling + function ifDbTypeEqualsTo(value, opsReqType) { + const verd = getDbType() + return value === verd + } -function getMachines({ storeGet }) { - const presets = storeGet('/kubedbuiPresets') || {} - const avlMachines = presets.admin?.machineProfiles?.available || [] - let arr = [] - if (avlMachines.length) { - arr = avlMachines.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - 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 } - } else return { text: machine, value: machine } - } - }) - } else { - arr = machineList - .map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + // machine profile stuffs + 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 } } + } }) - .filter((val) => !!val) + } 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 } - return arr -} -function setMachine({ getValue, discriminator, storeGet }) { - const dbDetails = getValue(discriminator, '/dbDetails') - const annotations = dbDetails?.metadata?.annotations || {} - const machine = annotations['kubernetes.io/instance-type'] || 'custom' - - machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] + 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 machinePresets = machinesFromPreset.find((item) => item.id === machine) - if (machinePresets) return machine - else return '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({ getValue, discriminator, commit, model }, type, valPath) { - let selectedMachine = '' - selectedMachine = getValue(discriminator, '/machine') - const machine = machinesFromPreset.find((item) => item.id === selectedMachine) + 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 }, + } + } - let obj = {} - if (selectedMachine !== 'custom') { - if (machine) obj = { limits: { ...machine?.limits }, requests: { ...machine?.limits } } - else obj = machines[selectedMachine]?.resources - } else { - const val = getValue(discriminator, `/dbDetails${valPath}`) || {} - obj = Array.isArray(val) ? val[0]?.resources : { ...val } - } + const path = `/spec/verticalScaling/${type}/resources` - const path = `/spec/verticalScaling/${type}/resources` + if (obj && Object.keys(obj).length) + commit('wizard/model$update', { + path: path, + value: obj, + force: true, + }) - 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 - // update metadata.annotations - const annotations = getValue(model, '/metadata/annotations') || {} - if (selectedMachine === 'custom') commit('wizard/model$delete', '/metadata/annotations') - else { - annotations['kubernetes.io/instance-type'] = selectedMachine if (machinesFromPreset.length) commit('wizard/model$update', { path: '/metadata/annotations', value: annotations, force: true, }) + + if (annotations && Object.keys(annotations).length === 0) + commit('wizard/model$delete', '/metadata/annotations') } -} -function isMachineCustom({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/machine') - const machine = getValue(discriminator, '/machine') - return machine === 'custom' -} + function isMachineCustom(path) { + // watchDependency(`discriminator#${path}`) + const machine = getValue(discriminator, `${path}`) + return machine === 'custom' + } -// for config secret -async function getConfigSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + // Fetch and store database Infos + // for secret configurations in reconfigure + let configSecrets = [] + let secretConfigData = [] - const secrets = (resp && resp.data && resp.data.items) || [] + 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 filteredSecrets = secrets + 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') - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return filteredSecrets -} + 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: ['user.conf'], + }, + }, + ) + configSecrets = resp?.data?.response?.availableSecrets || [] + secretConfigData = resp?.data?.response?.configurations || [] + } catch (e) { + console.log(e) + } + } -function createSecretUrl({ storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 + } - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/secrets/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/secrets/create` + async function getConfigSecretsforAppyConfig() { + const secrets = secretConfigData.map((item) => { + return { text: item.componentName, value: item.componentName } + }) + return secrets } -} -function isEqualToValueFromType({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/valueFromType') - const valueFrom = getValue(discriminator, '/valueFromType') - return valueFrom === value -} + function getSelectedConfigurationData(type) { + type = type ? type + '/' : '' + const path = `/${type}selectedConfiguration` + const selectedConfiguration = getValue(discriminator, path) -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + if (!selectedConfiguration) { + return [] + } - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + const configuration = secretConfigData.find( + (item) => item.componentName === selectedConfiguration, + ) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, + 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, }) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + return result } - return ans -} -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` + const selectedConfiguration = + configType === 'create' ? getValue(model, path) : getValue(discriminator, path) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, + 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 + } }) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + // Convert data object back to YAML string + return yaml.dump(data) } - return ans -} -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - group, - version, - resource, -) { - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/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) - }) + 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])) + + 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 resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + function decodeError(msg, defaultMsg) { + if (typeof msg === 'string') { + return msg || defaultMsg } - }) -} -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) - - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) + return ( + (msg.response && msg.response.data && msg.response.data.message) || + (msg.response && msg.response.data) || + (msg.status && msg.status.status) || + defaultMsg + ) } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + 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 + } -// reconfiguration type -function ifReconfigurationTypeEqualsTo({ discriminator, getValue, watchDependency }, value) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - watchDependency('discriminator#/reconfigurationType') + function isNotCreateSecret(type) { + return !isCreateSecret(type) + } - return reconfigurationType === value -} + 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 onApplyconfigChange({ discriminator, getValue, commit }) { - const applyconfig = getValue(discriminator, '/applyConfig') + 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', + }) + } - const configObj = {} + async function onApplyconfigChange(type) { + type = type ? type + '/' : '' + const configValue = getValue(discriminator, `${type}applyConfig`) - if (applyconfig) { - applyconfig.forEach((item) => { - const { key, value } = item - configObj[key] = value + if (!configValue) { + commit('wizard/model$delete', `/spec/configuration/${type}applyConfig`) + return + } + const tempConfigObj = {} + configValue.forEach((item) => { + if (item.name) { + 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, }) } - commit('wizard/model$update', { - path: '/spec/configuration/applyConfig', - value: configObj, - force: true, - }) -} + 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], + }) + }) + } else { + configObj.push({ name: '', content: '' }) + } + return configObj + } -function onReconfigurationTypeChange({ commit, discriminator, getValue, setDiscriminatorValue }) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - setDiscriminatorValue('/applyConfig', []) - if (reconfigurationType === 'remove') { - commit('wizard/model$delete', `/spec/configuration`) + 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/removeCustomConfig`, + path: `/spec/configuration/${type}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({ discriminator, getValue, watchDependency }) { - const tls = getDbTls({ - discriminator, - getValue, - watchDependency, - }) - return !!tls -} + const configuration = secretConfigData.find((item) => item.componentName === selectedConfig) -function setSSLMode({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') + if (!configuration.data) { + return [{ name: '', content: '' }] + } - const retValue = getValue(discriminator, `/dbDetails/spec/sslMode`) - return retValue || 'require' -} + 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 + } -function setClientAuthMode({ discriminator, getValue, watchDependency, commit }) { - watchDependency('discriminator#/dbDetails') + async function onNewConfigSecretChange(type) { + type = type ? type + '/' : '' + const path = `/spec/configuration/${type}configSecret/name` + const selectedSecret = getValue(model, path) - const retValue = getValue(discriminator, `/dbDetails/spec/clientAuthMode`) + if (!selectedSecret) { + commit('wizard/model$delete', `/spec/configuration/${type}configSecret`) + return [{ name: '', content: '' }] + } + if (selectedSecret === 'Create') return [{ name: '', content: '' }] - commit('wizard/model$update', { - path: '/spec/tls/clientAuthMode', - value: retValue || '', - force: true, - }) + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = storeGet('/route/query/namespace') || getValue(model, '/metadata/namespace') - return retValue -} + 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 + }) + } + }) -function initIssuerRefApiGroup({ getValue, model, watchDependency }) { - const kind = getValue(model, '/spec/tls/issuerRef/kind') - watchDependency('model#/spec/tls/issuerRef/kind') + return configObj + } catch (e) { + console.error('Error fetching secret:', e) + return [{ name: '', content: '' }] + } + } - if (kind) { - return 'cert-manager.io' - } else return undefined -} + function onSelectedSecretChange(index) { + const secretData = getValue(discriminator, 'createSecret/data') || [] + const selfSecrets = secretData.map((item) => item.key) -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - 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` + const remainingSecrets = configSecretKeys.filter((item) => !selfSecrets.includes(item)) - 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) - } + const selfKey = getValue(discriminator, `createSecret/data/${index}/key`) + if (selfKey) { + remainingSecrets.push(selfKey) } - let clusterIssuers = presets.admin?.clusterIssuers?.available || [] - if (presets.status === '404') { - const url = `/clusters/${owner}/${cluster}/proxy/cert-manager.io/v1/clusterissuers` - return getIssuer(url) + 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` } - return clusterIssuers } - async function getIssuer(url) { + 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) - const resources = (resp && resp.data && resp.data.items) || [] + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + 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 } }, + }, }) - return resources + + const items = (resp && resp.data && resp.data.items) || [] + ans = items } catch (e) { console.log(e) - return [] } + + 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, + }) -function initTlsOperation() { - return 'update' -} -function onTlsOperationChange({ discriminator, getValue, commit }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + 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, + }) - commit('wizard/model$delete', '/spec/tls') + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } - if (tlsOperation === 'rotate') { - commit('wizard/model$update', { - path: '/spec/tls/rotateCertificates', - value: true, - force: true, + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } }) - } else if (tlsOperation === 'remove') { + } + + // reconfiguration type + function ifReconfigurationTypeEqualsTo(value) { + const reconfigurationType = getValue(discriminator, '/reconfigurationType') + const watchPath = `discriminator#/reconfigurationType` + // watchDependency(watchPath) + 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 setSSLMode() { + // watchDependency('discriminator#/dbDetails') + const retValue = getValue(discriminator, `/dbDetails/spec/sslMode`) + return retValue || 'require' + } + + function setClientAuthMode() { + // watchDependency('discriminator#/dbDetails') + const retValue = getValue(discriminator, `/dbDetails/spec/clientAuthMode`) + commit('wizard/model$update', { - path: '/spec/tls/remove', - value: true, + path: '/spec/tls/clientAuthMode', + value: retValue || '', force: true, }) + + return retValue } -} -function showIssuerRefAndCertificates({ discriminator, getValue, watchDependency }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') - watchDependency('discriminator#/tlsOperation') - const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' + function initIssuerRefApiGroup() { + const kind = getValue(model, '/spec/tls/issuerRef/kind') + // watchDependency('model#/spec/tls/issuerRef/kind') - return verd -} + if (kind) { + return 'cert-manager.io' + } else return undefined + } -function isIssuerRefRequired({ discriminator, getValue, watchDependency }) { - const hasTls = hasTlsField({ - discriminator, - getValue, - watchDependency, - }) + 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') - return !hasTls -} + 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, + }) + } else if (tlsOperation === 'remove') { + commit('wizard/model$update', { + path: '/spec/tls/remove', + value: true, + force: true, + }) + } + } + + 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 getClientAuthModes({ getValue, watchDependency, discriminator }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + function getClientAuthModes() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') - const { spec } = dbDetails || {} - const { version } = spec || {} + const { spec } = dbDetails || {} + const { version } = spec || {} - watchDependency('discriminator#/tlsOperation') + // watchDependency('discriminator#/tlsOperation') + const tlsOperation = getValue(discriminator, '/tlsOperation') + + // major version section from version + const major = parseInt(version && version.split('.')[0]) - const tlsOperation = getValue(discriminator, '/tlsOperation') + const options = ['md5'] - // major version section from version - const major = parseInt(version && version.split('.')[0]) + if (major >= 11) { + options.push('scram') + } - const options = ['md5'] + if (tlsOperation !== 'remove') { + options.push('cert') + } - if (major >= 11) { - options.push('scram') + return options.map((item) => ({ text: item, value: item })) } - if (tlsOperation !== 'remove') { - options.push('cert') + function getRequestTypeFromRoute() { + const isDbloading = isDbDetailsLoading() + const { query } = route || {} + const { requestType } = query || {} + return isDbloading ? '' : requestType || '' } - return options.map((item) => ({ text: item, value: item })) -} + function isDbDetailsLoading() { + // watchDependency('discriminator#/dbDetails') + // watchDependency('model#/spec/databaseRef/name') + const dbDetails = getValue(discriminator, '/dbDetails') + const dbName = getValue(model, '/spec/databaseRef/name') -function getRequestTypeFromRoute({ route, model, discriminator, getValue, watchDependency }) { - const isDbloading = isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) - const { query } = route || {} - const { requestType } = query || {} - return isDbloading ? '' : requestType || '' -} + return !dbDetails || !dbName + } -function isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - watchDependency('model#/spec/databaseRef/name') - const dbDetails = getValue(discriminator, '/dbDetails') - const dbName = getValue(model, '/spec/databaseRef/name') + function setValueFromDbDetails(path, commitPath) { + // watchDependency('discriminator#/dbDetails') + const retValue = getValue(discriminator, `/dbDetails${path}`) - return !dbDetails || !dbName -} + if (commitPath && retValue) { + const tlsOperation = getValue(discriminator, '/tlsOperation') -function setValueFromDbDetails( - { discriminator, getValue, watchDependency, commit }, - path, - commitPath, -) { - watchDependency('discriminator#/dbDetails') - const retValue = getValue(discriminator, `/dbDetails${path}`) + // computed called when tls fields is not visible + if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined - if (commitPath && retValue) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + // 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, + }) + } - // computed called when tls fields is not visible - if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined + return retValue || 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, - }) + function getAliasOptions() { + return ['server', 'client', 'metrics-exporter'] } - return retValue || undefined -} + function isNamespaceDisabled() { + const { namespace } = route.query || {} + return !!namespace + } -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} + function isDatabaseRefDisabled() { + const { name } = route.params || {} + return !!name + } -function isNamespaceDisabled({ route }) { - const { namespace } = route.query || {} - return !!namespace -} + function onNamespaceChange() { + commit('wizard/model$delete', '/spec/type') + } -function isDatabaseRefDisabled({ route }) { - const { name } = route.params || {} - return !!name -} + function onDbChange() { + commit('wizard/model$delete', '/spec/type') + getDbDetails() + } -function onNamespaceChange({ commit }) { - commit('wizard/model$delete', '/spec/type') -} + function setApplyToIfReady() { + return 'IfReady' + } -function onDbChange({ commit, axios, storeGet, model, getValue, setDiscriminatorValue }) { - commit('wizard/model$delete', '/spec/type') - getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) -} + function isVerticalScaleTopologyRequired() { + // watchDependency(`discriminator#/topologyKey`) + // watchDependency(`discriminator#/topologyValue`) -function setApplyToIfReady() { - return 'IfReady' -} + const key = getValue(discriminator, `/topologyKey`) + const value = getValue(discriminator, `/topologyValue`) + const path = `/spec/verticalScaling/postgres/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 isVerticalScaleTopologyRequired({ watchDependency, getValue, discriminator, commit }) { - watchDependency('discriminator#/topologyKey') - watchDependency('discriminator#/topologyValue') + function checkVolume(initpath, path) { + const volume = getValue(discriminator, `/dbDetails${initpath}`) + const input = getValue(model, path) - const key = getValue(discriminator, '/topologyKey') - const value = getValue(discriminator, '/topologyValue') - const path = `/spec/verticalScaling/postgres/topology` + try { + const sizeInBytes = parseSize(volume) + const inputSizeInBytes = parseSize(input) - if (key || value) { - commit('wizard/model$update', { - path: path, - value: { key, value }, - force: true, + 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 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() { + 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 true - } else { - commit('wizard/model$delete', path) - return false + return data || 'No Data Found' } -} -function checkVolume({ model, discriminator, getValue }, initpath, path) { - const volume = getValue(discriminator, `/dbDetails${initpath}`) - const input = getValue(model, path) + function namespaceWatcherFunctions() { + getDbs() + initDatabaseRef() + getConfigSecrets() + resourceNames() + getIssuerRefsName() + onNamespaceChange() + } - try { - const sizeInBytes = parseSize(volume) - const inputSizeInBytes = parseSize(input) + function requestTypeWatcherFunctions() { + onRequestTypeChange() + ifRequestTypeEqualsTo() + showAndInitName() + } - if (inputSizeInBytes >= sizeInBytes) return true - else return 'Cannot expand to lower volume!' - } catch (err) { - return err.message || 'Invalid' + function databaseRefWatcherFunctions() { + onDbChange() + showAndInitName() + isDbDetailsLoading() } -} -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 IssuerRefWatcherFunctions() { + initIssuerRefApiGroup() + getIssuerRefsName() + } -return { - fetchJsons, - returnFalse, - getNamespaces, - getDbs, - getDbDetails, - getDbVersions, - ifRequestTypeEqualsTo, - onRequestTypeChange, - getDbTls, - setSSLMode, - setClientAuthMode, - getDbType, - disableOpsRequest, - initNamespace, - initDatabaseRef, - isRancherManaged, - showAndInitName, - showAndInitNamespace, - showAndInitDatabaseRef, - showConfigureOpsrequestLabel, - showAndInitOpsRequestType, - - ifDbTypeEqualsTo, - getConfigSecrets, - createSecretUrl, - isEqualToValueFromType, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - ifReconfigurationTypeEqualsTo, - onReconfigurationTypeChange, - onApplyconfigChange, - hasTlsField, - initIssuerRefApiGroup, - getIssuerRefsName, - initTlsOperation, - onTlsOperationChange, - showIssuerRefAndCertificates, - isIssuerRefRequired, - getClientAuthModes, - getRequestTypeFromRoute, - isDbDetailsLoading, - setValueFromDbDetails, - getAliasOptions, - isDatabaseRefDisabled, - isNamespaceDisabled, - onNamespaceChange, - onDbChange, - setApplyToIfReady, - isVerticalScaleTopologyRequired, - getMachines, - setMachine, - onMachineChange, - isMachineCustom, - checkVolume, + function tlsOperationWatcherFunction() { + showIssuerRefAndCertificates() + onTlsOperationChange() + } + + function dbDetailsWatcherFunction() { + getDbTls() + getDbType() + isDbDetailsLoading() + } + + 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, + }) + } + + return { + setExporter, + onExporterResourceChange, + dbDetailsWatcherFunction, + tlsOperationWatcherFunction, + namespaceWatcherFunctions, + requestTypeWatcherFunctions, + databaseRefWatcherFunctions, + IssuerRefWatcherFunctions, + fetchAliasOptions, + validateNewCertificates, + disableAlias, + isRancherManaged, + fetchJsons, + returnFalse, + getNamespaces, + getDbs, + getDbDetails, + getDbVersions, + getVersionInfo, + isVersionEmpty, + getVersion, + ifRequestTypeEqualsTo, + onRequestTypeChange, + getDbTls, + setSSLMode, + setClientAuthMode, + getDbType, + disableOpsRequest, + initNamespace, + initDatabaseRef, + showAndInitName, + showAndInitNamespace, + showAndInitDatabaseRef, + showConfigureOpsrequestLabel, + showAndInitOpsRequestType, + ifDbTypeEqualsTo, + getConfigSecrets, + createSecretUrl, + isConfigSelected, + isEqualToValueFromType, + getNamespacedResourceList, + getResourceList, + resourceNames, + unNamespacedResourceNames, + ifReconfigurationTypeEqualsTo, + onReconfigurationTypeChange, + onApplyconfigChange, + hasTlsField, + initIssuerRefApiGroup, + getIssuerRefsName, + initTlsOperation, + onTlsOperationChange, + showIssuerRefAndCertificates, + isIssuerRefRequired, + getClientAuthModes, + getRequestTypeFromRoute, + isDbDetailsLoading, + setValueFromDbDetails, + getAliasOptions, + isNamespaceDisabled, + isDatabaseRefDisabled, + onDbChange, + onNamespaceChange, + setApplyToIfReady, + isVerticalScaleTopologyRequired, + getMachines, + setMachine, + onMachineChange, + isMachineCustom, + checkVolume, + getSelectedConfigSecretValue, + fetchConfigSecrets, + getConfigSecretsforAppyConfig, + getSelectedConfigurationData, + getSelectedConfigurationName, + getSelectedConfigurationValueForRemove, + createNewConfigSecret, + decodeError, + isCreateSecret, + isNotCreateSecret, + onCreateSecretChange, + cancelCreateSecret, + setApplyConfig, + onRemoveConfigChange, + onNewConfigSecretChange, + onSelectedSecretChange, + isTlsEnabled, + } } diff --git a/charts/opskubedbcom-proxysqlopsrequest-editor/ui/create-ui.yaml b/charts/opskubedbcom-proxysqlopsrequest-editor/ui/create-ui.yaml index 3b81de3eff..3d24380835 100644 --- a/charts/opskubedbcom-proxysqlopsrequest-editor/ui/create-ui.yaml +++ b/charts/opskubedbcom-proxysqlopsrequest-editor/ui/create-ui.yaml @@ -1,560 +1,527 @@ -steps: -- form: - discriminator: - dbDetails: - type: object +type: multi-step-form +step: + - type: single-step-form + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - schema: - $ref: discriminator#/properties/dbDetails - type: input - - if: showAndInitName - label: - text: labels.op_req_name - required: true - schema: - $ref: schema#/properties/metadata/properties/name - type: input - - computed: initNamespace - disabled: isNamespaceDisabled - fetch: getNamespaces - hasGroup: isRancherManaged - if: showAndInitNamespace - label: - text: labels.namespace - onChange: onNamespaceChange - required: true - schema: - $ref: schema#/properties/metadata/properties/namespace - type: select - - computed: initDatabaseRef - disabled: isDatabaseRefDisabled - fetch: getDbs - if: showAndInitDatabaseRef - label: - text: labels.databaseRef - onChange: onDbChange - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/proxyRef/properties/name - type: select - - if: showConfigureOpsrequestLabel - label: - text: labels.config_ops_request - type: label-element - - computed: getRequestTypeFromRoute - disabled: isDbDetailsLoading - hasDescription: true - if: showAndInitOpsRequestType - label: - text: labels.ops_request_type - onChange: onRequestTypeChange - options: - - description: options.UpdateVersion.description - text: options.UpdateVersion.text - value: UpdateVersion - - description: options.HorizontalScaling.description - text: options.HorizontalScaling.text - value: HorizontalScaling - - description: options.VerticalScaling.description - text: options.VerticalScaling.text - value: VerticalScaling - - description: options.Restart.description - text: options.Restart.text - value: Restart - - description: options.Reconfigure.description - text: options.Reconfigure.text - value: Reconfigure - - description: options.ReconfigureTLS.description - text: options.ReconfigureTLS.text - value: ReconfigureTLS - schema: - $ref: schema#/properties/spec/properties/type - type: radio - - elements: - - computed: setValueFromDbDetails|/spec/version - fetch: getDbVersions - label: - text: labels.targetVersion - schema: - $ref: schema#/properties/spec/properties/updateVersion/properties/targetVersion - type: select - if: ifRequestTypeEqualsTo|UpdateVersion - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/replicas - label: - text: labels.replicas - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/member - type: input - if: ifRequestTypeEqualsTo|HorizontalScaling - label: - text: Horizontal Scaling Form - schema: - $ref: schema#/properties/spec/properties/horizontalScaling - type: single-step-form - - discriminator: - machine: - default: "" - type: string - elements: - - computed: setMachine - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|proxysql|/spec/podTemplate/spec/resources - schema: - $ref: discriminator#/machine - type: select - - if: isMachineCustom - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/proxysql/properties/resources - type: resource-input-form - - label: - text: labels.node_selection_policy +# common + - type: input + label: op_req_name + if: + type: function + name: showAndInitName + validation: + type: required + schema: schema/properties/metadata/properties/name + - type: select + label: Namespace + if: + type: function + name: showAndInitNamespace + init: + type: func + value: initNamespace + disable: isNamespaceDisabled + loader: getNamespaces + validation: + type: required + hasGroup: isRancherManaged + schema: schema/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/metadata/properties/namespace + - type: select + label: Database Ref + if: + type: function + name: showAndInitDatabaseRef + loader: + name: getDbs + watchPaths: + - schema/properties/metadata/properties/namespace + init: + type: func + value: initDatabaseRef + validation: + type: required + disable: isDatabaseRefDisabled + refresh: true + watcher: + func: onDbChange + paths: + - schema/properties/spec/properties/proxyRef/properties/name + schema: schema/properties/spec/properties/proxyRef/properties/name + - type: label-element + label: config_ops_request + if: + type: function + name: showConfigureOpsrequestLabel + - type: radio + label: Type of Ops Request + if: + type: function + name: showAndInitOpsRequestType options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/proxysql/properties/nodeSelectionPolicy - type: select - - discriminator: - topologyKey: - default: "" - type: string - topologyValue: - default: "" - type: string + - 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: 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 + init: + type: func + value: getRequestTypeFromRoute + disable: isDbDetailsLoading + watcher: + func: onRequestTypeChange + paths: + - schema/properties/spec/properties/type + isHorizontal: true + schema: schema/properties/spec/properties/type +# UpdateVersion + - type: block-layout + showLabels: true + label: Version + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|UpdateVersion + elements: + - type: select-compare + label: Target Version + subtitle: Select the desired ProxySQL version to which you want to update your database. + init: + type: func + value: setValueFromDbDetails|/spec/version + loader: getDbVersions + schema: schema/properties/spec/properties/updateVersion/properties/targetVersion + - type: info + label: '' + loader: + name: getVersionInfo + watchPaths: + - temp/properties/filteredVersion + if: + type: function + name: isVersionEmpty +# Horizontal Scale + - type: block-layout + label: Horizontal Scaling Form + showLabels: true + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|HorizontalScaling elements: - - label: - text: labels.key - required: isVerticalScaleTopologyRequired - schema: - $ref: discriminator#/topologyKey - type: input - - label: - text: labels.value - required: isVerticalScaleTopologyRequired - schema: - $ref: discriminator#/topologyValue - type: input - label: - text: labels.topology - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|VerticalScaling - label: - text: labels.proxysql - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/proxysql - show_label: true - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/initConfig/adminVariables|/spec/configuration/adminVariables - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.configuration.adminVariables - schema: - $ref: schema#/properties/spec/properties/configuration/properties/adminVariables - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/configuration/properties/adminVariables - type: input - - computed: setValueFromDbDetails|/spec/initConfig/mysqlVariables|/spec/configuration/mysqlVariables - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.configuration.mysqlVariables - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mysqlVariables - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mysqlVariables - type: input - - elements: - - label: - text: labels.configuration.reqType - onChange: onMySQLUserReqTypeChange - options: - - add - - update - - delete - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mysqlQueryRules/properties/reqType - type: select - - addFormLabel: labels.configuration.queryRule - computed: setMySQLRules - element: - discriminator: - mysqlQueryRules: - emitAs: mysqlQueryRules - type: array + - type: horizontal-layout elements: - - isArray: true - keys: - label: - text: labels.annotations.key - label: - text: labels.configuration.rules - schema: - $ref: discriminator#/properties/mysqlQueryRules/items/properties/rules - type: key-value-input-form - values: - label: - text: labels.annotations.value - schema: - $ref: discriminator#/properties/mysqlQueryRules/items/properties/rules/additionalProperties - type: input - schema: - $ref: discriminator#/properties/mysqlQueryRules/items - type: single-step-form - label: - text: labels.configuration.queryRules - onChange: onMySQLRulesChange - schema: - $ref: discriminator#/properties/mysqlQueryRules - tableContents: - - inTableColumn: true - label: - text: labels.configuration.rules - path: rules - type: value - typeOfValue: key-value - type: single-step-form-array - label: - text: labels.configuration.mysqlQueryRules - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mysqlQueryRules - show_label: true - type: single-step-form - - customClass: mt-10 + - type: input-compare + label: Replicas + header: Replica + subtitle: Define the total number of replicas for the database. Increasing replicas improves fault tolerance and load distribution, while reducing replicas conserves resources + init: + type: func + value: setValueFromDbDetails|/spec/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/member + - type: info + 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. +# vertical Scale + - type: block-layout + if: + type: function + name: ifRequestTypeEqualsTo|VerticalScaling elements: - - label: - text: labels.configuration.reqType - onChange: onMySQLUserReqTypeChange - options: - - add - - update - - delete - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mysqlUsers/properties/reqType - type: select - - addFormLabel: labels.configuration.user - customClass: mt-20 - element: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines|proxysql + init: + type: func + value: setMachine|proxysql + watcher: + func: onMachineChange|proxysql|/spec/podTemplate/spec/resources + paths: + - temp/properties/machine + schema: temp/properties/machine + - type: block-layout + label: Node Selection + showLabels: true elements: - - label: - text: labels.configuration.username - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mysqlUsers/properties/users/items/properties/username - type: input - - label: - text: labels.configuration.active - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mysqlUsers/properties/users/items/properties/active - type: input - - label: - text: labels.configuration.default_schema - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mysqlUsers/properties/users/items/properties/default_schema - type: input - - label: - text: labels.configuration.use_ssl - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mysqlUsers/properties/users/items/properties/use_ssl - type: input - - label: - text: labels.configuration.attributes - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mysqlUsers/properties/users/items/properties/attributes - type: input - - label: - text: labels.configuration.backend - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mysqlUsers/properties/users/items/properties/backend - type: input - - label: - text: labels.configuration.comment - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mysqlUsers/properties/users/items/properties/comment - type: input - - label: - text: labels.configuration.default_hostgroup - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mysqlUsers/properties/users/items/properties/default_hostgroup - type: input - - label: - text: labels.configuration.fast_forward - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mysqlUsers/properties/users/items/properties/fast_forward - type: input - - label: - text: labels.configuration.frontend - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mysqlUsers/properties/users/items/properties/frontend - type: input - - label: - text: labels.configuration.max_connections - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mysqlUsers/properties/users/items/properties/max_connections - type: input - - label: - text: labels.configuration.schema_locked - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mysqlUsers/properties/users/items/properties/schema_locked - type: input - - label: - text: labels.configuration.transaction_persistent - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mysqlUsers/properties/users/items/properties/transaction_persistent - type: input - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mysqlUsers/properties/users/items - type: single-step-form - if: showUserCreationField - label: - text: labels.configuration.users - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mysqlUsers/properties/users - tableContents: - - inTableColumn: true - label: - text: labels.configuration.username - path: username - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.configuration.active - path: active - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.configuration.default_schema - path: default_schema - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.configuration.use_ssl - path: use_ssl - type: value - typeOfValue: string - - label: - text: labels.configuration.attributes - path: attributes - type: value - typeOfValue: string - - label: - text: labels.configuration.backend - path: backend - type: value - typeOfValue: string - - label: - text: labels.configuration.comment - path: comment - type: value - typeOfValue: string - - label: - text: labels.configuration.default_hostgroup - path: default_hostgroup - type: value - typeOfValue: string - - label: - text: labels.configuration.fast_forward - path: fast_forward - type: value - typeOfValue: string - - label: - text: labels.configuration.frontend - path: frontend - type: value - typeOfValue: string - - label: - text: labels.configuration.max_connections - path: max_connections - type: value - typeOfValue: string - - label: - text: labels.configuration.schema_locked - path: schema_locked - type: value - typeOfValue: string - - label: - text: labels.configuration.transaction_persistent - path: transaction_persistent - type: value - typeOfValue: string - type: single-step-form-array - - addFormLabel: labels.configuration.user - customClass: mt-20 - element: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/proxysql/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|proxysql + schema: temp/topologyKey-proxysql + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|proxysql + schema: temp/topologyValue-proxysql + - type: block-layout + label: Exporter + showLabels: true + hideBlock: true elements: - - label: - text: labels.configuration.username - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mysqlUsers/properties/users/items/properties/username - type: input - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mysqlUsers/properties/users/items - type: single-step-form - if: showUserDeletionField - label: - text: labels.configuration.users - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mysqlUsers/properties/users - tableContents: - - inTableColumn: true - label: - text: labels.configuration.username - path: username - type: value - typeOfValue: string - type: single-step-form-array - label: - text: labels.configuration.mysqlUsers - schema: - $ref: schema#/properties/spec/properties/configuration/properties/mysqlUsers - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|Reconfigure - schema: - $ref: schema#/properties/spec/properties/configuration - type: single-step-form - - discriminator: - tlsOperation: - default: update - type: string - elements: - - computed: initTlsOperation - if: hasTlsField - label: - text: labels.tlsOperation - onChange: onTlsOperationChange - options: - - text: Update - value: update - - text: Rotate - value: rotate - - text: Remove - value: remove - schema: - $ref: discriminator#/properties/tlsOperation - type: radio - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/remove - type: switch - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/rotateCertificates - type: switch - - elements: - - computed: initIssuerRefApiGroup - disabled: true - label: - text: labels.api_group - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup - type: input - - computed: setValueFromDbDetails|/spec/tls/issuerRef/kind - label: - text: labels.kind - options: - - text: Issuer - value: Issuer - - text: ClusterIssuer - value: ClusterIssuer - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/kind - type: select - - allowUserDefinedOption: true - computed: setValueFromDbDetails|/spec/tls/issuerRef/name - fetch: getIssuerRefsName - label: - text: labels.name - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/name - type: select - if: showIssuerRefAndCertificates - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef - type: single-step-form - - alias: reusable_certificates - chart: - name: uibytebuildersdev-component-certificates - version: v0.29.0 - computed: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates - functionCallbacks: - getAliasOptions: - $ref: functions#/getAliasOptions - if: showIssuerRefAndCertificates - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/spec/properties/tls/properties/certificates - type: reusable-element - if: ifRequestTypeEqualsTo|ReconfigureTLS - label: - text: labels.tls - schema: - $ref: schema#/properties/spec/properties/tls - type: single-step-form - - customClass: mt-10 - label: - text: labels.timeout - options: - - text: 5 minutes - value: 5m - - text: 10 minutes - value: 10m - - text: 30 minutes - value: 30m - - text: 1 hour - value: 1h - - text: 2 hours - value: 2h - - text: 5 hours - value: 5h - - text: 10 hours - value: 10h - schema: - $ref: schema#/properties/spec/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: labels.apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/spec/properties/apply - type: radio - type: single-step-form - id: basic - title: steps.0.label -type: multi-step-form + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setExporter|cpu + type: input + 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 + watcher: + func: onExporterResourceChange|memory + paths: + - schema/properties/spec/properties/verticalScaling/properties/exporter/properties/resources/properties/limits/properties/memory +# Reconfigure + - type: block-layout + label: Reconfigure Form + if: + name: ifRequestTypeEqualsTo|Reconfigure + type: function + elements: + - type: input-compare + label: Admin Variables + init: + type: func + value: setValueFromDbDetails|/spec/initConfig/adminVariables|/spec/configuration/adminVariables + schema: schema/properties/spec/properties/configuration/properties/adminVariables + - type: input-compare + label: MySQL Variables + init: + type: func + value: setValueFromDbDetails|/spec/initConfig/mysqlVariables|/spec/configuration/mysqlVariables + schema: schema/properties/spec/properties/configuration/properties/mysqlVariables + - type: block-layout + label: MySQL Query Rules + showLabels: true + elements: + - type: select + label: Request Type + options: + - text: Add + value: add + - text: Update + value: update + - text: Delete + value: delete + watcher: + func: onMySQLUserReqTypeChange + paths: + - schema/properties/spec/properties/configuration/properties/mysqlQueryRules/properties/reqType + schema: schema/properties/spec/properties/configuration/properties/mysqlQueryRules/properties/reqType + - type: array-item-form + label: Query Rules + buttonClass: is-light is-outlined + init: + type: func + value: setMySQLRules + watcher: + func: onMySQLRulesChange + paths: + - temp/mysqlQueryRules + schema: temp/mysqlQueryRules/properties/rules + element: + type: input + label: Rules + - type: block-layout + label: MySQL Users + showLabels: true + elements: + - type: select + label: Request Type + options: + - text: Add + value: add + - text: Update + value: update + - text: Delete + value: delete + watcher: + func: onMySQLUserReqTypeChange + paths: + - schema/properties/spec/properties/configuration/properties/mysqlUsers/properties/reqType + schema: schema/properties/spec/properties/configuration/properties/mysqlUsers/properties/reqType + - type: array-object-form + label: Users + buttonClass: is-light is-outlined + if: + name: showUserCreationField + type: function + schema: schema/properties/spec/properties/configuration/properties/mysqlUsers/properties/users + elements: + - type: input + label: Username + validation: + type: required + schema: items/properties/username + - type: input + label: Active + schema: items/properties/active + - type: input + label: Default Schema + schema: items/properties/default_schema + - type: input + label: Use SSL + schema: items/properties/use_ssl + - type: input + label: Attributes + schema: items/properties/attributes + - type: input + label: Backend + schema: items/properties/backend + - type: input + label: Comment + schema: items/properties/comment + - type: input + label: Default Hostgroup + schema: items/properties/default_hostgroup + - type: input + label: Fast Forward + schema: items/properties/fast_forward + - type: input + label: Frontend + schema: items/properties/frontend + - type: input + label: Max Connections + schema: items/properties/max_connections + - type: input + label: Schema Locked + schema: items/properties/schema_locked + - type: input + label: Transaction Persistent + schema: items/properties/transaction_persistent + - type: array-item-form + label: Users + buttonClass: is-light is-outlined + if: + name: showUserDeletionField + type: function + schema: schema/properties/spec/properties/configuration/properties/mysqlUsers/properties/users/properties/username + element: + type: input + label: Username + validation: + type: required +# Reconfigure TLS + - type: block-layout + label: TLS + if: + name: ifRequestTypeEqualsTo|ReconfigureTLS + type: function + elements: + - type: radio + label: TLS Operation + if: + name: hasTlsField + type: function + options: + - text: Update + value: update + - text: Rotate + value: rotate + - text: Remove + value: remove + init: + type: func + value: initTlsOperation + schema: temp/properties/tlsOperation + - type: switch + label: Remove TLS + fullwidth: true + if: + name: isTlsEnabled + type: function + schema: schema/properties/spec/properties/tls/properties/remove + - type: switch + label: Rotate Certificates + fullwidth: true + schema: schema/properties/spec/properties/tls/properties/rotateCertificates + if: + name: isTlsEnabled + type: function + - type: block-layout + label: Issuer Reference + showLabels: true + if: + name: showIssuerRefAndCertificates + type: function + elements: + - type: input + label: API Group + init: + type: func + value: initIssuerRefApiGroup + watcher: + func: initIssuerRefApiGroup + paths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + disable: true + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup + - type: select + label: Kind + options: + - text: Issuer + value: Issuer + - text: ClusterIssuer + value: ClusterIssuer + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/kind + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - type: select + label: Name + loader: + name: getIssuerRefsName + watchPaths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - schema/properties/metadata/properties/namespace + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/name + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/name + - type: block-layout + label: Certificates + showLabels: false + if: + name: showIssuerRefAndCertificates + type: function + loader: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates + elements: + - type: array-object-form + label: Certificates + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/tls/properties/certificates + elements: + - type: select + label: Alias + loader: fetchAliasOptions + disable: disableAlias + schema: alias + validation: + type: required + - type: input + label: Secret Name + schema: secretName + - type: input + label: Duration + schema: duration + - type: input + label: Renew Before + schema: renewBefore + - type: array-item-form + label: Organizations + buttonClass: is-light is-outlined + schema: subject/properties/organizations + element: + type: input + label: Organization + - type: array-item-form + label: Countries + buttonClass: is-light is-outlined + schema: subject/properties/countries + element: + type: input + label: Country + - type: array-item-form + label: Organizational Units + buttonClass: is-light is-outlined + schema: subject/properties/organizationalUnits + element: + type: input + label: Organizational Unit + - type: array-item-form + label: Provinces + buttonClass: is-light is-outlined + schema: subject/properties/provinces + element: + type: input + label: Province + - type: array-item-form + label: DNS Names + buttonClass: is-light is-outlined + schema: dnsNames + element: + type: input + label: DNS Name + - type: array-item-form + label: IP Addresses + buttonClass: is-light is-outlined + schema: ipAddresses + element: + type: input + label: IP Address +# common + - type: block-layout + label: OpsRequest Options + showLabels: true + elements: + - type: time-picker + label: Timeout + subtitle: Specify the maximum time allowed for the operation to complete before it times out + schema: 'schema/properties/spec/properties/timeout' + - type: radio + label: Apply + schema: 'schema/properties/spec/properties/apply' + init: + type: func + value: setApplyToIfReady + options: + - text: IfReady (OpsRequest will be applied if database is ready) + value: IfReady + - text: Always (OpsRequest will always be applied) + value: Always diff --git a/charts/opskubedbcom-proxysqlopsrequest-editor/ui/functions.js b/charts/opskubedbcom-proxysqlopsrequest-editor/ui/functions.js index b2790d8b93..bab4ff7183 100644 --- a/charts/opskubedbcom-proxysqlopsrequest-editor/ui/functions.js +++ b/charts/opskubedbcom-proxysqlopsrequest-editor/ui/functions.js @@ -1,3 +1,4 @@ +const { axios, useOperator, store } = window.vueHelpers || {} const machines = { 'db.t.micro': { resources: { @@ -304,181 +305,229 @@ const machineList = [ 'db.r.24xlarge', ] -async function fetchJsons({ axios, itemCtx }) { - let ui = {} - let language = {} - let functions = {} - const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart +let machinesFromPreset = [] - 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) - } +export const useFunc = (model) => { + const route = store.state?.route - return { - ui: ui.data || {}, - language: language.data || {}, - functions, + 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 returnFalse() { + return true + } -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function isTlsEnabled() { + const dbDetails = getValue(discriminator, '/dbDetails') + return ( + (dbDetails?.spec?.sslMode && + dbDetails?.spec?.sslMode !== 'disabled' && + dbDetails?.spec?.sslMode !== 'disable') || + dbDetails?.spec?.tls + ) + } -async function getNamespaces({ axios, storeGet }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + async function getNamespaces() { + if (storeGet('/route/params/actions')) return [] + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - const resources = (resp && resp.data && resp.data.items) || [] + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, + }) - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + const resources = (resp && resp.data && resp.data.items) || [] -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/namespace') + async function getDbs() { + 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/kubedb.com/v1alpha2/namespaces/${namespace}/proxysqls`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + const namespace = getValue(model, '/metadata/namespace') + // watchDependency('model#/metadata/namespace') - const resources = (resp && resp.data && resp.data.items) || [] + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/proxysqls`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + const resources = (resp && resp.data && resp.data.items) || [] -async function getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - const namespace = getValue(model, '/metadata/namespace') - const name = getValue(model, '/spec/proxyRef/name') + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } - if (namespace && name) { - const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/proxysqls/${name}` - const resp = await axios.get(url) + async function getDbDetails() { + machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] - setDiscriminatorValue('/dbDetails', resp.data || {}) + 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/proxyRef/name') - return resp.data || {} - } else return {} -} + if (namespace && name) { + const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/proxysqls/${name}` + const resp = await axios.get(url) -async function getDbVersions({ axios, storeGet, getValue, discriminator }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + setDiscriminatorValue('/dbDetails', resp.data || {}) - const url = `/clusters/${owner}/${cluster}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/kubedb-ui-presets` + return resp.data || {} + } else return {} + } - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + 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 { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + presetVersions = presets.admin?.databases?.ProxySQL?.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/proxysqlversions`, + { + 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 allowed = found?.spec?.updateConstraints?.allowlist || [] + 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 filteredProxySQLVersions = 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.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.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.includes(item.metadata?.name)) && + isVersionWithinConstraints(item.spec?.version, limit) + ) + }) + setDiscriminatorValue('/filteredVersion', filteredProxySQLVersions) + return filteredProxySQLVersions.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) - presets.status = String(e.status) + return [] } } - try { - const presetVersions = presets.admin?.databases?.ProxySQL?.versions?.available || [] - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null, updateConstraints: null }, - }, - }, - } + function getVersionInfo() { + const filteredVersion = getValue(discriminator, '/filteredVersion') + if (filteredVersion.length) return '' - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/catalog.kubedb.com/v1alpha1/proxysqlversions`, - { - params: queryParams, - }, - ) - - const resources = (resp && resp.data && resp.data.items) || [] + let txt = 'No versions from this list can be selected as the target version: [ ' - 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 allowed = found?.spec?.updateConstraints?.allowlist || [] - 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 filteredProxySQLVersions = 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.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.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.includes(item.metadata?.name)) && - isVersionWithinConstraints(item.spec?.version, limit) - ) + presetVersions.forEach((v, idx) => { + txt = `${txt}"${v}"` + if (idx !== presetVersions.length - 1) txt = txt + ', ' + else txt = txt + ' ]' }) - return filteredProxySQLVersions.map((item) => { + return txt + } + + function getVersion() { + return filteredVersion.map((item) => { const name = (item.metadata && item.metadata.name) || '' const specVersion = (item.spec && item.spec.version) || '' return { @@ -486,799 +535,816 @@ async function getDbVersions({ axios, storeGet, getValue, discriminator }) { value: name, } }) - } catch (e) { - console.log(e) - return [] } -} -function versionCompare(v1, v2) { - const arr1 = v1.split('.').map(Number) - const arr2 = v2.split('.').map(Number) + 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 + 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 + if (num1 > num2) return 1 // v1 is higher + if (num1 < num2) return -1 // v2 is higher + } + return 0 // versions are equal } - 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 + 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 } - return true -} -function ifRequestTypeEqualsTo({ model, getValue, watchDependency }, type) { - const selectedType = getValue(model, '/spec/type') - watchDependency('model#/spec/type') + function ifRequestTypeEqualsTo(type) { + const selectedType = getValue(model, '/spec/type') + // watchDependency('model#/spec/type') - return selectedType === type -} + return selectedType === type + } -function onRequestTypeChange({ model, getValue, commit }) { - 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 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', + } -function disableOpsRequest({ itemCtx, discriminator, getValue, watchDependency }) { - if (itemCtx.value === 'HorizontalScaling') { - const dbType = getDbType({ - discriminator, - getValue, - watchDependency, + Object.keys(reqTypeMapping).forEach((key) => { + if (key !== selectedType) commit('wizard/model$delete', `/spec/${reqTypeMapping[key]}`) }) + } - if (dbType === 'standalone') return true - else return false - } else return false -} + function getDbTls() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') -function getDbTls({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + const { spec } = dbDetails || {} + return spec?.tls || undefined + } - const { spec } = dbDetails || {} - return spec?.tls || undefined -} + function getDbType() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') -function getDbType({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + const { spec } = dbDetails || {} + const { replicas } = spec || {} + let verd = '' - const { spec } = dbDetails || {} - const { replicas } = spec || {} - let verd = '' + if (replicas > 1) { + verd = 'cluster' + } else { + verd = 'standalone' + } - if (replicas > 1) { - verd = 'cluster' - } else { - verd = 'standalone' + return verd } - return verd -} - -function initNamespace({ route }) { - const { namespace } = route.query || {} - return namespace || null -} + function initNamespace() { + const { namespace } = route.query || {} + return namespace || null + } -function initDatabaseRef({ route, watchDependency }) { - watchDependency('model#/metadata/namespace') - const { name } = route.params || {} - return name -} + function initDatabaseRef() { + // watchDependency('model#/metadata/namespace') + const { name } = route.params || {} + return name + } -function asDatabaseOperation(route) { - return !!route.params.actions -} + function asDatabaseOperation() { + return !!route.params.actions + } -function generateOpsRequestNameForClusterUI(getValue, model, route) { - const dbName = getValue(model, '/spec/databaseRef/name') + function generateOpsRequestNameForClusterUI(getValue, model, route) { + const dbName = getValue(model, '/spec/proxyRef/name') - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' - const resources = route.params.resource || '' - const resource = resources.slice(0, -1) + 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 : ''}` -} + const opsName = dbName ? dbName : resource + return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` + } -function showAndInitName({ route, commit, getValue, model, watchDependency }) { - watchDependency('model#/spec/type') - watchDependency('model#/spec/databaseRef/name') - const ver = asDatabaseOperation(route) + function showAndInitName() { + // watchDependency('model#/spec/type') + // watchDependency('model#/spec/proxyRef/name') + const ver = asDatabaseOperation() - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + 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({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/metadata/namespace', - value: `${route.query.namespace}`, - force: true, - }) + 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 } - return !ver -} -function showAndInitDatabaseRef({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/spec/proxyRef/name', - value: `${route.params.name}`, - force: true, - }) - } + function showAndInitNamespace() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/metadata/namespace', + value: `${route.query.namespace}`, + force: true, + }) + } - return !ver -} -function showConfigureOpsrequestLabel({ route }) { - return !asDatabaseOperation(route) -} -function showAndInitOpsRequestType({ route, commit }) { - const ver = asDatabaseOperation(route) - const opMap = { - upgrade: 'UpdateVersion', - updateVersion: 'UpdateVersion', - horizontalscaling: 'HorizontalScaling', - verticalscaling: 'VerticalScaling', - volumeexpansion: 'VolumeExpansion', - restart: 'Restart', - reconfiguretls: 'ReconfigureTLS', - reconfigure: 'Reconfigure', - } - if (ver) { - const operation = route.params.actions - const match = /^(.*)-opsrequest-(.*)$/.exec(operation) - const opstype = match[2] - commit('wizard/model$update', { - path: '/spec/type', - value: opMap[opstype], - force: true, - }) + return !ver } - return !ver -} - -// for config secret -async function getConfigSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + function showAndInitDatabaseRef() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/spec/proxyRef/name', + value: `${route.params.name}`, + force: true, + }) + } - const secrets = (resp && resp.data && resp.data.items) || [] + return !ver + } - const filteredSecrets = secrets + function showConfigureOpsrequestLabel() { + return !asDatabaseOperation() + } - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return filteredSecrets -} + 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, + }) + } + } -function isEqualToValueFromType({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/valueFromType') - const valueFrom = getValue(discriminator, '/valueFromType') - return valueFrom === value -} + return !ver + } -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + // machine profile stuffs + function getMachines(type) { + const presets = storeGet('/kubedbuiPresets') || {} + const dbDetails = getValue(discriminator, '/dbDetails') + const limits = dbDetails?.spec?.podTemplate?.spec?.resources?.requests || { + cpu: '', + memory: '', + } - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + 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 + } - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }) + function setMachine(type) { + const dbDetails = getValue(discriminator, '/dbDetails') + const limits = dbDetails?.spec?.podTemplate?.spec?.resources?.requests || { + cpu: '', + memory: '', + } + const annotations = dbDetails?.metadata?.annotations || {} + const machine = annotations['kubernetes.io/instance-type'] || 'custom' - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + 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 } } - return ans -} -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` + const path = `/spec/verticalScaling/${type}/resources` - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }) + if (obj && Object.keys(obj).length) + commit('wizard/model$update', { + path: path, + value: obj, + force: true, + }) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + // 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, + }) } - return ans -} -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - group, - version, - resource, -) { - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/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) - }) + function isMachineCustom() { + // watchDependency('discriminator#/machine') + const machine = getValue(discriminator, '/machine') + return machine === 'custom' } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) - - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) - } + // for config secret + async function getConfigSecrets() { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = getValue(model, '/metadata/namespace') + // watchDependency('model#/metadata/namespace') - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/core/v1/namespaces/${namespace}/secrets`, + { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }, + ) -// reconfiguration type -function ifReconfigurationTypeEqualsTo({ discriminator, getValue, watchDependency }, value) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - watchDependency('discriminator#/reconfigurationType') + const secrets = (resp && resp.data && resp.data.items) || [] - return reconfigurationType === value -} -function onReconfigurationTypeChange({ commit, discriminator, getValue }) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - if (reconfigurationType === 'remove') { - commit('wizard/model$delete', `/spec/configuration`) + const filteredSecrets = secrets - commit('wizard/model$update', { - path: `/spec/configuration/removeCustomConfig`, - value: true, - force: true, + filteredSecrets.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + item.text = name + item.value = name + return true }) - } else { - commit('wizard/model$delete', `/spec/configuration/configSecret`) - commit('wizard/model$delete', `/spec/configuration/inlineConfig`) - commit('wizard/model$delete', `/spec/configuration/removeCustomConfig`) + return filteredSecrets } -} -function disableReconfigurationType({ getValue, watchDependency, discriminator, itemCtx }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') - - const { spec } = dbDetails || {} - if (itemCtx.value === 'inlineConfig' || itemCtx.value === 'remove') { - if (spec.configSecret) return false - else return true - } else return false -} -// for tls -function hasTlsField({ discriminator, getValue, watchDependency }) { - const tls = getDbTls({ - discriminator, - getValue, - watchDependency, - }) + function createSecretUrl() { + const user = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - return !!tls -} + 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 initIssuerRefApiGroup({ getValue, model, watchDependency, discriminator }) { - const kind = getValue(model, '/spec/tls/issuerRef/kind') - watchDependency('model#/spec/tls/issuerRef/kind') + function isEqualToValueFromType(value) { + // watchDependency('discriminator#/valueFromType') + const valueFrom = getValue(discriminator, '/valueFromType') + return valueFrom === value + } - if (kind) { - const apiGroup = getValue(discriminator, '/dbDetails/spec/tls/issuerRef/apiGroup') - if (apiGroup) return apiGroup - return 'cert-manager.io' - } else return undefined -} + async function getNamespacedResourceList({ namespace, group, version, resource }) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - 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` + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` - 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) + 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 clusterIssuers + + return ans } + async function getResourceList({ group, version, resource }) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - async function getIssuer(url) { - try { - const resp = await axios.get(url) - const resources = (resp && resp.data && resp.data.items) || [] + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + let ans = [] + try { + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, }) - return resources + + const items = (resp && resp.data && resp.data.items) || [] + ans = items } catch (e) { console.log(e) - return [] } - } -} -function initTlsOperation() { - return 'update' -} -function onTlsOperationChange({ discriminator, getValue, commit }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + 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, + }) - commit('wizard/model$delete', '/spec/tls') + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } - 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, + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } }) - commit('wizard/model$delete', '/spec/tls/certificates') - commit('wizard/model$delete', '/spec/tls/rotateCertificates') } -} + async function unNamespacedResourceNames(group, version, resource) { + let resources = await getResourceList({ + group, + version, + resource, + }) -function showIssuerRefAndCertificates({ discriminator, getValue, watchDependency }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') - watchDependency('discriminator#/tlsOperation') - const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } - return verd -} + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -function isIssuerRefRequired({ discriminator, getValue, watchDependency }) { - const hasTls = hasTlsField({ - discriminator, - getValue, - watchDependency, - }) + // MySQL Query Rules + function setMySQLRules() { + const rules = getValue(model, '/spec/configuration/mysqlQueryRules/rules') + const modifiedRules = rules?.map((item) => ({ rules: item })) - return !hasTls -} + setDiscriminatorValue('/mysqlQueryRules', modifiedRules) -function getRequestTypeFromRoute({ route, model, discriminator, getValue, watchDependency }) { - const isDbloading = isDbDetailsLoading({ - discriminator, - model, - getValue, - watchDependency, - }) - const { query } = route || {} - const { requestType } = query || {} - return isDbloading ? '' : requestType || '' -} + return modifiedRules + } -// ************************************** Set db details ***************************************** + function onMySQLRulesChange() { + const rules = getValue(discriminator, '/mysqlQueryRules') + const modifiedRules = rules?.map((item) => item.rules) -function isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - watchDependency('model#/spec/proxyRef/name') - const dbDetails = getValue(discriminator, '/dbDetails') - const dbName = getValue(model, '/spec/proxyRef/name') + commit('wizard/model$update', { + path: '/spec/configuration/mysqlQueryRules/rules', + value: modifiedRules, + force: true, + }) + } - return !dbDetails || !dbName -} + // MySQL Users + function onMySQLUserReqTypeChange() { + const reqType = getValue(model, '/spec/configuration/mysqlUsers/reqType') -function setValueFromDbDetails( - { discriminator, getValue, watchDependency, commit }, - path, - commitPath, -) { - watchDependency('discriminator#/dbDetails') + if (reqType === 'delete') { + const users = getValue(model, '/spec/configuration/mysqlUsers/users') || [] + const mappedUsers = users.map((item) => { + return { + username: item.username, + } + }) - const retValue = getValue(discriminator, `/dbDetails${path}`) + if (mappedUsers && mappedUsers.length) { + commit('wizard/model$update', { + path: '/spec/configuration/mysqlUsers/users', + value: mappedUsers, + force: true, + }) + } + } + } - if (commitPath && retValue) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + function showUserCreationField() { + // watchDependency('model#/spec/configuration/mysqlUsers/reqType') + const reqType = getValue(model, '/spec/configuration/mysqlUsers/reqType') + return !reqType || reqType === 'update' || reqType === 'add' + } - // computed called when tls fields is not visible - if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined + function showUserDeletionField() { + // watchDependency('model#/spec/configuration/mysqlUsers/reqType') + const reqType = getValue(model, '/spec/configuration/mysqlUsers/reqType') + return reqType === 'delete' + } - // 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, - }) + // for tls + function hasTlsField() { + const tls = getDbTls() + + return !!tls } - return retValue || undefined -} + function initIssuerRefApiGroup() { + const kind = getValue(model, '/spec/tls/issuerRef/kind') + // watchDependency('model#/spec/tls/issuerRef/kind') -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} + if (kind) { + return 'cert-manager.io' + } else return undefined + } -function isNamespaceDisabled({ route }) { - const { namespace } = route.query || {} - return !!namespace -} + 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') -function isDatabaseRefDisabled({ route }) { - const { name } = route.params || {} - return !!name -} + 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 [] + } -function onNamespaceChange({ commit }) { - commit('wizard/model$delete', '/spec/type') -} + 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 onDbChange({ commit, axios, storeGet, model, getValue, setDiscriminatorValue }) { - commit('wizard/model$delete', '/spec/type') - getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) -} + function initTlsOperation() { + return 'update' + } + function onTlsOperationChange() { + const tlsOperation = getValue(discriminator, '/tlsOperation') -/**************************************** MySQL Query Rules *******************************/ + commit('wizard/model$delete', '/spec/tls') -function onMySQLRulesChange({ discriminator, getValue, commit }) { - const rules = getValue(discriminator, '/mysqlQueryRules') - const modifiedRules = rules?.map((item) => item.rules) + if (tlsOperation === 'rotate') { + commit('wizard/model$update', { + path: '/spec/tls/rotateCertificates', + value: true, + force: true, + }) + } else if (tlsOperation === 'remove') { + commit('wizard/model$update', { + path: '/spec/tls/remove', + value: true, + force: true, + }) + } + } - commit('wizard/model$update', { - path: '/spec/configuration/mysqlQueryRules/rules', - value: modifiedRules, - force: true, - }) -} + function showIssuerRefAndCertificates() { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // watchDependency('discriminator#/tlsOperation') + const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' -function setMySQLRules({ model, getValue, setDiscriminatorValue }) { - const rules = getValue(model, '/spec/configuration/mysqlQueryRules/rules') - const modifiedRules = rules?.map((item) => ({ rules: item })) + return verd + } - setDiscriminatorValue('/mysqlQueryRules', modifiedRules) + function isIssuerRefRequired() { + const hasTls = hasTlsField() + return hasTls ? false : '' + } - return modifiedRules -} + function getRequestTypeFromRoute() { + const isDbloading = isDbDetailsLoading() + const { query } = route || {} + const { requestType } = query || {} + return isDbloading ? '' : requestType || '' + } + + function isDbDetailsLoading() { + // watchDependency('discriminator#/dbDetails') + // watchDependency('model#/spec/proxyRef/name') + const dbDetails = getValue(discriminator, '/dbDetails') + const dbName = getValue(model, '/spec/proxyRef/name') -/**************************************** MySQL Users *******************************/ + return !dbDetails || !dbName + } -function onMySQLUserReqTypeChange({ model, getValue, commit }) { - const reqType = getValue(model, '/spec/configuration/mysqlUsers/reqType') + function setValueFromDbDetails(path, commitPath) { + const retValue = getValue(discriminator, `/dbDetails${path}`) - if (reqType === 'delete') { - const users = getValue(model, '/spec/configuration/mysqlUsers/users') || [] - const mappedUsers = users.map((item) => { - return { - username: item.username, - } - }) + if (commitPath) { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // computed called when tls fields is not visible + if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined - if (mappedUsers && mappedUsers.length) { + // direct model update required for reusable element. + // computed property is not applicable for reusable element commit('wizard/model$update', { - path: '/spec/configuration/mysqlUsers/users', - value: mappedUsers, + path: commitPath, + value: retValue, force: true, }) } + return retValue || undefined } -} -function showUserCreationField({ model, getValue, watchDependency }) { - watchDependency('model#/spec/configuration/mysqlUsers/reqType') - const reqType = getValue(model, '/spec/configuration/mysqlUsers/reqType') - return !reqType || reqType === 'update' || reqType === 'add' -} + function getAliasOptions() { + return ['server', 'client', 'metrics-exporter'] + } -function showUserDeletionField({ model, getValue, watchDependency }) { - watchDependency('model#/spec/configuration/mysqlUsers/reqType') - const reqType = getValue(model, '/spec/configuration/mysqlUsers/reqType') - return reqType === 'delete' -} + function isNamespaceDisabled() { + const { namespace } = route.query || {} + return !!namespace + } -function setApplyToIfReady() { - return 'IfReady' -} + function isDatabaseRefDisabled() { + const { name } = route.params || {} + return !!name + } -function isVerticalScaleTopologyRequired({ watchDependency, getValue, discriminator, commit }) { - watchDependency('discriminator#/topologyKey') - watchDependency('discriminator#/topologyValue') + function onNamespaceChange() { + commit('wizard/model$delete', '/spec/type') + } - const key = getValue(discriminator, '/topologyKey') - const value = getValue(discriminator, '/topologyValue') - const path = `/spec/verticalScaling/proxysql/topology` + function onDbChange() { + commit('wizard/model$delete', '/spec/type') + getDbDetails() + } - if (key || value) { - commit('wizard/model$update', { - path: path, - value: { key, value }, - force: true, - }) - return true - } else { - commit('wizard/model$delete', path) - return false + function setApplyToIfReady() { + return 'IfReady' } -} -// machine profile stuffs -let machinesFromPreset = [] + function isVerticalScaleTopologyRequired() { + // watchDependency('discriminator#/topologyKey') + // watchDependency('discriminator#/topologyValue') -function getMachines({ storeGet }) { - const presets = storeGet('/kubedbuiPresets') || {} - const avlMachines = presets.admin?.machineProfiles?.available || [] - let arr = [] - if (avlMachines.length) { - arr = avlMachines.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - 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 } - } else return { text: machine, value: machine } - } - }) - } else { - arr = machineList - .map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + const key = getValue(discriminator, '/topologyKey') + const value = getValue(discriminator, '/topologyValue') + const path = `/spec/verticalScaling/proxysql/topology` + + if (key || value) { + commit('wizard/model$update', { + path: path, + value: { key, value }, + force: true, }) - .filter((val) => !!val) + return '' + } else { + commit('wizard/model$delete', path) + return false + } } - return arr -} - -function setMachine({ getValue, discriminator, storeGet }) { - const dbDetails = getValue(discriminator, '/dbDetails') - const annotations = dbDetails?.metadata?.annotations || {} - const machine = annotations['kubernetes.io/instance-type'] || 'custom' - machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] + function fetchAliasOptions() { + return getAliasOptions ? getAliasOptions() : [] + } - const machinePresets = machinesFromPreset.find((item) => item.id === machine) - if (machinePresets) return machine - else return 'custom' -} + function validateNewCertificates({ itemCtx }) { + const addedAliases = (model && model.map((item) => item.alias)) || [] -function onMachineChange({ getValue, discriminator, commit, model }, type, valPath) { - let selectedMachine = '' - selectedMachine = getValue(discriminator, '/machine') - const machine = machinesFromPreset.find((item) => item.id === selectedMachine) + if (addedAliases.includes(itemCtx.alias) && itemCtx.isCreate) { + return { isInvalid: true, message: 'Alias already exists' } + } + return {} + } - let obj = {} - if (selectedMachine !== 'custom') { - if (machine) obj = { limits: { ...machine?.limits }, requests: { ...machine?.limits } } - else obj = machines[selectedMachine]?.resources - } else { - const val = getValue(discriminator, `/dbDetails${valPath}`) || {} - obj = Array.isArray(val) ? val[0]?.resources : { ...val } + function disableAlias() { + return !!(model && model.alias) } - const path = `/spec/verticalScaling/${type}/resources` + function setExporter(type) { + let path = `/dbDetails/spec/monitor/prometheus/exporter/resources/limits/${type}` + const limitVal = getValue(discriminator, path) - if (obj && Object.keys(obj).length) - commit('wizard/model$update', { - path: path, - value: obj, - force: true, - }) + if (!limitVal) { + path = `/dbDetails/spec/monitor/prometheus/exporter/resources/requests/${type}` + const reqVal = getValue(discriminator, path) - // update metadata.annotations - const annotations = getValue(model, '/metadata/annotations') || {} - if (selectedMachine === 'custom') commit('wizard/model$delete', '/metadata/annotations') - else { - annotations['kubernetes.io/instance-type'] = selectedMachine - if (machinesFromPreset.length) + 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: '/metadata/annotations', - value: annotations, + path: commitPath, + value: val, force: true, }) } -} - -function isMachineCustom({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/machine') - const machine = getValue(discriminator, '/machine') - return machine === 'custom' -} -return { - fetchJsons, - returnFalse, - getNamespaces, - getDbs, - getDbDetails, - getDbVersions, - ifRequestTypeEqualsTo, - onRequestTypeChange, - getDbTls, - getDbType, - initNamespace, - initDatabaseRef, - isRancherManaged, - showAndInitName, - showAndInitNamespace, - showAndInitDatabaseRef, - showConfigureOpsrequestLabel, - showAndInitOpsRequestType, - - getConfigSecrets, - isEqualToValueFromType, - disableOpsRequest, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - ifReconfigurationTypeEqualsTo, - onReconfigurationTypeChange, - disableReconfigurationType, - hasTlsField, - initIssuerRefApiGroup, - getIssuerRefsName, - initTlsOperation, - onTlsOperationChange, - showIssuerRefAndCertificates, - isIssuerRefRequired, - getRequestTypeFromRoute, - isDbDetailsLoading, - setValueFromDbDetails, - getAliasOptions, - isNamespaceDisabled, - isDatabaseRefDisabled, - onNamespaceChange, - onDbChange, - setMySQLRules, - onMySQLRulesChange, - onMySQLUserReqTypeChange, - showUserCreationField, - showUserDeletionField, - setApplyToIfReady, - isVerticalScaleTopologyRequired, - - getMachines, - setMachine, - onMachineChange, - isMachineCustom, + return { + setExporter, + onExporterResourceChange, + fetchAliasOptions, + validateNewCertificates, + disableAlias, + isRancherManaged, + fetchJsons, + returnFalse, + getNamespaces, + getDbs, + getDbDetails, + getDbVersions, + getVersionInfo, + isVersionEmpty, + getVersion, + ifRequestTypeEqualsTo, + onRequestTypeChange, + getDbTls, + getDbType, + initNamespace, + initDatabaseRef, + showAndInitName, + showAndInitNamespace, + showAndInitDatabaseRef, + showConfigureOpsrequestLabel, + showAndInitOpsRequestType, + getConfigSecrets, + createSecretUrl, + isEqualToValueFromType, + getNamespacedResourceList, + getResourceList, + resourceNames, + unNamespacedResourceNames, + hasTlsField, + initIssuerRefApiGroup, + getIssuerRefsName, + initTlsOperation, + onTlsOperationChange, + showIssuerRefAndCertificates, + isIssuerRefRequired, + getRequestTypeFromRoute, + isDbDetailsLoading, + setValueFromDbDetails, + getAliasOptions, + isNamespaceDisabled, + isDatabaseRefDisabled, + onDbChange, + onNamespaceChange, + setApplyToIfReady, + isVerticalScaleTopologyRequired, + getMachines, + setMachine, + onMachineChange, + isMachineCustom, + setMySQLRules, + onMySQLRulesChange, + onMySQLUserReqTypeChange, + showUserCreationField, + showUserDeletionField, + isTlsEnabled, + } } diff --git a/charts/opskubedbcom-rabbitmqopsrequest-editor/ui/create-ui.yaml b/charts/opskubedbcom-rabbitmqopsrequest-editor/ui/create-ui.yaml index 40c9676966..be01348874 100644 --- a/charts/opskubedbcom-rabbitmqopsrequest-editor/ui/create-ui.yaml +++ b/charts/opskubedbcom-rabbitmqopsrequest-editor/ui/create-ui.yaml @@ -1,403 +1,627 @@ -steps: -- form: - discriminator: - dbDetails: - type: object +type: multi-step-form +step: + - type: single-step-form + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - schema: - $ref: discriminator#/properties/dbDetails - type: input - - if: showAndInitName - label: - text: labels.op_req_name - required: true - schema: - $ref: schema#/properties/metadata/properties/name - type: input - - computed: initNamespace - disabled: isNamespaceDisabled - fetch: getNamespaces - hasGroup: isRancherManaged - if: showAndInitNamespace - label: - text: labels.namespace - onChange: onNamespaceChange - required: true - schema: - $ref: schema#/properties/metadata/properties/namespace - type: select - - computed: initDatabaseRef - disabled: isDatabaseRefDisabled - fetch: getDbs - if: showAndInitDatabaseRef - label: - text: labels.databaseRef - onChange: onDbChange - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/databaseRef/properties/name - type: select - - if: showConfigureOpsrequestLabel - label: - text: labels.config_ops_request - type: label-element - - computed: getRequestTypeFromRoute - disabled: isDbDetailsLoading - hasDescription: true - if: showAndInitOpsRequestType - individualItemDisabilityCheck: disableOpsRequest - label: - text: labels.ops_request_type - onChange: onRequestTypeChange - options: - - description: options.UpdateVersion.description - text: options.UpdateVersion.text - value: UpdateVersion - - description: options.HorizontalScaling.description - text: options.HorizontalScaling.text - value: HorizontalScaling - - description: options.VerticalScaling.description - text: options.VerticalScaling.text - value: VerticalScaling - - description: options.VolumeExpansion.description - text: options.VolumeExpansion.text - value: VolumeExpansion - - description: options.Restart.description - text: options.Restart.text - value: Restart - - description: options.Reconfigure.description - text: options.Reconfigure.text - value: Reconfigure - - description: options.ReconfigureTLS.description - text: options.ReconfigureTLS.text - value: ReconfigureTLS - schema: - $ref: schema#/properties/spec/properties/type - type: radio - - elements: - - computed: setValueFromDbDetails|/spec/version - fetch: getDbVersions - label: - text: labels.targetVersion - schema: - $ref: schema#/properties/spec/properties/updateVersion/properties/targetVersion - type: select - if: ifRequestTypeEqualsTo|UpdateVersion - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/replicas - if: ifDbTypeEqualsTo|Combined|horizontalScaling - label: - text: Node - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/node - type: input - if: ifRequestTypeEqualsTo|HorizontalScaling - label: - text: Horizontal Scaling Form - type: single-step-form - - elements: - - discriminator: - machine: - default: "" - type: string - elements: - - computed: setMachine - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|node|/spec/podTemplate/spec/containers - schema: - $ref: discriminator#/machine - type: select - - if: isMachineCustom - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/resources - type: resource-input-form - - label: - text: Node Selection Policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/nodeSelectionPolicy - type: select - - elements: - - label: - text: key - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/topology/properties/key - type: input - - label: - text: value - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/topology/properties/value - type: input - label: - text: Topology - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/topology - show_label: true - type: single-step-form - label: - text: Node - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|VerticalScaling - type: single-step-form - - elements: - - elements: - - computed: setValueFromDbDetails|/spec/storage/resources/requests/storage - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/node - type: input - validationRuleObject: - func: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/node - label: - text: Node - schema: - $ref: schema#/properties/spec/properties/volumeExpansion - show_label: true - type: single-step-form - - label: - text: Mode +# common + - type: input + label: op_req_name + if: + type: function + name: showAndInitName + validation: + type: required + schema: schema/properties/metadata/properties/name + - type: select + label: Namespace + if: + type: function + name: showAndInitNamespace + init: + type: func + value: initNamespace + disable: isNamespaceDisabled + loader: getNamespaces + validation: + type: required + hasGroup: isRancherManaged + schema: schema/properties/metadata/properties/namespace + - type: select + label: Database Ref + if: + type: function + name: showAndInitDatabaseRef + loader: + name: getDbs + watchPaths: + - schema/properties/metadata/properties/namespace + init: + type: func + value: initDatabaseRef + validation: + type: required + disable: isDatabaseRefDisabled + refresh: true + schema: schema/properties/spec/properties/databaseRef/properties/name + watcher: + func: onDbChange + paths: + - schema/properties/spec/properties/databaseRef/properties/name + - type: label-element + label: config_ops_request + if: + type: function + name: showConfigureOpsrequestLabel + - type: radio + label: Type of Ops Request + if: + type: function + name: showAndInitOpsRequestType options: - - text: Offline - value: Offline - - text: Online - value: Online - required: true - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/mode - type: select - if: ifRequestTypeEqualsTo|VolumeExpansion - label: - text: Volume Expansion Form - type: single-step-form - - elements: - - discriminator: - reconfigurationType: - type: string + - 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 + init: + type: func + value: getRequestTypeFromRoute + disable: isDbDetailsLoading + watcher: + func: isDbDetailsLoading + paths: + - temp/dbDetails + - schema/properties/spec/properties/databaseRef/properties/name + isHorizontal: true + schema: schema/properties/spec/properties/type +# UpdateVersion + - type: block-layout + showLabels: true + label: Version + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|UpdateVersion elements: - - label: - text: labels.reconfigurationType - onChange: onReconfigurationTypeChange - options: - - text: Select New Config Secret - value: selectNewConfigSecret - - text: Apply Config - value: applyConfig - - text: Remove - value: remove - required: true - schema: - $ref: discriminator#/properties/reconfigurationType - type: radio - - elements: - - add_new_button: - label: labels.createConfig - target: _blank - url: - function: createSecretUrl - computed: setValueFromDbDetails|/spec/configSecret/name - fetch: getConfigSecrets - label: - text: labels.configSecret - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret/properties/name - type: select - if: ifReconfigurationTypeEqualsTo|selectNewConfigSecret - label: - text: Configuration config secret - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret - type: single-step-form - - addFormLabel: labels.applyConfig.label - element: - discriminator: - configArray: - emitAs: applyConfig - type: array + - type: select-compare + label: Target Version + subtitle: Select the desired RabbitMQ version to which you want to update your database. + init: + type: func + value: setValueFromDbDetails|/spec/version + loader: getDbVersions + schema: schema/properties/spec/properties/updateVersion/properties/targetVersion + - type: info + label: '' + loader: + name: getVersionInfo + watchPaths: + - temp/properties/filteredVersion + if: + type: function + name: isVersionEmpty +# Horizontal Scale + - type: block-layout + label: Horizontal Scaling Form + showLabels: true + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|HorizontalScaling + elements: + - type: horizontal-layout elements: - - label: - text: labels.applyConfig.key - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/key - type: input - - label: - text: labels.applyConfig.value - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/value - type: editor - type: single-step-form - if: ifReconfigurationTypeEqualsTo|applyConfig - label: - text: labels.applyConfig.label - onChange: onApplyconfigChange - required: true - schema: - $ref: discriminator#/properties/applyConfig - tableContents: - - inTableColumn: true - label: - text: labels.applyConfig.key - path: key - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.applyConfig.value - path: value - type: value - typeOfValue: code - type: single-step-form-array - - if: returnFalse - label: - text: labels.removeCustomConfig - schema: - $ref: schema#/properties/spec/properties/configuration/properties/removeCustomConfig - type: switch - label: - text: labels.configuration - schema: - $ref: schema#/properties/spec/properties/configuration - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|Reconfigure - label: - text: Reconfigure Form - type: single-step-form - - discriminator: - tlsOperation: - default: update - type: string - elements: - - computed: initTlsOperation - if: hasTlsField - label: - text: labels.tlsOperation - onChange: onTlsOperationChange - options: - - text: Update - value: update - - text: Rotate - value: rotate - - text: Remove - value: remove - schema: - $ref: discriminator#/properties/tlsOperation - type: radio - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/remove - type: switch - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/rotateCertificates - type: switch - - elements: - - computed: initIssuerRefApiGroup - disabled: true - label: - text: labels.api_group - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup - type: input - - computed: setValueFromDbDetails|/spec/tls/issuerRef/kind - label: - text: labels.kind - options: - - text: Issuer - value: Issuer - - text: ClusterIssuer - value: ClusterIssuer - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/kind - sortable: true - type: select - - allowUserDefinedOption: true - computed: setValueFromDbDetails|/spec/tls/issuerRef/name - fetch: getIssuerRefsName - label: - text: labels.name - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/name - sortable: true - type: select - if: showIssuerRefAndCertificates - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef - type: single-step-form - - alias: reusable_certificates - chart: - name: uibytebuildersdev-component-certificates - version: v0.29.0 - computed: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates - functionCallbacks: - getAliasOptions: - $ref: functions#/getAliasOptions - if: showIssuerRefAndCertificates - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/spec/properties/tls/properties/certificates - type: reusable-element - if: ifRequestTypeEqualsTo|ReconfigureTLS - label: - text: labels.tls - schema: - $ref: schema#/properties/spec/properties/tls - type: single-step-form - - label: - text: labels.timeout - options: - - text: 5 minutes - value: 5m - - text: 10 minutes - value: 10m - - text: 30 minutes - value: 30m - - text: 1 hour - value: 1h - - text: 2 hours - value: 2h - - text: 5 hours - value: 5h - - text: 10 hours - value: 10h - schema: - $ref: schema#/properties/spec/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: labels.apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/spec/properties/apply - type: radio - type: single-step-form - id: basic - title: steps.0.label -type: multi-step-form + - type: input-compare + label: Node + header: Node + subtitle: Define the total number of nodes for the database. Increasing nodes improves fault tolerance and load distribution, while reducing nodes conserves resources + if: + type: function + name: ifDbTypeEqualsTo|Combined|horizontalScaling + init: + type: func + value: setValueFromDbDetails|/spec/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/node + - type: info + hasIcon: true + label: Each node represents an independent copy of your database. For example, setting this to 3 creates three copies of the database for better availability. + if: + type: function + name: ifDbTypeEqualsTo|Combined|horizontalScaling +# vertical Scale + - type: block-layout + if: + type: function + name: ifRequestTypeEqualsTo|VerticalScaling + elements: + - type: block-layout + label: Node + showLabels: false + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines + init: + type: func + value: setMachine + watcher: + func: onMachineChange|node|/spec/podTemplate/spec/containers + paths: + - temp/properties/machine + schema: temp/properties/machine + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/node/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired + schema: schema/properties/spec/properties/verticalScaling/properties/node/properties/topology/properties/key + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired + schema: schema/properties/spec/properties/verticalScaling/properties/node/properties/topology/properties/value + - type: block-layout + label: Exporter + showLabels: true + hideBlock: true + elements: + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setExporter|cpu + type: input + 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 + watcher: + func: onExporterResourceChange|memory + paths: + - schema/properties/spec/properties/verticalScaling/properties/exporter/properties/resources/properties/limits/properties/memory +# Volume Expansion + - type: block-layout + label: Volume Expansion Form + if: + type: function + name: ifRequestTypeEqualsTo|VolumeExpansion + elements: + - type: horizontal-layout + elements: + - type: block-layout + elements: + - type: label-element + 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: select + label: Mode + options: + - text: Offline + value: Offline + - text: Online + value: Online + validation: + type: required + schema: schema/properties/spec/properties/volumeExpansion/properties/mode + - type: block-layout + label: RabbitMQ volume expansion + showLabels: true + fixedBlock: true + elements: + - type: horizontal-layout + elements: + - type: input-compare + header: Storage Size + label: Storage Size + subtitle: How much extra storage does your database need? Specify the size(e.g. 2Gi for 2 gigabytes) so we can allocate it correctly + init: + type: func + value: setValueFromDbDetails|/spec/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/node + schema: schema/properties/spec/properties/volumeExpansion/properties/node + - type: info + hasIcon: true + label: Storage expansion allows you to increase your database's disk space without downtime (Online mode) or with brief downtime (Offline mode). +# Reconfigure + - type: block-layout + label: Reconfigure Form + if: + name: ifRequestTypeEqualsTo|Reconfigure + type: function + loader: + name: fetchConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + elements: + - type: block-layout + label: Configuration + elements: + - type: label-element + label: '' + subtitle: Select a new configuration secret, apply a custom configuration, or remove an existing setup to update your database settings + - type: tab-layout + label: New Config Secret + schema: temp/properties/reconfigurationType + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + elements: + - type: block-layout + label: Config Secret + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret + type: function + elements: + - type: label-element + label: Config Secret + subtitle: Select a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: schema/properties/spec/properties/configuration/properties/configSecret/properties/name + refresh: true + label: Config Secret + loader: + name: getConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/createSecret/properties/status + init: + type: func + value: setValueFromDbDetails|/spec/configSecret/name + watcher: + func: onCreateSecretChange + paths: + - temp/properties/createSecret/properties/status + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|create + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + - type: block-layout + label: Create a New Config Secret + showLabels: true + if: + type: function + name: isCreateSecret + hasButton: + text: Save + hasCancel: cancelCreateSecret + action: createNewConfigSecret + elements: + - type: input + label: Secret Name + schema: temp/properties/createSecret/properties/name + validation: + type: required + - type: array-object-form + label: String Data + schema: temp/properties/createSecret/properties/data + buttonClass: is-light is-outlined + validation: + type: required + elements: + - type: select + label: Key + schema: key + loader: + name: onSelectedSecretChange + watchPaths: + - temp/properties/createSecret/properties/data + validation: + type: required + - type: textarea + label: Value + schema: value + - type: multi-file-editor + editorHeight: 500px + readonly: true + if: + type: function + name: isNotCreateSecret + loader: + name: onNewConfigSecretChange + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + schema: temp/properties/newConfigSecret + - type: block-layout + label: ApplyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig + type: function + elements: + - type: label-element + 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). + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfiguration + refresh: true + label: Configuration + loader: getConfigSecretsforAppyConfig + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|apply + watchPaths: + - temp/properties/selectedConfiguration + - type: multi-file-editor + editorHeight: 500px + schema: temp/properties/applyConfig + loader: + name: setApplyConfig + watchPaths: + - temp/properties/selectedConfiguration + watcher: + func: onApplyconfigChange + paths: + - temp/properties/applyConfig + - type: block-layout + label: Remove + if: + name: ifReconfigurationTypeEqualsTo|remove + type: function + elements: + - type: label-element + label: Remove + subtitle: Selected a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfigurationRemove + refresh: true + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|remove + watchPaths: + - temp/properties/selectedConfigurationRemove + - type: multi-file-editor + editorHeight: 500px + readonly: true + init: + type: func + value: onRemoveConfigChange + watcher: + func: onRemoveConfigChange + paths: + - temp/properties/selectedConfigurationRemove + schema: temp/properties/removeConfig +# Reconfigure TLS + - type: block-layout + label: TLS + if: + name: ifRequestTypeEqualsTo|ReconfigureTLS + type: function + elements: + - type: radio + label: TLS Operation + if: + name: hasTlsField + type: function + options: + - text: Update + value: update + - text: Rotate + value: rotate + - text: Remove + value: remove + init: + type: func + value: initTlsOperation + schema: temp/properties/tlsOperation + - type: switch + label: Remove TLS + fullwidth: true + if: + name: isTlsEnabled + type: function + schema: schema/properties/spec/properties/tls/properties/remove + - type: switch + label: Rotate Certificates + fullwidth: true + schema: schema/properties/spec/properties/tls/properties/rotateCertificates + if: + name: isTlsEnabled + type: function + - type: block-layout + label: Issuer Reference + showLabels: true + if: + name: showIssuerRefAndCertificates + type: function + elements: + - type: input + label: API Group + init: + type: func + value: initIssuerRefApiGroup + watcher: + func: initIssuerRefApiGroup + paths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + disable: true + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup + - type: select + label: Kind + options: + - text: Issuer + value: Issuer + - text: ClusterIssuer + value: ClusterIssuer + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/kind + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - type: select + label: Name + loader: + name: getIssuerRefsName + watchPaths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - schema/properties/metadata/properties/namespace + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/name + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/name + - type: block-layout + label: Certificates + showLabels: false + if: + name: showIssuerRefAndCertificates + type: function + loader: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates + elements: + - type: array-object-form + label: Certificates + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/tls/properties/certificates + elements: + - type: select + label: Alias + loader: fetchAliasOptions + disable: disableAlias + schema: alias + validation: + type: required + - type: input + label: Secret Name + schema: secretName + - type: input + label: Duration + schema: duration + - type: input + label: Renew Before + schema: renewBefore + - type: array-item-form + label: Organizations + buttonClass: is-light is-outlined + schema: subject/properties/organizations + element: + type: input + label: Organization + - type: array-item-form + label: Countries + buttonClass: is-light is-outlined + schema: subject/properties/countries + element: + type: input + label: Country + - type: array-item-form + label: Organizational Units + buttonClass: is-light is-outlined + schema: subject/properties/organizationalUnits + element: + type: input + label: Organizational Unit + - type: array-item-form + label: Provinces + buttonClass: is-light is-outlined + schema: subject/properties/provinces + element: + type: input + label: Province + - type: array-item-form + label: DNS Names + buttonClass: is-light is-outlined + schema: dnsNames + element: + type: input + label: DNS Name + - type: array-item-form + label: IP Addresses + buttonClass: is-light is-outlined + schema: ipAddresses + element: + type: input + label: IP Address +# common + - type: block-layout + label: OpsRequest Options + showLabels: true + elements: + - type: time-picker + label: Timeout + schema: 'schema/properties/spec/properties/timeout' + - type: radio + label: apply + schema: 'schema/properties/spec/properties/apply' + init: + type: func + value: setApplyToIfReady + options: + - text: IfReady (OpsRequest will be applied if database is ready) + value: IfReady + - text: Always (OpsRequest will always be applied) + value: Always diff --git a/charts/opskubedbcom-rabbitmqopsrequest-editor/ui/functions.js b/charts/opskubedbcom-rabbitmqopsrequest-editor/ui/functions.js index bdf6692fa2..ef09d63222 100644 --- a/charts/opskubedbcom-rabbitmqopsrequest-editor/ui/functions.js +++ b/charts/opskubedbcom-rabbitmqopsrequest-editor/ui/functions.js @@ -1,3 +1,4 @@ +const { axios, useOperator, store, useToast } = window.vueHelpers || {} const machines = { 'db.t.micro': { resources: { @@ -304,181 +305,236 @@ const machineList = [ 'db.r.24xlarge', ] -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) - } +const configSecretKeys = ['rabbitmq.conf'] +let machinesFromPreset = [] - return { - ui: ui.data || {}, - language: language.data || {}, - functions, - } -} +export const useFunc = (model) => { + const route = store.state?.route + const toast = useToast() -function returnFalse() { - return false -} + const { getValue, storeGet, discriminator, setDiscriminatorValue, commit } = useOperator( + model, + store.state, + ) -async function getNamespaces({ axios, storeGet }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + showAndInitOpsRequestType() - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + async function fetchJsons({ axios, itemCtx }) { + let ui = {} + let language = {} + let functions = {} + const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart - const resources = (resp && resp.data && resp.data.items) || [] + 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}`, + ) + const evalFunc = new Function(functionString.data || '') + functions = evalFunc() + } catch (e) { + console.log(e) + } - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' return { - text: name, - value: name, + ui: ui.data || {}, + language: language.data || {}, + functions, } - }) -} + } -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function returnFalse() { + return false + } -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function isTlsEnabled() { + const dbDetails = getValue(discriminator, '/dbDetails') + return ( + (dbDetails?.spec?.sslMode && + dbDetails?.spec?.sslMode !== 'disabled' && + dbDetails?.spec?.sslMode !== 'disable') || + dbDetails?.spec?.tls + ) + } - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/namespace') + 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/kubedb.com/v1alpha2/namespaces/${namespace}/rabbitmqs`, - { + 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) || [] + const resources = (resp && resp.data && resp.data.items) || [] - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -async function getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) { - 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') + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } - if (namespace && name) { - const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/rabbitmqs/${name}` - const resp = await axios.get(url) + async function getDbs() { + if (storeGet('/route/params/actions')) return [] + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - setDiscriminatorValue('/dbDetails', resp.data || {}) + const namespace = getValue(model, '/metadata/namespace') + // watchDependency('model#/metadata/namespace') - return resp.data || {} - } else return {} -} + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/rabbitmqs`, + { + 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}/rabbitmqs/${name}` + const resp = await axios.get(url) -async function getDbVersions({ axios, storeGet, getValue, discriminator }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + setDiscriminatorValue('/dbDetails', resp.data || {}) - const url = `/clusters/${owner}/${cluster}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/kubedb-ui-presets` + 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) + } + } - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { try { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + presetVersions = presets.admin?.databases?.RabbitMQ?.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/rabbitmqversions`, + { + 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 allowed = found?.spec?.updateConstraints?.allowlist || [] + const limit = allowed.length ? allowed[0] : '0.0' + + const filteredRabbitMQVersions = sortedVersions.filter((item) => { + if (limit === '0.0') + return ( + !item.spec?.deprecated && + (presets.status === '404' || presetVersions.includes(item.metadata?.name)) && + versionCompare(item.spec?.version, ver) >= 0 + ) + else if (!limit.match(/^(>=|<=|>|<)/)) + return ( + !item.spec?.deprecated && + (presets.status === '404' || presetVersions.includes(item.metadata?.name)) && + item.spec?.version === limit + ) + else + return ( + !item.spec?.deprecated && + (presets.status === '404' || presetVersions.includes(item.metadata?.name)) && + isVersionWithinConstraints(item.spec?.version, limit) + ) + }) + + setDiscriminatorValue('/filteredVersion', filteredRabbitMQVersions) + return filteredRabbitMQVersions.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) - presets.status = String(e.status) + return [] } } - try { - const presetVersions = presets.admin?.databases?.RabbitMQ?.versions?.available || [] - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null, updateConstraints: null }, - }, - }, - } + function getVersionInfo() { + const filteredVersion = getValue(discriminator, '/filteredVersion') + if (filteredVersion.length) return '' - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/catalog.kubedb.com/v1alpha1/rabbitmqversions`, - { - params: queryParams, - }, - ) + let txt = 'No versions from this list can be selected as the target version: [ ' - 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 allowed = found?.spec?.updateConstraints?.allowlist || [] - 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 filteredRabbitMQVersions = 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.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.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.includes(item.metadata?.name)) && - isVersionWithinConstraints(item.spec?.version, limit) - ) + presetVersions.forEach((v, idx) => { + txt = `${txt}"${v}"` + if (idx !== presetVersions.length - 1) txt = txt + ', ' + else txt = txt + ' ]' }) - return filteredRabbitMQVersions.map((item) => { + return txt + } + + function getVersion() { + return filteredVersion.map((item) => { const name = (item.metadata && item.metadata.name) || '' const specVersion = (item.spec && item.spec.version) || '' return { @@ -486,291 +542,325 @@ async function getDbVersions({ axios, storeGet, getValue, discriminator }) { value: name, } }) - } catch (e) { - console.log(e) - return [] } -} -function versionCompare(v1, v2) { - const arr1 = v1.split('.').map(Number) - const arr2 = v2.split('.').map(Number) + 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 + 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 + if (num1 > num2) return 1 + if (num1 < num2) return -1 + } + return 0 } - 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 + 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 } - return true -} -function ifRequestTypeEqualsTo({ model, getValue, watchDependency }, type) { - const selectedType = getValue(model, '/spec/type') - watchDependency('model#/spec/type') + function ifRequestTypeEqualsTo(type) { + const selectedType = getValue(model, '/spec/type') + // watchDependency('model#/spec/type') - return selectedType === type -} + return selectedType === type + } -function onRequestTypeChange({ model, getValue, commit }) { - 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 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', + } -function disableOpsRequest({ itemCtx, discriminator, getValue, watchDependency }) { - if (itemCtx.value === 'HorizontalScaling') { - const dbType = getDbType({ - discriminator, - getValue, - watchDependency, + Object.keys(reqTypeMapping).forEach((key) => { + if (key !== selectedType) commit('wizard/model$delete', `/spec/${reqTypeMapping[key]}`) }) + } - if (dbType === 'Standalone') return true - else return false - } else return false -} + function disableOpsRequest() { + if (itemCtx.value === 'HorizontalScaling') { + const dbType = getDbType() -function getDbTls({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + if (dbType === 'Standalone') return true + else return false + } else return false + } - const { spec } = dbDetails || {} - return spec?.tls || undefined -} + function getDbTls() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') -function getDbType({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') - const { spec } = dbDetails || {} - const { topology } = spec || {} - if (topology) return 'Topology' - else return 'Combined' -} + const { spec } = dbDetails || {} + return spec?.tls || undefined + } -function initNamespace({ route }) { - const { namespace } = route.query || {} - return namespace || null -} + function getDbType() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') + const { spec } = dbDetails || {} + const { topology } = spec || {} + if (topology) return 'Topology' + else return 'Combined' + } -function initDatabaseRef({ route, watchDependency }) { - watchDependency('model#/metadata/namespace') - const { name } = route.params || {} - return name -} + function initNamespace() { + const { namespace } = route.query || {} + return namespace || null + } -function asDatabaseOperation(route) { - return !!route.params.actions -} + function initDatabaseRef() { + // watchDependency('model#/metadata/namespace') + const { name } = route.params || {} + return name + } -function generateOpsRequestNameForClusterUI(getValue, model, route) { - const dbName = getValue(model, '/spec/databaseRef/name') + function asDatabaseOperation() { + return !!route.params.actions + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + function generateOpsRequestNameForClusterUI(getValue, model, route) { + const dbName = getValue(model, '/spec/databaseRef/name') - const resources = route.params.resource || '' - const resource = resources.slice(0, -1) + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' - const opsName = dbName ? dbName : resource - return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` -} + const resources = route.params.resource || '' + const resource = resources.slice(0, -1) -function showAndInitName({ route, commit, getValue, model, watchDependency }) { - watchDependency('model#/spec/type') - watchDependency('model#/spec/databaseRef/name') - const ver = asDatabaseOperation(route) + const opsName = dbName ? dbName : resource + return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + function showAndInitName() { + // watchDependency('model#/spec/type') + // watchDependency('model#/spec/databaseRef/name') + const ver = asDatabaseOperation() - 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({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/metadata/namespace', - value: `${route.query.namespace}`, - force: true, - }) - } + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' - return !ver -} -function showAndInitDatabaseRef({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/spec/databaseRef/name', - value: `${route.params.name}`, - force: true, - }) + if (ver) { + commit('wizard/model$update', { + path: '/metadata/name', + value: `${route.params.name}-${Math.floor(Date.now() / 1000)}-${lowerType}`, + force: true, + }) + } else { + commit('wizard/model$update', { + path: '/metadata/name', + value: generateOpsRequestNameForClusterUI(getValue, model, route), + force: true, + }) + } + return !ver } - return !ver -} -function showConfigureOpsrequestLabel({ route }) { - return !asDatabaseOperation(route) -} -function showAndInitOpsRequestType({ route, commit }) { - const ver = asDatabaseOperation(route) - const opMap = { - upgrade: 'UpdateVersion', - updateVersion: 'UpdateVersion', - horizontalscaling: 'HorizontalScaling', - verticalscaling: 'VerticalScaling', - volumeexpansion: 'VolumeExpansion', - restart: 'Restart', - reconfiguretls: 'ReconfigureTLS', - reconfigure: 'Reconfigure', - } - if (ver) { - const operation = route.params.actions - const match = /^(.*)-opsrequest-(.*)$/.exec(operation) - const opstype = match[2] - commit('wizard/model$update', { - path: '/spec/type', - value: opMap[opstype], - force: true, - }) + function showAndInitNamespace() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/metadata/namespace', + value: `${route.query.namespace}`, + force: true, + }) + } + + return !ver } - return !ver -} + function showAndInitDatabaseRef() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/spec/databaseRef/name', + value: `${route.params.name}`, + force: true, + }) + } -// vertical scaling -function ifDbTypeEqualsTo({ discriminator, getValue, watchDependency, commit }, value, opsReqType) { - const verd = getDbType({ - discriminator, - getValue, - watchDependency, - }) - return value === verd -} + return !ver + } -// machine profile stuffs -let machinesFromPreset = [] + function showConfigureOpsrequestLabel() { + return !asDatabaseOperation() + } -function getMachines({ storeGet }) { - const presets = storeGet('/kubedbuiPresets') || {} - const avlMachines = presets.admin?.machineProfiles?.available || [] - let arr = [] - if (avlMachines.length) { - arr = avlMachines.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - 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 } - } else return { text: machine, value: machine } + 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, + }) } - }) - } else { - arr = machineList - .map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } - }) - .filter((val) => !!val) - } - return arr -} + } -function setMachine({ getValue, discriminator, storeGet }) { - const dbDetails = getValue(discriminator, '/dbDetails') - const annotations = dbDetails?.metadata?.annotations || {} - const machine = annotations['kubernetes.io/instance-type'] || 'custom' + return !ver + } - machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] + function ifDbTypeEqualsTo(value, opsReqType) { + const verd = getDbType() + return value === verd + } - const machinePresets = machinesFromPreset.find((item) => item.id === machine) - if (machinePresets) return machine - else return 'custom' -} + function getMachines() { + const presets = storeGet('/kubedbuiPresets') || {} + const dbDetails = getValue(discriminator, '/dbDetails') + const containers = dbDetails?.spec?.podTemplate?.spec?.containers || [] + const kind = dbDetails?.kind || 'RabbitMQ' + const resource = containers.filter((ele) => ele.name === kind.toLowerCase()) + const limits = resource[0]?.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 onMachineChange({ getValue, discriminator, commit, model }, type, valPath) { - let selectedMachine = '' - selectedMachine = getValue(discriminator, '/machine') - const machine = machinesFromPreset.find((item) => item.id === selectedMachine) + function setMachine() { + const dbDetails = getValue(discriminator, '/dbDetails') + const containers = dbDetails?.spec?.podTemplate?.spec?.containers || [] + const kind = dbDetails?.kind || 'RabbitMQ' + const resource = containers.filter((ele) => ele.name === kind.toLowerCase()) + const limits = resource[0]?.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' - let obj = {} - if (selectedMachine !== 'custom') { - if (machine) obj = { limits: { ...machine?.limits }, requests: { ...machine?.limits } } - else obj = machines[selectedMachine]?.resources - } else { - const val = getValue(discriminator, `/dbDetails${valPath}`) || {} - obj = Array.isArray(val) ? val[0]?.resources : { ...val } + 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 } } - const path = `/spec/verticalScaling/${type}/resources` + 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, - }) + 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') || {} - if (selectedMachine === 'custom') commit('wizard/model$delete', '/metadata/annotations') - else { - annotations['kubernetes.io/instance-type'] = selectedMachine + const annotations = getValue(model, '/metadata/annotations') || {} + annotations['kubernetes.io/instance-type'] = selectedMachine.machine if (machinesFromPreset.length) commit('wizard/model$update', { path: '/metadata/annotations', @@ -778,520 +868,992 @@ function onMachineChange({ getValue, discriminator, commit, model }, type, valPa force: true, }) } -} -function isMachineCustom({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/machine') - const machine = getValue(discriminator, '/machine') - return machine === 'custom' -} + function isMachineCustom() { + // watchDependency('discriminator#/machine') + const machine = getValue(discriminator, '/machine') + return machine === 'custom' + } -// for config secret -async function getConfigSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + // Fetch and store database Infos + // for secret configurations in reconfigure + let configSecrets = [] + let secretConfigData = [] - const secrets = (resp && resp.data && resp.data.items) || [] + 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 filteredSecrets = secrets + 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') - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return filteredSecrets -} + 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: ['rabbitmq.conf'], + }, + }, + ) + configSecrets = resp?.data?.response?.availableSecrets || [] + secretConfigData = resp?.data?.response?.configurations || [] + } catch (e) { + console.log(e) + } + } -function createSecretUrl({ storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 + } - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/secrets/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/secrets/create` + async function getConfigSecretsforAppyConfig() { + const secrets = secretConfigData.map((item) => { + return { text: item.componentName, value: item.componentName } + }) + return secrets } -} -function isEqualToValueFromType({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/valueFromType') - const valueFrom = getValue(discriminator, '/valueFromType') - return valueFrom === value -} + function getSelectedConfigurationData(type) { + type = type ? type + '/' : '' + const path = `/${type}selectedConfiguration` + const selectedConfiguration = getValue(discriminator, path) -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + if (!selectedConfiguration) { + return [] + } - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + const configuration = secretConfigData.find( + (item) => item.componentName === selectedConfiguration, + ) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, + 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 + }) + } }) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + // Set the value to the model + commit('wizard/model$update', { + path: `/temp/${type}applyConfig`, + value: result, + force: true, + }) + + return result } - return ans -} -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` + const selectedConfiguration = + configType === 'create' ? getValue(model, path) : getValue(discriminator, path) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, + 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 + } }) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + // Convert data object back to YAML string + return yaml.dump(data) } - return ans -} -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - group, - version, - resource, -) { - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/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) - }) + 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])) + + 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 resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + function decodeError(msg, defaultMsg) { + if (typeof msg === 'string') { + return msg || defaultMsg } - }) -} -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) - - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) + return ( + (msg.response && msg.response.data && msg.response.data.message) || + (msg.response && msg.response.data) || + (msg.status && msg.status.status) || + defaultMsg + ) } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + 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 + } -// reconfiguration type -function ifReconfigurationTypeEqualsTo({ discriminator, getValue, watchDependency }, value) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - watchDependency('discriminator#/reconfigurationType') + function isNotCreateSecret(type) { + return !isCreateSecret(type) + } - return reconfigurationType === value -} + 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`) -function onApplyconfigChange({ discriminator, getValue, commit }) { - const applyconfig = getValue(discriminator, '/applyConfig') + const configFound = configSecrets.find((item) => item === name) + return configFound ? { text: name, value: name } : '' + } + } - const configObj = {} - if (applyconfig) { - applyconfig.forEach((item) => { - const { key, value } = item - configObj[key] = value + 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', }) } - commit('wizard/model$update', { - path: '/spec/configuration/applyConfig', - value: configObj, - force: true, - }) -} - -function onReconfigurationTypeChange({ commit, discriminator, getValue, setDiscriminatorValue }) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - setDiscriminatorValue('/applyConfig', []) - if (reconfigurationType === 'remove') { - commit('wizard/model$delete', `/spec/configuration`) + 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) { + 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/removeCustomConfig`, - value: true, - force: true, + path: `/spec/configuration/${type}applyConfig`, + value: tempConfigObj, }) - } 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({ discriminator, getValue, watchDependency }) { - const tls = getDbTls({ - discriminator, - getValue, - watchDependency, - }) + 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], + }) + }) + } else { + configObj.push({ name: '', content: '' }) + } + return configObj + } - return !!tls -} + function onRemoveConfigChange(type) { + type = type ? type + '/' : '' + const configPath = `/${type}selectedConfigurationRemove` + const selectedConfig = getValue(discriminator, configPath) -function initIssuerRefApiGroup({ getValue, model, watchDependency, discriminator }) { - const kind = getValue(model, '/spec/tls/issuerRef/kind') - watchDependency('model#/spec/tls/issuerRef/kind') + if (!selectedConfig) { + commit('wizard/model$delete', `/spec/configuration/${type}removeCustomConfig`) + return [{ name: '', content: '' }] + } + commit('wizard/model$update', { + path: `/spec/configuration/${type}removeCustomConfig`, + value: true, + }) - if (kind) { - const apiGroup = getValue(discriminator, '/dbDetails/spec/tls/issuerRef/apiGroup') - if (apiGroup) return apiGroup - return 'cert-manager.io' - } else return undefined -} + const configuration = secretConfigData.find((item) => item.componentName === selectedConfig) -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - 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` + if (!configuration.data) { + return [{ name: '', content: '' }] + } - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + const configObj = [] + // Decode base64 and format as array of objects with name and content + Object.keys(configuration.data).forEach((fileName) => { try { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + // Decode base64 string + const decodedString = atob(configuration.data[fileName]) + configObj.push({ + name: fileName, + content: decodedString, + }) } catch (e) { - console.log(e) - presets.status = String(e.status) + 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: '' }] } - let clusterIssuers = presets.admin?.clusterIssuers?.available || [] - if (presets.status === '404') { - const url = `/clusters/${owner}/${cluster}/proxy/cert-manager.io/v1/clusterissuers` - return getIssuer(url) + 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) } - return clusterIssuers + 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 isEqualToValueFromType(value) { + // watchDependency('discriminator#/valueFromType') + const valueFrom = getValue(discriminator, '/valueFromType') + return valueFrom === value } - async function getIssuer(url) { + 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) - const resources = (resp && resp.data && resp.data.items) || [] + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + 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 } }, + }, }) - return resources + + const items = (resp && resp.data && resp.data.items) || [] + ans = items } catch (e) { console.log(e) - return [] } + + return ans } -} -function initTlsOperation() { - return 'update' -} -function onTlsOperationChange({ discriminator, getValue, commit }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + async function resourceNames(group, version, resource) { + const namespace = getValue(model, '/metadata/namespace') + // watchDependency('model#/metadata/namespace') - commit('wizard/model$delete', '/spec/tls') + let resources = await getNamespacedResourceList({ + namespace, + group, + version, + resource, + }) - if (tlsOperation === 'rotate') { - commit('wizard/model$update', { - path: '/spec/tls/rotateCertificates', - value: true, - force: true, + 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, + } }) - 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, + } + + 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, + } }) - commit('wizard/model$delete', '/spec/tls/certificates') - commit('wizard/model$delete', '/spec/tls/rotateCertificates') } -} -function showIssuerRefAndCertificates({ discriminator, getValue, watchDependency }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') - watchDependency('discriminator#/tlsOperation') - const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' + function ifReconfigurationTypeEqualsTo(value) { + const reconfigurationType = getValue(discriminator, '/reconfigurationType') + // watchDependency('discriminator#/reconfigurationType') - return verd -} + return reconfigurationType === value + } -function isIssuerRefRequired({ discriminator, getValue, watchDependency }) { - const hasTls = hasTlsField({ - discriminator, - getValue, - watchDependency, - }) + function onReconfigurationTypeChange() { + const reconfigurationType = getValue(discriminator, '/reconfigurationType') + setDiscriminatorValue('/applyConfig', []) + if (reconfigurationType === 'remove') { + commit('wizard/model$delete', `/spec/configuration`) - return !hasTls -} + 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`) + } + } -function getRequestTypeFromRoute({ route, model, discriminator, getValue, watchDependency }) { - const isDbloading = isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) - const { query } = route || {} - const { requestType } = query || {} - return isDbloading ? '' : requestType || '' -} + function hasTlsField() { + const tls = getDbTls() + return !!tls + } -// ************************************** Set db details ***************************************** + function initIssuerRefApiGroup() { + const kind = getValue(model, '/spec/tls/issuerRef/kind') + // watchDependency('model#/spec/tls/issuerRef/kind') -function isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - watchDependency('model#/spec/databaseRef/name') - const dbDetails = getValue(discriminator, '/dbDetails') - const dbName = getValue(model, '/spec/databaseRef/name') + if (kind) { + const apiGroup = getValue(discriminator, '/dbDetails/spec/tls/issuerRef/apiGroup') + if (apiGroup) return apiGroup + return 'cert-manager.io' + } else return undefined + } - return !dbDetails || !dbName -} + 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') -function setValueFromDbDetails( - { discriminator, getValue, watchDependency, commit }, - path, - commitPath, -) { - watchDependency('discriminator#/dbDetails') + 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 [] + } - const retValue = getValue(discriminator, `/dbDetails${path}`) + 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 [] + } + } + } - if (commitPath && retValue) { + function initTlsOperation() { + return 'update' + } + + function onTlsOperationChange() { const tlsOperation = getValue(discriminator, '/tlsOperation') - // computed called when tls fields is not visible - if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined + commit('wizard/model$delete', '/spec/tls') - // 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, - }) + 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') + } } - return retValue || undefined -} + function showIssuerRefAndCertificates() { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // watchDependency('discriminator#/tlsOperation') + const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' -function setResource({ discriminator, getValue, watchDependency, storeGet }, path) { - watchDependency('discriminator#/dbDetails') - const containers = getValue(discriminator, `/dbDetails${path}`) || [] - const kind = getValue(discriminator, '/dbDetails/kind') - const resource = containers.filter((ele) => ele.name === kind.toLowerCase()) - return resource[0].resources -} + return verd + } -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} + function isIssuerRefRequired() { + const hasTls = hasTlsField() + return hasTls ? false : '' + } -function isNamespaceDisabled({ route }) { - const { namespace } = route.query || {} - return !!namespace -} + function getRequestTypeFromRoute() { + const isDbloading = isDbDetailsLoading() + const { query } = route || {} + const { requestType } = query || {} + return isDbloading ? '' : requestType || '' + } -function isDatabaseRefDisabled({ route }) { - const { name } = route.params || {} - return !!name -} + function isDbDetailsLoading() { + // watchDependency('discriminator#/dbDetails') + // watchDependency('model#/spec/databaseRef/name') + const dbDetails = getValue(discriminator, '/dbDetails') + const dbName = getValue(model, '/spec/databaseRef/name') -function onNamespaceChange({ commit }) { - commit('wizard/model$delete', '/spec/type') -} + return !dbDetails || !dbName + } -function onDbChange({ commit, axios, storeGet, model, getValue, setDiscriminatorValue }) { - commit('wizard/model$delete', '/spec/type') - getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) -} + function setValueFromDbDetails(path, commitPath) { + // watchDependency('discriminator#/dbDetails') -function setApplyToIfReady() { - return 'IfReady' -} + const retValue = getValue(discriminator, `/dbDetails${path}`) -function isVerticalScaleTopologyRequired({ watchDependency, getValue, discriminator, commit }) { - watchDependency('discriminator#/topologyKey') - watchDependency('discriminator#/topologyValue') + if (commitPath && retValue) { + const tlsOperation = getValue(discriminator, '/tlsOperation') - const key = getValue(discriminator, '/topologyKey') - const value = getValue(discriminator, '/topologyValue') - const path = `/spec/verticalScaling/rabbitmq/topology` + if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined - if (key || value) { - commit('wizard/model$update', { - path: path, - value: { key, value }, - force: true, + commit('wizard/model$update', { + path: commitPath, + value: retValue, + force: true, + }) + } + + return retValue || undefined + } + + function setResource(path) { + // watchDependency('discriminator#/dbDetails') + const containers = getValue(discriminator, `/dbDetails${path}`) || [] + const kind = getValue(discriminator, '/dbDetails/kind') + const resource = containers.filter((ele) => ele.name === kind.toLowerCase()) + return resource[0].resources + } + + 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/node/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 isConfigSelected() { + const selectedSecret = getValue(model, '/spec/configuration/configSecret/name') + return !!selectedSecret + } + + function getSelectedConfigSecret() { + const selectedSecret = getValue(model, '/spec/configuration/configSecret/name') + // watchDependency(`model#/spec/configuration/configSecret/name`) + 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() { + const selectedSecret = getValue(model, '/spec/configuration/configSecret/name') + let data + secretArray.forEach((item) => { + if (item.value === selectedSecret) { + data = objectToYaml(item.data).trim() || 'No Data Found' + } }) - return true - } else { - commit('wizard/model$delete', path) - return false + return data || 'No Data Found' } -} -function checkVolume({ model, discriminator, getValue }, initpath, path) { - const volume = getValue(discriminator, `/dbDetails${initpath}`) - const input = getValue(model, path) + function setExporter(type) { + let path = `/dbDetails/spec/monitor/prometheus/exporter/resources/limits/${type}` + const limitVal = getValue(discriminator, path) - try { - const sizeInBytes = parseSize(volume) - const inputSizeInBytes = parseSize(input) + if (!limitVal) { + path = `/dbDetails/spec/monitor/prometheus/exporter/resources/requests/${type}` + const reqVal = getValue(discriminator, path) - if (inputSizeInBytes >= sizeInBytes) return true - else return 'Cannot expand to lower volume!' - } catch (err) { - return err.message || 'Invalid' + if (reqVal) return reqVal + } + return limitVal } -} -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 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, + }) + } -return { - setResource, - fetchJsons, - returnFalse, - getNamespaces, - getDbs, - getDbDetails, - getDbVersions, - ifRequestTypeEqualsTo, - onRequestTypeChange, - getDbTls, - getDbType, - initNamespace, - initDatabaseRef, - isRancherManaged, - showAndInitName, - showAndInitNamespace, - showAndInitDatabaseRef, - showConfigureOpsrequestLabel, - showAndInitOpsRequestType, - - ifDbTypeEqualsTo, - getConfigSecrets, - createSecretUrl, - isEqualToValueFromType, - disableOpsRequest, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - ifReconfigurationTypeEqualsTo, - onReconfigurationTypeChange, - onApplyconfigChange, - hasTlsField, - initIssuerRefApiGroup, - getIssuerRefsName, - initTlsOperation, - onTlsOperationChange, - showIssuerRefAndCertificates, - isIssuerRefRequired, - getRequestTypeFromRoute, - isDbDetailsLoading, - setValueFromDbDetails, - getAliasOptions, - isNamespaceDisabled, - isDatabaseRefDisabled, - onNamespaceChange, - onDbChange, - setApplyToIfReady, - isVerticalScaleTopologyRequired, - getMachines, - setMachine, - onMachineChange, - isMachineCustom, - checkVolume, + return { + setExporter, + onExporterResourceChange, + fetchAliasOptions, + validateNewCertificates, + disableAlias, + setResource, + fetchJsons, + returnFalse, + getNamespaces, + getDbs, + getDbDetails, + getDbVersions, + getVersionInfo, + isVersionEmpty, + getVersion, + ifRequestTypeEqualsTo, + onRequestTypeChange, + getDbTls, + getDbType, + initNamespace, + initDatabaseRef, + isRancherManaged, + showAndInitName, + showAndInitNamespace, + showAndInitDatabaseRef, + showConfigureOpsrequestLabel, + showAndInitOpsRequestType, + ifDbTypeEqualsTo, + getConfigSecrets, + createSecretUrl, + isEqualToValueFromType, + disableOpsRequest, + getNamespacedResourceList, + getResourceList, + resourceNames, + unNamespacedResourceNames, + ifReconfigurationTypeEqualsTo, + onReconfigurationTypeChange, + onApplyconfigChange, + hasTlsField, + initIssuerRefApiGroup, + getIssuerRefsName, + initTlsOperation, + onTlsOperationChange, + showIssuerRefAndCertificates, + isIssuerRefRequired, + getRequestTypeFromRoute, + isDbDetailsLoading, + setValueFromDbDetails, + getAliasOptions, + isNamespaceDisabled, + isDatabaseRefDisabled, + onNamespaceChange, + onDbChange, + setApplyToIfReady, + isVerticalScaleTopologyRequired, + getMachines, + setMachine, + onMachineChange, + isMachineCustom, + checkVolume, + isConfigSelected, + getSelectedConfigSecret, + getSelectedConfigSecretValue, + fetchConfigSecrets, + getConfigSecretsforAppyConfig, + getSelectedConfigurationData, + getSelectedConfigurationName, + getSelectedConfigurationValueForRemove, + createNewConfigSecret, + decodeError, + isCreateSecret, + isNotCreateSecret, + onCreateSecretChange, + cancelCreateSecret, + setApplyConfig, + onRemoveConfigChange, + onNewConfigSecretChange, + onSelectedSecretChange, + isTlsEnabled, + } } diff --git a/charts/opskubedbcom-redisopsrequest-editor/ui/create-ui.yaml b/charts/opskubedbcom-redisopsrequest-editor/ui/create-ui.yaml index 5c8c606d01..c389a7d019 100644 --- a/charts/opskubedbcom-redisopsrequest-editor/ui/create-ui.yaml +++ b/charts/opskubedbcom-redisopsrequest-editor/ui/create-ui.yaml @@ -1,416 +1,631 @@ -steps: -- form: - discriminator: - dbDetails: - type: object +type: multi-step-form +step: + - type: single-step-form + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - schema: - $ref: discriminator#/properties/dbDetails - type: input - - if: showAndInitName - label: - text: labels.op_req_name - required: true - schema: - $ref: schema#/properties/metadata/properties/name - type: input - - computed: initNamespace - disabled: isNamespaceDisabled - fetch: getNamespaces - hasGroup: isRancherManaged - if: showAndInitNamespace - label: - text: labels.namespace - onChange: onNamespaceChange - required: true - schema: - $ref: schema#/properties/metadata/properties/namespace - type: select - - computed: initDatabaseRef - disabled: isDatabaseRefDisabled - fetch: getDbs - if: showAndInitDatabaseRef - label: - text: labels.databaseRef - onChange: onDbChange - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/databaseRef/properties/name - type: select - - if: showConfigureOpsrequestLabel - label: - text: labels.config_ops_request - type: label-element - - computed: getRequestTypeFromRoute - disabled: isDbDetailsLoading - hasDescription: true - if: showAndInitOpsRequestType - individualItemDisabilityCheck: disableOpsRequest - label: - text: labels.ops_request_type - onChange: onRequestTypeChange - options: - - description: options.UpdateVersion.description - text: options.UpdateVersion.text - value: UpdateVersion - - description: options.HorizontalScaling.description - text: options.HorizontalScaling.text - value: HorizontalScaling - - description: options.VerticalScaling.description - text: options.VerticalScaling.text - value: VerticalScaling - - description: options.VolumeExpansion.description - text: options.VolumeExpansion.text - value: VolumeExpansion - - description: options.Restart.description - text: options.Restart.text - value: Restart - - description: options.Reconfigure.description - text: options.Reconfigure.text - value: Reconfigure - - description: options.ReconfigureTLS.description - text: options.ReconfigureTLS.text - value: ReconfigureTLS - schema: - $ref: schema#/properties/spec/properties/type - type: radio - - elements: - - computed: setValueFromDbDetails|/spec/version - fetch: getDbVersions - label: - text: labels.targetVersion - schema: - $ref: schema#/properties/spec/properties/updateVersion/properties/targetVersion - type: select - if: ifRequestTypeEqualsTo|UpdateVersion - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/cluster/master - if: ifDbTypeEqualsTo|Cluster|horizontalScaling - label: - text: labels.master - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/shards - type: input - - computed: setReplicas - if: ifDbTypeEqualsTo|[Cluster,Sentinel]|horizontalScaling - label: - text: labels.replicas - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/replicas - type: input - if: ifRequestTypeEqualsTo|HorizontalScaling - label: - text: Horizontal Scaling Form - type: single-step-form - - elements: - - discriminator: - machine: - default: "" - type: string - elements: - - computed: setMachine - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|redis|/spec/podTemplate/spec/resources - schema: - $ref: discriminator#/machine - type: select - - if: isMachineCustom - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/redis/properties/resources - type: resource-input-form - - label: - text: labels.node_selection_policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/redis/properties/nodeSelectionPolicy - type: select - - discriminator: - topologyKey: - default: "" - type: string - topologyValue: - default: "" - type: string - elements: - - label: - text: labels.key - required: isVerticalScaleTopologyRequired - schema: - $ref: discriminator#/topologyKey - type: input - - label: - text: labels.value - required: isVerticalScaleTopologyRequired - schema: - $ref: discriminator#/topologyValue - type: input - label: - text: labels.topology - show_label: true - type: single-step-form - label: - text: labels.redis - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/redis - show_label: true - type: single-step-form - - computed: setValueFromDbDetails|/spec/monitor/prometheus/exporter/resources|/spec/verticalScaling/exporter/resources - label: - text: labels.exporter - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/exporter/properties/resources - type: resource-input-form - if: ifRequestTypeEqualsTo|VerticalScaling - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/storage/resources/requests/storage - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/redis - type: input - validationRuleObject: - func: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/redis - - label: - text: Mode +# common + - type: input + label: op_req_name + if: + type: function + name: showAndInitName + validation: + type: required + schema: schema/properties/metadata/properties/name + - type: select + label: Namespace + if: + type: function + name: showAndInitNamespace + init: + type: func + value: initNamespace + disable: isNamespaceDisabled + loader: getNamespaces + validation: + type: required + hasGroup: isRancherManaged + schema: schema/properties/metadata/properties/namespace + - type: select + label: Database Ref + if: + type: function + name: showAndInitDatabaseRef + loader: + name: getDbs + watchPaths: + - schema/properties/metadata/properties/namespace + init: + type: func + value: initDatabaseRef + validation: + type: required + disable: isDatabaseRefDisabled + refresh: true + watcher: + func: onDbChange + paths: + - schema/properties/spec/properties/databaseRef/properties/name + schema: schema/properties/spec/properties/databaseRef/properties/name + - type: label-element + label: config_ops_request + if: + type: function + name: showConfigureOpsrequestLabel + - type: radio + label: Type of Ops Request + if: + type: function + name: showAndInitOpsRequestType options: - - text: Offline - value: Offline - - text: Online - value: Online - required: true - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/mode - type: select - if: ifRequestTypeEqualsTo|VolumeExpansion - label: - text: Volume Expansion Form - type: single-step-form - - elements: - - discriminator: - reconfigurationType: - type: string + - 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 + init: + type: func + value: getRequestTypeFromRoute + disable: isDbDetailsLoading + watcher: + func: isDbDetailsLoading + paths: + - temp/dbDetails + - schema/properties/spec/properties/databaseRef/properties/name + isHorizontal: true + schema: schema/properties/spec/properties/type +# UpdateVersion + - type: block-layout + showLabels: true + label: Version + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|UpdateVersion + elements: + - type: select-compare + label: Target Version + subtitle: Select the desired Redis version to which you want to update your database. + init: + type: func + value: setValueFromDbDetails|/spec/version + loader: getDbVersions + schema: schema/properties/spec/properties/updateVersion/properties/targetVersion + - type: info + label: '' + loader: + name: getVersionInfo + watchPaths: + - temp/properties/filteredVersion + if: + type: function + name: isVersionEmpty +# Horizontal Scale + - type: block-layout + label: Horizontal Scaling Form + showLabels: true + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|HorizontalScaling elements: - - label: - text: labels.reconfigurationType - onChange: onReconfigurationTypeChange - options: - - text: Select New Config Secret - value: selectNewConfigSecret - - text: Apply Config - value: applyConfig - - text: Remove - value: remove - required: true - schema: - $ref: discriminator#/properties/reconfigurationType - type: radio - - elements: - - add_new_button: - label: labels.createConfig - target: _blank - url: - function: createSecretUrl - computed: setValueFromDbDetails|/spec/configSecret/name - fetch: getConfigSecrets - label: - text: labels.configSecret - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret/properties/name - type: select - if: ifReconfigurationTypeEqualsTo|selectNewConfigSecret - label: - text: Configuration config secret - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret - type: single-step-form - - addFormLabel: labels.applyConfig.label - element: - discriminator: - configArray: - emitAs: applyConfig - type: array + - type: horizontal-layout + if: + type: function + name: ifDbTypeEqualsTo|Cluster|horizontalScaling elements: - - label: - text: labels.applyConfig.key - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/key - type: input - - label: - text: labels.applyConfig.value - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/value - type: editor - type: single-step-form - if: ifReconfigurationTypeEqualsTo|applyConfig - label: - text: labels.applyConfig.label - onChange: onApplyconfigChange - required: true - schema: - $ref: discriminator#/properties/applyConfig - tableContents: - - inTableColumn: true - label: - text: labels.applyConfig.key - path: key - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.applyConfig.value - path: value - type: value - typeOfValue: code - type: single-step-form-array - - if: returnFalse - label: - text: labels.removeCustomConfig - schema: - $ref: schema#/properties/spec/properties/configuration/properties/removeCustomConfig - type: switch - label: - text: labels.configuration - schema: - $ref: schema#/properties/spec/properties/configuration - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|Reconfigure - label: - text: Reconfigure Form - type: single-step-form - - discriminator: - tlsOperation: - default: update - type: string - elements: - - computed: initTlsOperation - if: hasTlsField - label: - text: labels.tlsOperation - onChange: onTlsOperationChange - options: - - text: Update - value: update - - text: Rotate - value: rotate - - text: Remove - value: remove - schema: - $ref: discriminator#/properties/tlsOperation - type: radio - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/remove - type: switch - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/rotateCertificates - type: switch - - elements: - - computed: initIssuerRefApiGroup - disabled: true - label: - text: labels.api_group - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup - type: input - - computed: setValueFromDbDetails|/spec/tls/issuerRef/kind - label: - text: labels.kind - options: - - text: Issuer - value: Issuer - - text: ClusterIssuer - value: ClusterIssuer - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/kind - sortable: true - type: select - - allowUserDefinedOption: true - computed: setValueFromDbDetails|/spec/tls/issuerRef/name - fetch: getIssuerRefsName - label: - text: labels.name - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/name - sortable: true - type: select - if: showIssuerRefAndCertificates - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef - type: single-step-form - - alias: reusable_certificates - chart: - name: uibytebuildersdev-component-certificates - version: v0.29.0 - computed: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates - functionCallbacks: - getAliasOptions: - $ref: functions#/getAliasOptions - if: showIssuerRefAndCertificates - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/spec/properties/tls/properties/certificates - type: reusable-element - if: ifRequestTypeEqualsTo|ReconfigureTLS - label: - text: labels.tls - schema: - $ref: schema#/properties/spec/properties/tls - type: single-step-form - - label: - text: labels.timeout - options: - - text: 5 minutes - value: 5m - - text: 10 minutes - value: 10m - - text: 30 minutes - value: 30m - - text: 1 hour - value: 1h - - text: 2 hours - value: 2h - - text: 5 hours - value: 5h - - text: 10 hours - value: 10h - schema: - $ref: schema#/properties/spec/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: labels.apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/spec/properties/apply - type: radio - type: single-step-form - id: basic - title: steps.0.label -type: multi-step-form + - type: input-compare + header: Master + label: Master + subtitle: Define the total number of master shards for your database + init: + type: func + value: setValueFromDbDetails|/spec/cluster/master + schema: schema/properties/spec/properties/horizontalScaling/properties/shards + - type: horizontal-layout + if: + type: function + name: ifDbTypeEqualsTo|[Cluster,Sentinel]|horizontalScaling + elements: + - type: input-compare + header: Replicas + label: Replicas + subtitle: Define the total number of replicas for your database + init: + type: func + value: setReplicas + schema: schema/properties/spec/properties/horizontalScaling/properties/replicas + - type: info + 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. +# vertical Scale + - type: block-layout + if: + type: function + name: ifRequestTypeEqualsTo|VerticalScaling + elements: + - type: block-layout + label: Redis + showLabels: false + elements: + - type: machine-compare + label: Resources + loader: getMachines + init: + type: func + value: setMachine + watcher: + func: onMachineChange|redis|/spec/podTemplate/spec/resources + paths: + - temp/properties/machine + schema: temp/properties/machine + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + label: Node Selection Policy + subtitle: Control where your workloads runs by defining label selectors or taints. Choose how Kubernetes places your pods across different nodes. + - type: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/redis/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + label: " Label Selector: Specify key-value pairs to match node labels, ensuring pods are scheduled on nodes with specific characteristics (e.g., disktype=ssd).
Taints: Define tolerations to allow pods to run on nodes with matching taints, useful for dedicated or specialized nodes." + customClass: mt-20 + - type: label-element + label: Topology + subtitle: Define node topology preferences using key-value pairs to control pod distribution across zones or regions + - type: horizontal-layout + elements: + - type: input + label: Key + schema: temp/topologyKey + - type: input + label: Value + schema: temp/topologyValue + - type: block-layout + label: Exporter + showLabels: true + hideBlock: true + elements: + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setExporter|cpu + type: input + 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 + watcher: + func: onExporterResourceChange|memory + paths: + - schema/properties/spec/properties/verticalScaling/properties/exporter/properties/resources/properties/limits/properties/memory +# Volume Expansion + - type: block-layout + label: Volume Expansion Form + if: + type: function + name: ifRequestTypeEqualsTo|VolumeExpansion + elements: + - type: horizontal-layout + elements: + - type: block-layout + elements: + - type: label-element + 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: select + label: Mode + options: + - text: Offline + value: Offline + - text: Online + value: Online + validation: + type: required + schema: schema/properties/spec/properties/volumeExpansion/properties/mode + - type: block-layout + label: Redis volume expansion + showLabels: true + fixedBlock: true + elements: + - type: horizontal-layout + elements: + - type: input-compare + header: Storage Size + label: Storage Size + subtitle: How much extra storage does your database need? Specify the size(e.g. 2Gi for 2 gigabytes) so we can allocate it correctly + init: + type: func + value: setValueFromDbDetails|/spec/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/redis + schema: schema/properties/spec/properties/volumeExpansion/properties/redis + - type: info + hasIcon: true + label: Storage expansion allows you to increase your database's disk space without downtime (Online mode) or with brief downtime (Offline mode). +# Reconfigure + - type: block-layout + label: Reconfigure Form + if: + name: ifRequestTypeEqualsTo|Reconfigure + type: function + loader: + name: fetchConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + elements: + - type: block-layout + label: Configuration + elements: + - type: label-element + label: '' + subtitle: Select a new configuration secret, apply a custom configuration, or remove an existing setup to update your database settings + - type: tab-layout + label: New Config Secret + schema: temp/properties/reconfigurationType + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + elements: + - type: block-layout + label: Config Secret + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret + type: function + elements: + - type: label-element + label: Config Secret + subtitle: Select a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: schema/properties/spec/properties/configuration/properties/configSecret/properties/name + refresh: true + label: Config Secret + loader: + name: getConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/createSecret/properties/status + init: + type: func + value: setValueFromDbDetails|/spec/configSecret/name + watcher: + func: onCreateSecretChange + paths: + - temp/properties/createSecret/properties/status + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|create + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + - type: block-layout + label: Create a New Config Secret + showLabels: true + if: + type: function + name: isCreateSecret + hasButton: + text: Save + hasCancel: cancelCreateSecret + action: createNewConfigSecret + elements: + - type: input + label: Secret Name + schema: temp/properties/createSecret/properties/name + validation: + type: required + - type: array-object-form + label: String Data + schema: temp/properties/createSecret/properties/data + buttonClass: is-light is-outlined + validation: + type: required + elements: + - type: select + label: Key + schema: key + loader: + name: onSelectedSecretChange + watchPaths: + - temp/properties/createSecret/properties/data + validation: + type: required + - type: textarea + label: Value + schema: value + - type: multi-file-editor + editorHeight: 500px + readonly: true + if: + type: function + name: isNotCreateSecret + loader: + name: onNewConfigSecretChange + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + schema: temp/properties/newConfigSecret + - type: block-layout + label: ApplyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig + type: function + elements: + - type: label-element + 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). + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfiguration + refresh: true + label: Configuration + loader: getConfigSecretsforAppyConfig + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|apply + watchPaths: + - temp/properties/selectedConfiguration + - type: multi-file-editor + editorHeight: 500px + schema: temp/properties/applyConfig + loader: + name: setApplyConfig + watchPaths: + - temp/properties/selectedConfiguration + watcher: + func: onApplyconfigChange + paths: + - temp/properties/applyConfig + - type: block-layout + label: Remove + if: + name: ifReconfigurationTypeEqualsTo|remove + type: function + elements: + - type: label-element + label: Remove + subtitle: Selected a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfigurationRemove + refresh: true + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|remove + watchPaths: + - temp/properties/selectedConfigurationRemove + - type: multi-file-editor + editorHeight: 500px + readonly: true + init: + type: func + value: onRemoveConfigChange + watcher: + func: onRemoveConfigChange + paths: + - temp/properties/selectedConfigurationRemove + schema: temp/properties/removeConfig +# Reconfigure TLS + - type: block-layout + label: TLS + if: + name: ifRequestTypeEqualsTo|ReconfigureTLS + type: function + elements: + - type: radio + label: TLS Operation + if: + name: hasTlsField + type: function + options: + - text: Update + value: update + - text: Rotate + value: rotate + - text: Remove + value: remove + init: + type: func + value: initTlsOperation + schema: temp/properties/tlsOperation + - type: switch + label: Remove TLS + fullwidth: true + if: + name: isTlsEnabled + type: function + schema: schema/properties/spec/properties/tls/properties/remove + - type: switch + label: Rotate Certificates + fullwidth: true + schema: schema/properties/spec/properties/tls/properties/rotateCertificates + if: + name: isTlsEnabled + type: function + - type: block-layout + label: Issuer Reference + showLabels: true + if: + name: showIssuerRefAndCertificates + type: function + elements: + - type: input + label: API Group + init: + type: func + value: initIssuerRefApiGroup + watcher: + func: initIssuerRefApiGroup + paths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + disable: true + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup + - type: select + label: Kind + options: + - text: Issuer + value: Issuer + - text: ClusterIssuer + value: ClusterIssuer + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/kind + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - type: select + label: Name + loader: + name: getIssuerRefsName + watchPaths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - schema/properties/metadata/properties/namespace + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/name + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/name + - type: block-layout + label: Certificates + showLabels: false + if: + name: showIssuerRefAndCertificates + type: function + loader: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates + elements: + - type: array-object-form + label: Certificates + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/tls/properties/certificates + elements: + - type: select + label: Alias + loader: fetchAliasOptions + disable: disableAlias + schema: alias + validation: + type: required + - type: input + label: Secret Name + schema: secretName + - type: input + label: Duration + schema: duration + - type: input + label: Renew Before + schema: renewBefore + - type: array-item-form + label: Organizations + buttonClass: is-light is-outlined + schema: subject/properties/organizations + element: + type: input + label: Organization + - type: array-item-form + label: Countries + buttonClass: is-light is-outlined + schema: subject/properties/countries + element: + type: input + label: Country + - type: array-item-form + label: Organizational Units + buttonClass: is-light is-outlined + schema: subject/properties/organizationalUnits + element: + type: input + label: Organizational Unit + - type: array-item-form + label: Provinces + buttonClass: is-light is-outlined + schema: subject/properties/provinces + element: + type: input + label: Province + - type: array-item-form + label: DNS Names + buttonClass: is-light is-outlined + schema: dnsNames + element: + type: input + label: DNS Name + - type: array-item-form + label: IP Addresses + buttonClass: is-light is-outlined + schema: ipAddresses + element: + type: input + label: IP Address +# common + - type: block-layout + label: OpsRequest Options + showLabels: true + elements: + - type: time-picker + label: Timeout + subtitle: Specify the maximum time allowed for the operation to complete before it times out + schema: 'schema/properties/spec/properties/timeout' + - type: radio + label: Apply + schema: 'schema/properties/spec/properties/apply' + init: + type: func + value: setApplyToIfReady + options: + - text: IfReady (OpsRequest will be applied if database is ready) + value: IfReady + - text: Always (OpsRequest will always be applied) + value: Always \ No newline at end of file diff --git a/charts/opskubedbcom-redisopsrequest-editor/ui/functions.js b/charts/opskubedbcom-redisopsrequest-editor/ui/functions.js index eced4b63aa..fabd0c291a 100644 --- a/charts/opskubedbcom-redisopsrequest-editor/ui/functions.js +++ b/charts/opskubedbcom-redisopsrequest-editor/ui/functions.js @@ -1,3 +1,4 @@ +const { axios, useOperator, store, useToast } = window.vueHelpers || {} const machines = { 'db.t.micro': { resources: { @@ -304,181 +305,231 @@ const machineList = [ 'db.r.24xlarge', ] -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, - } -} +let machinesFromPreset = [] +const configSecretKeys = ['kubedb-user.conf'] -function returnFalse() { - return false -} +export const useFunc = (model) => { + const route = store.state?.route + const toast = useToast() -async function getNamespaces({ axios, storeGet }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + const { getValue, storeGet, discriminator, setDiscriminatorValue, commit } = useOperator( + model, + store.state, + ) - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + showAndInitOpsRequestType() + async function fetchJsons({ axios, itemCtx }) { + let ui = {} + let language = {} + let functions = {} + const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart - const resources = (resp && resp.data && resp.data.items) || [] + 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 resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' return { - text: name, - value: name, + ui: ui.data || {}, + language: language.data || {}, + functions, } - }) -} + } -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function returnFalse() { + return false + } -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function isTlsEnabled() { + const dbDetails = getValue(discriminator, '/dbDetails') + return ( + (dbDetails?.spec?.sslMode && + dbDetails?.spec?.sslMode !== 'disabled' && + dbDetails?.spec?.sslMode !== 'disable') || + dbDetails?.spec?.tls + ) + } - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/namespace') + 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/kubedb.com/v1alpha2/namespaces/${namespace}/redises`, - { + 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) || [] + const resources = (resp && resp.data && resp.data.items) || [] - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -async function getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) { - 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') + async function getDbs() { + if (storeGet('/route/params/actions')) return [] + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - if (namespace && name) { - const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises/${name}` - const resp = await axios.get(url) + const namespace = getValue(model, '/metadata/namespace') + // watchDependency('model#/metadata/namespace') - setDiscriminatorValue('/dbDetails', resp.data || {}) + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/redises`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) - return resp.data || {} - } else return {} -} + 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 getDbVersions({ axios, storeGet, getValue, discriminator }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + async function getDbDetails() { + machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] - const url = `/clusters/${owner}/${cluster}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/kubedb-ui-presets` + 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}/redises/${name}` + const resp = await axios.get(url) - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + 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 { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + presetVersions = presets.admin?.databases?.Redis?.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/redisversions`, + { + 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 allowed = found?.spec?.updateConstraints?.allowlist || [] + 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 filteredRedisVersions = 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.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.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.includes(item.metadata?.name)) && + isVersionWithinConstraints(item.spec?.version, limit) + ) + }) + setDiscriminatorValue('/filteredVersion', filteredRedisVersions) + return filteredRedisVersions.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) - presets.status = String(e.status) + return [] } } - try { - const presetVersions = presets.admin?.databases?.Redis?.versions?.available || [] - const queryParams = { - filter: { - items: { - metadata: { name: null }, - spec: { version: null, deprecated: null, updateConstraints: null }, - }, - }, - } + function getVersionInfo() { + const filteredVersion = getValue(discriminator, '/filteredVersion') + if (filteredVersion.length) return '' - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/catalog.kubedb.com/v1alpha1/redisversions`, - { - params: queryParams, - }, - ) + let txt = 'No versions from this list can be selected as the target version: [ ' - 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 allowed = found?.spec?.updateConstraints?.allowlist || [] - 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 filteredRedisVersions = 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.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.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.includes(item.metadata?.name)) && - isVersionWithinConstraints(item.spec?.version, limit) - ) + presetVersions.forEach((v, idx) => { + txt = `${txt}"${v}"` + if (idx !== presetVersions.length - 1) txt = txt + ', ' + else txt = txt + ' ]' }) - return filteredRedisVersions.map((item) => { + return txt + } + + function getVersion() { + return filteredVersion.map((item) => { const name = (item.metadata && item.metadata.name) || '' const specVersion = (item.spec && item.spec.version) || '' return { @@ -486,305 +537,333 @@ async function getDbVersions({ axios, storeGet, getValue, discriminator }) { value: name, } }) - } catch (e) { - console.log(e) - return [] } -} -function versionCompare(v1, v2) { - const arr1 = v1.split('.').map(Number) - const arr2 = v2.split('.').map(Number) + 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 + 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 + if (num1 > num2) return 1 // v1 is higher + if (num1 < num2) return -1 // v2 is higher + } + return 0 // versions are equal } - 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 + 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 } - return true -} -function ifRequestTypeEqualsTo({ model, getValue, watchDependency }, type) { - const selectedType = getValue(model, '/spec/type') - watchDependency('model#/spec/type') + function ifRequestTypeEqualsTo(type) { + const selectedType = getValue(model, '/spec/type') + // watchDependency('model#/spec/type') - return selectedType === type -} + return selectedType === type + } -function onRequestTypeChange({ model, getValue, commit }) { - 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 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', + } -function disableOpsRequest({ itemCtx, discriminator, getValue, watchDependency }) { - if (itemCtx.value === 'HorizontalScaling') { - const dbType = getDbType({ - discriminator, - getValue, - watchDependency, + Object.keys(reqTypeMapping).forEach((key) => { + if (key !== selectedType) commit('wizard/model$delete', `/spec/${reqTypeMapping[key]}`) }) + } - if (dbType === 'Standalone') return true - else return false - } else return false -} + function getDbTls() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') -function getDbTls({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + const { spec } = dbDetails || {} + return spec?.tls || undefined + } - const { spec } = dbDetails || {} - return spec?.tls || undefined -} + function getDbType() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') -function getDbType({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + const { spec } = dbDetails || {} + const { mode } = spec || {} - const { spec } = dbDetails || {} - const { mode } = spec || {} + return mode || 'Standalone' + } - return mode || 'Standalone' -} + function disableOpsRequest() { + if (itemCtx.value === 'HorizontalScaling') { + const dbType = getDbType() -function initNamespace({ route }) { - const { namespace } = route.query || {} - return namespace || null -} + if (dbType === 'Standalone') return true + else return false + } else return false + } -function initDatabaseRef({ route, watchDependency }) { - watchDependency('model#/metadata/namespace') - const { name } = route.params || {} - return name -} + function initNamespace() { + const { namespace } = route.query || {} + return namespace || null + } -function asDatabaseOperation(route) { - return !!route.params.actions -} + function initDatabaseRef() { + // watchDependency('model#/metadata/namespace') + const { name } = route.params || {} + return name + } -function generateOpsRequestNameForClusterUI(getValue, model, route) { - const dbName = getValue(model, '/spec/databaseRef/name') + function asDatabaseOperation() { + return !!route.params.actions + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + function generateOpsRequestNameForClusterUI(getValue, model, route) { + const dbName = getValue(model, '/spec/databaseRef/name') - const resources = route.params.resource || '' - const resource = resources.slice(0, -1) + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' - const opsName = dbName ? dbName : resource - return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` -} + const resources = route.params.resource || '' + const resource = resources.slice(0, -1) -function showAndInitName({ route, commit, getValue, model, watchDependency }) { - watchDependency('model#/spec/type') - watchDependency('model#/spec/databaseRef/name') - const ver = asDatabaseOperation(route) + const opsName = dbName ? dbName : resource + return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + function showAndInitName() { + // watchDependency('model#/spec/type') + // watchDependency('model#/spec/databaseRef/name') + const ver = asDatabaseOperation() - 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, - }) + 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 } - return !ver -} -function showAndInitNamespace({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/metadata/namespace', - value: `${route.query.namespace}`, - force: true, - }) + + function showAndInitNamespace() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/metadata/namespace', + value: `${route.query.namespace}`, + force: true, + }) + } + + return !ver } - return !ver -} -function showAndInitDatabaseRef({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/spec/databaseRef/name', - value: `${route.params.name}`, - force: true, - }) + function showAndInitDatabaseRef() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/spec/databaseRef/name', + value: `${route.params.name}`, + force: true, + }) + } + + return !ver } - return !ver -} -function showConfigureOpsrequestLabel({ route }) { - return !asDatabaseOperation(route) -} -function showAndInitOpsRequestType({ route, commit }) { - const ver = asDatabaseOperation(route) - const opMap = { - upgrade: 'UpdateVersion', - updateVersion: 'UpdateVersion', - horizontalscaling: 'HorizontalScaling', - verticalscaling: 'VerticalScaling', - volumeexpansion: 'VolumeExpansion', - restart: 'Restart', - reconfiguretls: 'ReconfigureTLS', - reconfigure: 'Reconfigure', - } - if (ver) { - const operation = route.params.actions - const match = /^(.*)-opsrequest-(.*)$/.exec(operation) - const opstype = match[2] - commit('wizard/model$update', { - path: '/spec/type', - value: opMap[opstype], - force: true, - }) + function showConfigureOpsrequestLabel() { + return !asDatabaseOperation() } - return !ver -} + 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, + }) + } + } -// vertical scaling -function ifDbTypeEqualsTo({ discriminator, getValue, watchDependency }, value) { - const verd = getDbType({ - discriminator, - getValue, - watchDependency, - }) - console.log(value) + return !ver + } - return value.includes(verd) -} + // vertical scaling + function ifDbTypeEqualsTo(value) { + const verd = getDbType() -function setReplicas({ discriminator, getValue, watchDependency }) { - const verd = getDbType({ - discriminator, - getValue, - watchDependency, - }) - const dbDetails = getValue(discriminator, '/dbDetails') - if (verd === 'Sentinel') return dbDetails?.spec?.replicas - else return dbDetails?.spec?.cluster?.replicas -} + return value.includes(verd) + } -// machine profile stuffs -let machinesFromPreset = [] + function setReplicas() { + const verd = getDbType() + const dbDetails = getValue(discriminator, '/dbDetails') + if (verd === 'Sentinel') return dbDetails?.spec?.replicas + else return dbDetails?.spec?.cluster?.replicas + } -function getMachines({ storeGet }) { - const presets = storeGet('/kubedbuiPresets') || {} - const avlMachines = presets.admin?.machineProfiles?.available || [] - let arr = [] - if (avlMachines.length) { - arr = avlMachines.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - 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 } - } else return { text: machine, value: machine } - } - }) - } else { - arr = machineList - .map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + // machine profile stuffs + 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 } } + } }) - .filter((val) => !!val) + } 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 } - return arr -} - -function setMachine({ getValue, discriminator, storeGet }) { - const dbDetails = getValue(discriminator, '/dbDetails') - const annotations = dbDetails?.metadata?.annotations || {} - const machine = annotations['kubernetes.io/instance-type'] || 'custom' - - machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] - const machinePresets = machinesFromPreset.find((item) => item.id === machine) - if (machinePresets) return machine - else return 'custom' -} - -function onMachineChange({ getValue, discriminator, commit, model }, type, valPath) { - let selectedMachine = '' - selectedMachine = getValue(discriminator, '/machine') - const machine = machinesFromPreset.find((item) => item.id === selectedMachine) + 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' - let obj = {} - if (selectedMachine !== 'custom') { - if (machine) obj = { limits: { ...machine?.limits }, requests: { ...machine?.limits } } - else obj = machines[selectedMachine]?.resources - } else { - const val = getValue(discriminator, `/dbDetails${valPath}`) || {} - obj = Array.isArray(val) ? val[0]?.resources : { ...val } + 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 } } - const path = `/spec/verticalScaling/${type}/resources` + 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 }, + } + } - if (obj && Object.keys(obj).length) - commit('wizard/model$update', { - path: path, - value: obj, - force: true, - }) + 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') || {} - if (selectedMachine === 'custom') commit('wizard/model$delete', '/metadata/annotations') - else { - annotations['kubernetes.io/instance-type'] = selectedMachine + // 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', @@ -792,512 +871,985 @@ function onMachineChange({ getValue, discriminator, commit, model }, type, valPa force: true, }) } -} -function isMachineCustom({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/machine') - const machine = getValue(discriminator, '/machine') - return machine === 'custom' -} + function isMachineCustom() { + // watchDependency('discriminator#/machine') + const machine = getValue(discriminator, '/machine') + return machine === 'custom' + } -// for config secret -async function getConfigSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + // for config secret + let secretArray = [] - const secrets = (resp && resp.data && resp.data.items) || [] + // Fetch and store database Infos + // for secret configurations in reconfigure + let configSecrets = [] + let secretConfigData = [] - const filteredSecrets = secrets + 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') - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return filteredSecrets -} + 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') -function createSecretUrl({ storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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.conf'], + }, + }, + ) + configSecrets = resp?.data?.response?.availableSecrets || [] + secretConfigData = resp?.data?.response?.configurations || [] + } catch (e) { + console.log(e) + } + } - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/secrets/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/secrets/create` + 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 } -} -function isEqualToValueFromType({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/valueFromType') - const valueFrom = getValue(discriminator, '/valueFromType') - return valueFrom === value -} + async function getConfigSecretsforAppyConfig() { + const secrets = secretConfigData.map((item) => { + return { text: item.componentName, value: item.componentName } + }) + return secrets + } -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function getSelectedConfigurationData(type) { + type = type ? type + '/' : '' + const path = `/${type}selectedConfiguration` + const selectedConfiguration = getValue(discriminator, path) - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + if (!selectedConfiguration) { + return [] + } - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, + 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 + }) + } }) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + // Set the value to the model + commit('wizard/model$update', { + path: `/temp/${type}applyConfig`, + value: result, + force: true, + }) + + return result } - return ans -} -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` + const selectedConfiguration = + configType === 'create' ? getValue(model, path) : getValue(discriminator, path) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, + 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 + } }) - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + // Convert data object back to YAML string + return yaml.dump(data) } - return ans -} -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - group, - version, - resource, -) { - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/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) - }) + 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])) + + 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 resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + function decodeError(msg, defaultMsg) { + if (typeof msg === 'string') { + return msg || defaultMsg } - }) -} -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) - - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) + return ( + (msg.response && msg.response.data && msg.response.data.message) || + (msg.response && msg.response.data) || + (msg.status && msg.status.status) || + defaultMsg + ) } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + 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 + } -// reconfiguration type -function ifReconfigurationTypeEqualsTo({ discriminator, getValue, watchDependency }, value) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - watchDependency('discriminator#/reconfigurationType') + function isNotCreateSecret(type) { + return !isCreateSecret(type) + } - return reconfigurationType === value -} + 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`) -function onApplyconfigChange({ discriminator, getValue, commit }) { - const applyconfig = getValue(discriminator, '/applyConfig') + const configFound = configSecrets.find((item) => item === name) + return configFound ? { text: name, value: name } : '' + } + } - const configObj = {} - if (applyconfig) { - applyconfig.forEach((item) => { - const { key, value } = item - configObj[key] = value + 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', }) } - commit('wizard/model$update', { - path: '/spec/configuration/applyConfig', - value: configObj, - force: true, - }) -} - -function onReconfigurationTypeChange({ commit, discriminator, getValue, setDiscriminatorValue }) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - setDiscriminatorValue('/applyConfig', []) - if (reconfigurationType === 'remove') { - commit('wizard/model$delete', `/spec/configuration`) + 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) { + 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/removeCustomConfig`, - value: true, - force: true, + path: `/spec/configuration/${type}applyConfig`, + value: tempConfigObj, }) - } 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({ discriminator, getValue, watchDependency }) { - const tls = getDbTls({ - discriminator, - getValue, - watchDependency, - }) + 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], + }) + }) + } else { + configObj.push({ name: '', content: '' }) + } + return configObj + } - return !!tls -} + function onRemoveConfigChange(type) { + type = type ? type + '/' : '' + const configPath = `/${type}selectedConfigurationRemove` + const selectedConfig = getValue(discriminator, configPath) -function initIssuerRefApiGroup({ getValue, model, watchDependency, discriminator }) { - const kind = getValue(model, '/spec/tls/issuerRef/kind') - watchDependency('model#/spec/tls/issuerRef/kind') + if (!selectedConfig) { + commit('wizard/model$delete', `/spec/configuration/${type}removeCustomConfig`) + return [{ name: '', content: '' }] + } + commit('wizard/model$update', { + path: `/spec/configuration/${type}removeCustomConfig`, + value: true, + }) - if (kind) { - const apiGroup = getValue(discriminator, '/dbDetails/spec/tls/issuerRef/apiGroup') - if (apiGroup) return apiGroup - return 'cert-manager.io' - } else return undefined -} + const configuration = secretConfigData.find((item) => item.componentName === selectedConfig) -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - 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` + if (!configuration.data) { + return [{ name: '', content: '' }] + } - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + const configObj = [] + // Decode base64 and format as array of objects with name and content + Object.keys(configuration.data).forEach((fileName) => { try { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + // Decode base64 string + const decodedString = atob(configuration.data[fileName]) + configObj.push({ + name: fileName, + content: decodedString, + }) } catch (e) { - console.log(e) - presets.status = String(e.status) + 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: '' }] } - let clusterIssuers = presets.admin?.clusterIssuers?.available || [] - if (presets.status === '404') { - const url = `/clusters/${owner}/${cluster}/proxy/cert-manager.io/v1/clusterissuers` - return getIssuer(url) + 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: '' }] } - return clusterIssuers } - async function getIssuer(url) { - try { - const resp = await axios.get(url) - const resources = (resp && resp.data && resp.data.items) || [] + function onSelectedSecretChange(index) { + const secretData = getValue(discriminator, 'createSecret/data') || [] + const selfSecrets = secretData.map((item) => item.key) - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + 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 + } + + 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 getSelectedConfigSecret() { + 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() { + 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 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 } }, + }, }) - return resources + + const items = (resp && resp.data && resp.data.items) || [] + ans = items } catch (e) { console.log(e) - return [] } + + return ans } -} + async function getResourceList({ group, version, resource }) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function initTlsOperation() { - return 'update' -} -function onTlsOperationChange({ discriminator, getValue, commit }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` - commit('wizard/model$delete', '/spec/tls') + let ans = [] + try { + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) - if (tlsOperation === 'rotate') { - commit('wizard/model$update', { - path: '/spec/tls/rotateCertificates', - value: true, - force: true, + 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, }) - 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, + + 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, + } }) - commit('wizard/model$delete', '/spec/tls/certificates') - commit('wizard/model$delete', '/spec/tls/rotateCertificates') } -} + async function unNamespacedResourceNames(group, version, resource) { + let resources = await getResourceList({ + group, + version, + resource, + }) -function showIssuerRefAndCertificates({ discriminator, getValue, watchDependency }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') - watchDependency('discriminator#/tlsOperation') - const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } - return verd -} + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -function isIssuerRefRequired({ discriminator, getValue, watchDependency }) { - const hasTls = hasTlsField({ - discriminator, - getValue, - watchDependency, - }) + // reconfiguration type + function ifReconfigurationTypeEqualsTo(value) { + const reconfigurationType = getValue(discriminator, '/reconfigurationType') + // watchDependency('discriminator#/reconfigurationType') - return !hasTls -} + return reconfigurationType === value + } -function getRequestTypeFromRoute({ route, model, discriminator, getValue, watchDependency }) { - const isDbloading = isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) - const { query } = route || {} - const { requestType } = query || {} - return isDbloading ? '' : requestType || '' -} + 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`) + } + } -// ************************************** Set db details ***************************************** + // for tls + function hasTlsField() { + const tls = getDbTls() -function isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - watchDependency('model#/spec/databaseRef/name') - const dbDetails = getValue(discriminator, '/dbDetails') - const dbName = getValue(model, '/spec/databaseRef/name') + return !!tls + } - return !dbDetails || !dbName -} + function initIssuerRefApiGroup() { + const kind = getValue(model, '/spec/tls/issuerRef/kind') + // watchDependency('model#/spec/tls/issuerRef/kind') -function setValueFromDbDetails( - { discriminator, getValue, watchDependency, commit }, - path, - commitPath, -) { - watchDependency('discriminator#/dbDetails') + 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 [] + } - const retValue = getValue(discriminator, `/dbDetails${path}`) + 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 [] + } + } + } - if (commitPath && retValue) { + function initTlsOperation() { + return 'update' + } + function onTlsOperationChange() { const tlsOperation = getValue(discriminator, '/tlsOperation') - // computed called when tls fields is not visible - if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined + commit('wizard/model$delete', '/spec/tls') - // 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, - }) + 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') + } } - return retValue || undefined -} + function showIssuerRefAndCertificates() { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // watchDependency('discriminator#/tlsOperation') + const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} + return verd + } -function isNamespaceDisabled({ route }) { - const { namespace } = route.query || {} - return !!namespace -} + function isIssuerRefRequired() { + const hasTls = hasTlsField() + return hasTls ? false : '' + } -function isDatabaseRefDisabled({ route }) { - const { name } = route.params || {} - return !!name -} + function getRequestTypeFromRoute() { + const isDbloading = isDbDetailsLoading() + const { query } = route || {} + const { requestType } = query || {} + return isDbloading ? '' : requestType || '' + } -function onNamespaceChange({ commit }) { - commit('wizard/model$delete', '/spec/type') -} + function isDbDetailsLoading() { + // watchDependency('discriminator#/dbDetails') + // watchDependency('model#/spec/databaseRef/name') + const dbDetails = getValue(discriminator, '/dbDetails') + const dbName = getValue(model, '/spec/databaseRef/name') -function onDbChange({ commit, axios, storeGet, model, getValue, setDiscriminatorValue }) { - commit('wizard/model$delete', '/spec/type') - getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) -} + return !dbDetails || !dbName + } -function setApplyToIfReady() { - return 'IfReady' -} + function setValueFromDbDetails(path, commitPath) { + const retValue = getValue(discriminator, `/dbDetails${path}`) -function isVerticalScaleTopologyRequired({ watchDependency, getValue, discriminator, commit }) { - watchDependency('discriminator#/topologyKey') - watchDependency('discriminator#/topologyValue') + 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 - const key = getValue(discriminator, '/topologyKey') - const value = getValue(discriminator, '/topologyValue') - const path = `/spec/verticalScaling/redis/topology` + // 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 + } - if (key || value) { - commit('wizard/model$update', { - path: path, - value: { key, value }, - force: true, - }) - return true - } else { - commit('wizard/model$delete', path) - return false + function getAliasOptions() { + return ['server', 'client', 'metrics-exporter'] } -} -function checkVolume({ model, discriminator, getValue }, initpath, path) { - const volume = getValue(discriminator, `/dbDetails${initpath}`) - const input = getValue(model, path) + function isNamespaceDisabled() { + const { namespace } = route.query || {} + return !!namespace + } - try { - const sizeInBytes = parseSize(volume) - const inputSizeInBytes = parseSize(input) + function isDatabaseRefDisabled() { + const { name } = route.params || {} + return !!name + } - if (inputSizeInBytes >= sizeInBytes) return true - else return 'Cannot expand to lower volume!' - } catch (err) { - return err.message || 'Invalid' + function onNamespaceChange() { + commit('wizard/model$delete', '/spec/type') } -} -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 onDbChange() { + commit('wizard/model$delete', '/spec/type') + getDbDetails() + } -return { - fetchJsons, - returnFalse, - getNamespaces, - getDbs, - getDbDetails, - getDbVersions, - ifRequestTypeEqualsTo, - onRequestTypeChange, - getDbTls, - getDbType, - initNamespace, - initDatabaseRef, - isRancherManaged, - showAndInitName, - showAndInitNamespace, - showAndInitDatabaseRef, - showConfigureOpsrequestLabel, - showAndInitOpsRequestType, - - ifDbTypeEqualsTo, - getConfigSecrets, - createSecretUrl, - isEqualToValueFromType, - disableOpsRequest, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - ifReconfigurationTypeEqualsTo, - onReconfigurationTypeChange, - onApplyconfigChange, - hasTlsField, - initIssuerRefApiGroup, - getIssuerRefsName, - initTlsOperation, - onTlsOperationChange, - showIssuerRefAndCertificates, - isIssuerRefRequired, - getRequestTypeFromRoute, - isDbDetailsLoading, - setValueFromDbDetails, - getAliasOptions, - isNamespaceDisabled, - isDatabaseRefDisabled, - onNamespaceChange, - onDbChange, - setApplyToIfReady, - isVerticalScaleTopologyRequired, - getMachines, - setMachine, - onMachineChange, - isMachineCustom, - checkVolume, - setReplicas, + 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/redis/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 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, + }) + } + + return { + 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, + createSecretUrl, + isConfigSelected, + getSelectedConfigSecret, + getSelectedConfigSecretValue, + isEqualToValueFromType, + getNamespacedResourceList, + getResourceList, + resourceNames, + unNamespacedResourceNames, + ifReconfigurationTypeEqualsTo, + onReconfigurationTypeChange, + onApplyconfigChange, + hasTlsField, + initIssuerRefApiGroup, + getIssuerRefsName, + initTlsOperation, + onTlsOperationChange, + showIssuerRefAndCertificates, + isIssuerRefRequired, + getRequestTypeFromRoute, + isDbDetailsLoading, + setValueFromDbDetails, + getAliasOptions, + isNamespaceDisabled, + isDatabaseRefDisabled, + onDbChange, + onNamespaceChange, + setApplyToIfReady, + isVerticalScaleTopologyRequired, + getMachines, + setMachine, + onMachineChange, + isMachineCustom, + checkVolume, + setReplicas, + fetchConfigSecrets, + getConfigSecretsforAppyConfig, + getSelectedConfigurationData, + getSelectedConfigurationName, + getSelectedConfigurationValueForRemove, + createNewConfigSecret, + decodeError, + isCreateSecret, + isNotCreateSecret, + onCreateSecretChange, + cancelCreateSecret, + setApplyConfig, + onRemoveConfigChange, + onNewConfigSecretChange, + onSelectedSecretChange, + isTlsEnabled, + } } diff --git a/charts/opskubedbcom-singlestoreopsrequest-editor/ui/create-ui.yaml b/charts/opskubedbcom-singlestoreopsrequest-editor/ui/create-ui.yaml index 087fa58950..4f618f08b4 100644 --- a/charts/opskubedbcom-singlestoreopsrequest-editor/ui/create-ui.yaml +++ b/charts/opskubedbcom-singlestoreopsrequest-editor/ui/create-ui.yaml @@ -1,532 +1,825 @@ -steps: -- form: - discriminator: - dbDetails: - type: object +type: multi-step-form +step: + - type: single-step-form + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - schema: - $ref: discriminator#/properties/dbDetails - type: input - - if: showAndInitName - label: - text: labels.op_req_name - required: true - schema: - $ref: schema#/properties/metadata/properties/name - type: input - - computed: initNamespace - disabled: isNamespaceDisabled - fetch: getNamespaces - hasGroup: isRancherManaged - if: showAndInitNamespace - label: - text: labels.namespace - onChange: onNamespaceChange - required: true - schema: - $ref: schema#/properties/metadata/properties/namespace - type: select - - computed: initDatabaseRef - disabled: isDatabaseRefDisabled - fetch: getDbs - if: showAndInitDatabaseRef - label: - text: labels.databaseRef - onChange: onDbChange - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/databaseRef/properties/name - type: select - - if: showConfigureOpsrequestLabel - label: - text: labels.config_ops_request - type: label-element - - computed: getRequestTypeFromRoute - disabled: isDbDetailsLoading - hasDescription: true - if: showAndInitOpsRequestType - individualItemDisabilityCheck: disableOpsRequest - label: - text: labels.ops_request_type - onChange: onRequestTypeChange - options: - - description: options.UpdateVersion.description - text: options.UpdateVersion.text - value: UpdateVersion - - description: options.HorizontalScaling.description - text: options.HorizontalScaling.text - value: HorizontalScaling - - description: options.VerticalScaling.description - text: options.VerticalScaling.text - value: VerticalScaling - - description: options.VolumeExpansion.description - text: options.VolumeExpansion.text - value: VolumeExpansion - - description: options.Restart.description - text: options.Restart.text - value: Restart - - description: options.Reconfigure.description - text: options.Reconfigure.text - value: Reconfigure - - description: options.ReconfigureTLS.description - text: options.ReconfigureTLS.text - value: ReconfigureTLS - schema: - $ref: schema#/properties/spec/properties/type - type: radio - - elements: - - computed: setValueFromDbDetails|/spec/version - fetch: getDbVersions - label: - text: labels.targetVersion - schema: - $ref: schema#/properties/spec/properties/updateVersion/properties/targetVersion - type: select - if: ifRequestTypeEqualsTo|UpdateVersion - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/topology/aggregator/replicas - label: - text: Aggregator - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/aggregator - type: input - - computed: setValueFromDbDetails|/spec/topology/leaf/replicas - label: - text: Leaf - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/leaf - type: input - if: ifRequestTypeEqualsTo|HorizontalScaling - label: - text: Horizontal Scaling Form - type: single-step-form - - elements: - - discriminator: - machine-aggregator: - default: "" - type: string +# common + - type: input + label: op_req_name + if: + type: function + name: showAndInitName + validation: + type: required + schema: schema/properties/metadata/properties/name + - type: select + label: Namespace + if: + type: function + name: showAndInitNamespace + init: + type: func + value: initNamespace + disable: isNamespaceDisabled + loader: getNamespaces + validation: + type: required + hasGroup: isRancherManaged + schema: schema/properties/metadata/properties/namespace + - type: select + label: Database Ref + if: + type: function + name: showAndInitDatabaseRef + loader: + name: getDbs + watchPaths: + - schema/properties/metadata/properties/namespace + init: + type: func + value: initDatabaseRef + validation: + type: required + disable: isDatabaseRefDisabled + refresh: true + schema: schema/properties/spec/properties/databaseRef/properties/name + watcher: + func: onDbChange + paths: + - schema/properties/spec/properties/databaseRef/properties/name + - type: label-element + label: config_ops_request + if: + type: function + name: showConfigureOpsrequestLabel + - type: radio + label: Type of Ops Request + if: + type: function + name: showAndInitOpsRequestType + 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 + init: + type: func + value: getRequestTypeFromRoute + disable: isDbDetailsLoading + watcher: + func: isDbDetailsLoading + paths: + - temp/dbDetails + - schema/properties/spec/properties/databaseRef/properties/name + isHorizontal: true + schema: schema/properties/spec/properties/type +# UpdateVersion + - type: block-layout + showLabels: true + label: Version + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|UpdateVersion elements: - - computed: setMachine|aggregator - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|aggregator|/spec/topology/aggregator/podTemplate/spec/containers - schema: - $ref: discriminator#/machine-aggregator - type: select - - if: isMachineCustom|/machine-aggregator - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/aggregator/properties/resources - type: resource-input-form - - label: - text: Node Selection Policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/aggregator/properties/nodeSelectionPolicy - type: select - - elements: - - label: - text: key - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/aggregator/properties/topology/properties/key - type: input - - label: - text: value - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/aggregator/properties/topology/properties/value - type: input - label: - text: Topology - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/aggregator/properties/topology - show_label: true - type: single-step-form - if: ifDbTypeEqualsTo|Topology|VerticalScaling - label: - text: Aggregator - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/aggregator - show_label: true - type: single-step-form - - discriminator: - machine-leaf: - default: "" - type: string + - type: select-compare + label: Target Version + subtitle: Select the desired SingleStore version to which you want to update your database. + init: + type: func + value: setValueFromDbDetails|/spec/version + loader: getDbVersions + schema: schema/properties/spec/properties/updateVersion/properties/targetVersion + - type: info + label: '' + loader: + name: getVersionInfo + watchPaths: + - temp/properties/filteredVersion + if: + type: function + name: isVersionEmpty +# Horizontal Scale + - type: block-layout + label: Horizontal Scaling Form + showLabels: true + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|HorizontalScaling elements: - - computed: setMachine|leaf - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|leaf|/spec/topology/leaf/podTemplate/spec/containers - schema: - $ref: discriminator#/machine-leaf - type: select - - if: isMachineCustom|/machine-leaf - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/leaf/properties/resources - type: resource-input-form - - label: - text: Node Selection Policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/leaf/properties/nodeSelectionPolicy - type: select - - elements: - - label: - text: key - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/leaf/properties/topology/properties/key - type: input - - label: - text: value - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/leaf/properties/topology/properties/value - type: input - label: - text: Topology - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/leaf/properties/topology - show_label: true - type: single-step-form - if: ifDbTypeEqualsTo|Topology|VerticalScaling - label: - text: Leaf - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/leaf - show_label: true - type: single-step-form - - discriminator: - machine-node: - default: "" - type: string + - type: horizontal-layout + if: + type: function + name: ifDbTypeEqualsTo|Topology|HorizontalScaling + elements: + - type: input-compare + label: Aggregator + header: Aggregator + subtitle: Define the total number of aggregators for the database. Increasing aggregators improves fault tolerance and load distribution, while reducing aggregators conserves resources + init: + type: func + value: setValueFromDbDetails|/spec/topology/aggregator/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/aggregator + - type: info + hasIcon: true + label: Each aggregator represents an independent copy of your database. For example, setting this to 3 creates three copies of the database for better availability. + - type: horizontal-layout + if: + type: function + name: ifDbTypeEqualsTo|Topology|HorizontalScaling + elements: + - type: input-compare + label: Leaf + header: Leaf + subtitle: Define the total number of leaf nodes for the database. Increasing leaves improves fault tolerance and load distribution, while reducing leaves conserves resources + init: + type: func + value: setValueFromDbDetails|/spec/topology/leaf/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/leaf + - type: info + hasIcon: true + label: Each leaf represents an independent copy of your database. For example, setting this to 3 creates three copies of the database for better availability. +# vertical Scale + - type: block-layout + if: + type: function + name: ifRequestTypeEqualsTo|VerticalScaling elements: - - computed: setMachine|node - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|node|/spec/podTemplate/spec/containers - schema: - $ref: discriminator#/machine-node - type: select - - if: isMachineCustom|/machine-node - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/resources - type: resource-input-form - - label: - text: Node Selection Policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/nodeSelectionPolicy - type: select - - elements: - - label: - text: key - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/topology/properties/key - type: input - - label: - text: value - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/topology/properties/value - type: input - label: - text: Topology - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/topology - show_label: true - type: single-step-form - if: ifDbTypeEqualsTo|Combined|VerticalScaling - label: - text: Node - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node - show_label: true - type: single-step-form - - computed: setResource|/spec/topology/aggregator/podTemplate/spec/containers - if: ifDbTypeEqualsTo|Topology|VerticalScaling - label: - text: Coordinator - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/coordinator/properties/resources - type: resource-input-form - if: ifRequestTypeEqualsTo|VerticalScaling - type: single-step-form - - elements: - - elements: - - computed: setValueFromDbDetails|/spec/topology/aggregator/storage/resources/requests/storage - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/aggregator - type: input - validationRuleObject: - func: checkVolume|/spec/topology/aggregator/storage/resources/requests/storage|/spec/volumeExpansion/aggregator - if: ifDbTypeEqualsTo|Topology|VolumeExpansion - label: - text: Aggregator - show_label: true - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/topology/leaf/storage/resources/requests/storage - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/leaf - type: input - validationRuleObject: - func: checkVolume|/spec/topology/leaf/storage/resources/requests/storage|/spec/volumeExpansion/leaf - if: ifDbTypeEqualsTo|Topology|VolumeExpansion - label: - text: Leaf - show_label: true - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/storage/resources/requests/storage - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/node - type: input - validationRuleObject: - func: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/node - if: ifDbTypeEqualsTo|Combined|VolumeExpansion - label: - text: Node - show_label: true - type: single-step-form - - label: - text: Mode - options: - - text: Offline - value: Offline - - text: Online - value: Online - required: true - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/mode - type: select - if: ifRequestTypeEqualsTo|VolumeExpansion - label: - text: Volume Expansion Form - type: single-step-form - - elements: - - discriminator: - reconfigurationType: - type: string + - type: block-layout + label: Aggregator Vertical Scaling + if: + type: function + name: ifDbTypeEqualsTo|Topology|VerticalScaling + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines|aggregator + init: + type: func + value: setMachine|aggregator + watcher: + func: onMachineChange|aggregator|/spec/topology/aggregator/podTemplate/spec/containers + paths: + - temp/properties/machine-aggregator + schema: temp/properties/machine-aggregator + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/aggregator/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|aggregator + schema: temp/topologyKey-aggregator + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|aggregator + schema: temp/topologyValue-aggregator + - type: block-layout + label: Leaf Vertical Scaling + if: + type: function + name: ifDbTypeEqualsTo|Topology|VerticalScaling + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines|leaf + init: + type: func + value: setMachine|leaf + watcher: + func: onMachineChange|leaf|/spec/topology/leaf/podTemplate/spec/containers + paths: + - temp/properties/machine-leaf + schema: temp/properties/machine-leaf + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/leaf/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|leaf + schema: temp/topologyKey-leaf + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|leaf + schema: temp/topologyValue-leaf + - type: block-layout + label: Node Vertical Scaling + if: + type: function + name: ifDbTypeEqualsTo|Combined|VerticalScaling + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines|node + init: + type: func + value: setMachine|node + watcher: + func: onMachineChange|node|/spec/podTemplate/spec/containers + paths: + - temp/properties/machine-node + schema: temp/properties/machine-node + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/node/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|node + schema: temp/topologyKey-node + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|node + schema: temp/topologyValue-node + - type: block-layout + label: Coordinator Vertical Scaling + showLabels: true + if: + type: function + name: ifDbTypeEqualsTo|Topology|VerticalScaling + elements: + - type: machine-compare + label: Resources + loader: getMachines|coordinator + init: + type: func + value: setMachine|coordinator + watcher: + func: onMachineChange|coordinator|/spec/topology/aggregator/podTemplate/spec/containers + paths: + - temp/properties/machine-coordinator + schema: temp/properties/machine-coordinator + - type: block-layout + label: Exporter + showLabels: true + hideBlock: true + elements: + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setExporter|cpu + type: input + 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 + watcher: + func: onExporterResourceChange|memory + paths: + - schema/properties/spec/properties/verticalScaling/properties/exporter/properties/resources/properties/limits/properties/memory +# Volume Expansion + - type: block-layout + label: Volume Expansion Form + if: + type: function + name: ifRequestTypeEqualsTo|VolumeExpansion elements: - - label: - text: labels.reconfigurationType - onChange: onReconfigurationTypeChange - options: - - text: Select New Config Secret - value: selectNewConfigSecret - - text: Apply Config - value: applyConfig - - text: Remove - value: remove - required: true - schema: - $ref: discriminator#/properties/reconfigurationType - type: radio - - addFormLabel: labels.applyConfig.label - element: - discriminator: - configArray: - emitAs: applyConfig - type: array + - type: horizontal-layout elements: - - label: - text: labels.applyConfig.key - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/key - type: input - - label: - text: labels.applyConfig.value - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/value - type: editor - type: single-step-form - if: ifReconfigurationTypeEqualsTo|applyConfig - label: - text: labels.applyConfig.label - onChange: onApplyconfigChange - required: true - schema: - $ref: discriminator#/properties/applyConfig - tableContents: - - inTableColumn: true - label: - text: labels.applyConfig.key - path: key - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.applyConfig.value - path: value - type: value - typeOfValue: code - type: single-step-form-array - - if: returnFalse - label: - text: labels.removeCustomConfig - schema: - $ref: schema#/properties/spec/properties/configuration/properties/node/properties/removeCustomConfig - type: switch - label: - text: labels.configuration - schema: - $ref: schema#/properties/spec/properties/configuration - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|Reconfigure - label: - text: Reconfigure Form - type: single-step-form - - discriminator: - tlsOperation: - default: update - type: string - elements: - - computed: initTlsOperation - if: hasTlsField - label: - text: labels.tlsOperation - onChange: onTlsOperationChange - options: - - text: Update - value: update - - text: Rotate - value: rotate - - text: Remove - value: remove - schema: - $ref: discriminator#/properties/tlsOperation - type: radio - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/remove - type: switch - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/rotateCertificates - type: switch - - elements: - - computed: initIssuerRefApiGroup - disabled: true - label: - text: labels.api_group - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup - type: input - - computed: setValueFromDbDetails|/spec/tls/issuerRef/kind - label: - text: labels.kind - options: - - text: Issuer - value: Issuer - - text: ClusterIssuer - value: ClusterIssuer - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/kind - sortable: true - type: select - - allowUserDefinedOption: true - computed: setValueFromDbDetails|/spec/tls/issuerRef/name - fetch: getIssuerRefsName - label: - text: labels.name - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/name - sortable: true - type: select - if: showIssuerRefAndCertificates - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef - type: single-step-form - - alias: reusable_certificates - chart: - name: uibytebuildersdev-component-certificates - version: v0.29.0 - computed: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates - functionCallbacks: - getAliasOptions: - $ref: functions#/getAliasOptions - if: showIssuerRefAndCertificates - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/spec/properties/tls/properties/certificates - type: reusable-element - if: ifRequestTypeEqualsTo|ReconfigureTLS - label: - text: labels.tls - schema: - $ref: schema#/properties/spec/properties/tls - type: single-step-form - - label: - text: labels.timeout - options: - - text: 5 minutes - value: 5m - - text: 10 minutes - value: 10m - - text: 30 minutes - value: 30m - - text: 1 hour - value: 1h - - text: 2 hours - value: 2h - - text: 5 hours - value: 5h - - text: 10 hours - value: 10h - schema: - $ref: schema#/properties/spec/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: labels.apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/spec/properties/apply - type: radio - type: single-step-form - id: basic - title: steps.0.label -type: multi-step-form + - type: block-layout + elements: + - type: label-element + 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: select + label: Mode + options: + - text: Offline + value: Offline + - text: Online + value: Online + validation: + type: required + schema: schema/properties/spec/properties/volumeExpansion/properties/mode + - type: block-layout + label: Aggregator Volume Expansion + showLabels: true + fixedBlock: true + if: + type: function + name: ifDbTypeEqualsTo|Topology|VolumeExpansion + elements: + - type: horizontal-layout + elements: + - type: input-compare + label: Storage Size + init: + type: func + value: setValueFromDbDetails|/spec/topology/aggregator/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/topology/aggregator/storage/resources/requests/storage|/spec/volumeExpansion/aggregator + schema: schema/properties/spec/properties/volumeExpansion/properties/aggregator + - type: block-layout + label: Leaf Volume Expansion + showLabels: true + fixedBlock: true + if: + type: function + name: ifDbTypeEqualsTo|Topology|VolumeExpansion + elements: + - type: horizontal-layout + elements: + - type: input-compare + label: Storage Size + init: + type: func + value: setValueFromDbDetails|/spec/topology/leaf/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/topology/leaf/storage/resources/requests/storage|/spec/volumeExpansion/leaf + schema: schema/properties/spec/properties/volumeExpansion/properties/leaf + - type: block-layout + label: Node Volume Expansion + showLabels: true + fixedBlock: true + if: + type: function + name: ifDbTypeEqualsTo|Combined|VolumeExpansion + elements: + - type: horizontal-layout + elements: + - type: label-element + label: Storage Size + 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: info + hasIcon: true + label: Storage expansion allows you to increase your database's disk space without downtime (Online mode) or with brief downtime (Offline mode). + - type: input-compare + label: Storage Size + init: + type: func + value: setValueFromDbDetails|/spec/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/node + schema: schema/properties/spec/properties/volumeExpansion/properties/node +# Reconfigure + - type: block-layout + label: Reconfigure Form + if: + name: ifRequestTypeEqualsTo|Reconfigure + type: function + loader: + name: fetchConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + elements: + - type: block-layout + label: Configuration + elements: + - type: label-element + label: '' + subtitle: Select a new configuration secret, apply a custom configuration, or remove an existing setup to update your database settings + - type: tab-layout + label: New Config Secret + schema: temp/properties/reconfigurationType + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + elements: + - type: block-layout + label: Config Secret + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret + type: function + elements: + - type: label-element + label: Config Secret + subtitle: Select a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: schema/properties/spec/properties/configuration/properties/configSecret/properties/name + refresh: true + label: Config Secret + loader: + name: getConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/createSecret/properties/status + init: + type: func + value: setValueFromDbDetails|/spec/configSecret/name + watcher: + func: onCreateSecretChange + paths: + - temp/properties/createSecret/properties/status + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|create + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + - type: block-layout + label: Create a New Config Secret + showLabels: true + if: + type: function + name: isCreateSecret + hasButton: + text: Save + hasCancel: cancelCreateSecret + action: createNewConfigSecret + elements: + - type: input + label: Secret Name + schema: temp/properties/createSecret/properties/name + validation: + type: required + - type: array-object-form + label: String Data + schema: temp/properties/createSecret/properties/data + buttonClass: is-light is-outlined + validation: + type: required + elements: + - type: select + label: Key + schema: key + loader: + name: onSelectedSecretChange + watchPaths: + - temp/properties/createSecret/properties/data + validation: + type: required + - type: textarea + label: Value + schema: value + - type: multi-file-editor + editorHeight: 500px + readonly: true + if: + type: function + name: isNotCreateSecret + loader: + name: onNewConfigSecretChange + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + schema: temp/properties/newConfigSecret + - type: block-layout + label: ApplyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig + type: function + elements: + - type: label-element + 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). + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfiguration + refresh: true + label: Configuration + loader: getConfigSecretsforAppyConfig + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|apply + watchPaths: + - temp/properties/selectedConfiguration + - type: multi-file-editor + editorHeight: 500px + schema: temp/properties/applyConfig + loader: + name: setApplyConfig + watchPaths: + - temp/properties/selectedConfiguration + watcher: + func: onApplyconfigChange + paths: + - temp/properties/applyConfig + - type: block-layout + label: Remove + if: + name: ifReconfigurationTypeEqualsTo|remove + type: function + elements: + - type: label-element + label: Remove + subtitle: Selected a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfigurationRemove + refresh: true + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|remove + watchPaths: + - temp/properties/selectedConfigurationRemove + - type: multi-file-editor + editorHeight: 500px + readonly: true + init: + type: func + value: onRemoveConfigChange + watcher: + func: onRemoveConfigChange + paths: + - temp/properties/selectedConfigurationRemove + schema: temp/properties/removeConfig + +# Reconfigure TLS + - type: block-layout + label: TLS + if: + name: ifRequestTypeEqualsTo|ReconfigureTLS + type: function + elements: + - type: radio + label: TLS Operation + if: + name: hasTlsField + type: function + options: + - text: Update + value: update + - text: Rotate + value: rotate + - text: Remove + value: remove + init: + type: func + value: initTlsOperation + watcher: + func: onTlsOperationChange + paths: + - temp/properties/tlsOperation + schema: temp/properties/tlsOperation + - type: switch + label: Remove TLS + fullwidth: true + if: + name: isTlsEnabled + type: function + schema: schema/properties/spec/properties/tls/properties/remove + - type: switch + label: Rotate Certificates + fullwidth: true + schema: schema/properties/spec/properties/tls/properties/rotateCertificates + if: + name: isTlsEnabled + type: function + - type: block-layout + label: Issuer Reference + showLabels: true + if: + name: showIssuerRefAndCertificates + type: function + elements: + - type: input + label: API Group + init: + type: func + value: initIssuerRefApiGroup + watcher: + func: initIssuerRefApiGroup + paths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + disable: true + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup + - type: select + label: Kind + options: + - text: Issuer + value: Issuer + - text: ClusterIssuer + value: ClusterIssuer + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/kind + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - type: select + label: Name + loader: + name: getIssuerRefsName + watchPaths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - schema/properties/metadata/properties/namespace + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/name + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/name + - type: block-layout + label: Certificates + showLabels: false + if: + name: showIssuerRefAndCertificates + type: function + loader: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates + elements: + - type: array-object-form + label: Certificates + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/tls/properties/certificates + elements: + - type: select + label: Alias + loader: fetchAliasOptions + disable: disableAlias + schema: alias + validation: + type: required + - type: input + label: Secret Name + schema: secretName + - type: input + label: Duration + schema: duration + - type: input + label: Renew Before + schema: renewBefore + - type: array-item-form + label: Organizations + buttonClass: is-light is-outlined + schema: subject/properties/organizations + element: + type: input + label: Organization + - type: array-item-form + label: Countries + buttonClass: is-light is-outlined + schema: subject/properties/countries + element: + type: input + label: Country + - type: array-item-form + label: Organizational Units + buttonClass: is-light is-outlined + schema: subject/properties/organizationalUnits + element: + type: input + label: Organizational Unit + - type: array-item-form + label: Provinces + buttonClass: is-light is-outlined + schema: subject/properties/provinces + element: + type: input + label: Province + - type: array-item-form + label: DNS Names + buttonClass: is-light is-outlined + schema: dnsNames + element: + type: input + label: DNS Name + - type: array-item-form + label: IP Addresses + buttonClass: is-light is-outlined + schema: ipAddresses + element: + type: input + label: IP Address +# common + - type: block-layout + label: Ops Request Options + showLabels: true + elements: + - type: time-picker + label: Timeout + schema: 'schema/properties/spec/properties/timeout' + - type: radio + label: apply + schema: 'schema/properties/spec/properties/apply' + init: + type: func + value: setApplyToIfReady + options: + - text: IfReady (OpsRequest will be applied if database is ready) + value: IfReady + - text: Always (OpsRequest will always be applied) + value: Always diff --git a/charts/opskubedbcom-singlestoreopsrequest-editor/ui/functions.js b/charts/opskubedbcom-singlestoreopsrequest-editor/ui/functions.js index 99b52cb778..e277ac5c0a 100644 --- a/charts/opskubedbcom-singlestoreopsrequest-editor/ui/functions.js +++ b/charts/opskubedbcom-singlestoreopsrequest-editor/ui/functions.js @@ -1,3 +1,4 @@ +const { axios, useOperator, store, useToast } = window.vueHelpers || {} const machines = { 'db.t.micro': { resources: { @@ -304,181 +305,231 @@ const machineList = [ 'db.r.24xlarge', ] -async function fetchJsons({ axios, itemCtx }) { - let ui = {} - let language = {} - let functions = {} - const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart +let machinesFromPreset = [] +const configSecretKeys = ['kubedb-user.cnf'] - 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) - } +export const useFunc = (model) => { + const route = store.state?.route + const toast = useToast() - return { - ui: ui.data || {}, - language: language.data || {}, - functions, + 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 returnFalse() { + return false + } -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function isTlsEnabled() { + const dbDetails = getValue(discriminator, '/dbDetails') + return ( + (dbDetails?.spec?.sslMode && + dbDetails?.spec?.sslMode !== 'disabled' && + dbDetails?.spec?.sslMode !== 'disable') || + dbDetails?.spec?.tls + ) + } -async function getNamespaces({ axios, storeGet }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + async function getNamespaces() { + if (storeGet('/route/params/actions')) return [] + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - const resources = (resp && resp.data && resp.data.items) || [] + const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { + params: { filter: { items: { metadata: { name: null } } } }, + }) - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + const resources = (resp && resp.data && resp.data.items) || [] -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/namespace') + async function getDbs() { + 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/kubedb.com/v1alpha2/namespaces/${namespace}/singlestores`, - { - params: { filter: { items: { metadata: { name: null } } } }, - }, - ) + const namespace = getValue(model, '/metadata/namespace') + // watchDependency('model#/metadata/namespace') - const resources = (resp && resp.data && resp.data.items) || [] + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/singlestores`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + const resources = (resp && resp.data && resp.data.items) || [] -async function getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) { - 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') + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } - if (namespace && name) { - const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/singlestores/${name}` - const resp = await axios.get(url) + async function getDbDetails() { + machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] - setDiscriminatorValue('/dbDetails', resp.data || {}) + 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') - return resp.data || {} - } else return {} -} + if (namespace && name) { + const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/singlestores/${name}` + const resp = await axios.get(url) -async function getDbVersions({ axios, storeGet, getValue, discriminator }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + setDiscriminatorValue('/dbDetails', resp.data || {}) - const url = `/clusters/${owner}/${cluster}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/kubedb-ui-presets` + return resp.data || {} + } else return {} + } - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + 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 { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + presetVersions = presets.admin?.databases?.Singlestore?.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/singlestoreversions`, + { + 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 allowed = found?.spec?.updateConstraints?.allowlist || [] + 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 filteredSinglestoreVersions = 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.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.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.includes(item.metadata?.name)) && + isVersionWithinConstraints(item.spec?.version, limit) + ) + }) + setDiscriminatorValue('/filteredVersion', filteredSinglestoreVersions) + return filteredSinglestoreVersions.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) - presets.status = String(e.status) + return [] } } - try { - const presetVersions = presets.admin?.databases?.Singlestore?.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/singlestoreversions`, - { - params: queryParams, - }, - ) + function getVersionInfo() { + const filteredVersion = getValue(discriminator, '/filteredVersion') + if (filteredVersion.length) return '' - const resources = (resp && resp.data && resp.data.items) || [] + let txt = 'No versions from this list can be selected as the target version: [ ' - 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 allowed = found?.spec?.updateConstraints?.allowlist || [] - 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 filteredSinglestoreVersions = 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.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.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.includes(item.metadata?.name)) && - isVersionWithinConstraints(item.spec?.version, limit) - ) + presetVersions.forEach((v, idx) => { + txt = `${txt}"${v}"` + if (idx !== presetVersions.length - 1) txt = txt + ', ' + else txt = txt + ' ]' }) - return filteredSinglestoreVersions.map((item) => { + return txt + } + + function getVersion() { + return filteredVersion.map((item) => { const name = (item.metadata && item.metadata.name) || '' const specVersion = (item.spec && item.spec.version) || '' return { @@ -486,831 +537,1360 @@ async function getDbVersions({ axios, storeGet, getValue, discriminator }) { value: name, } }) - } catch (e) { - console.log(e) - return [] } -} -function versionCompare(v1, v2) { - const arr1 = v1.split('.').map(Number) - const arr2 = v2.split('.').map(Number) + 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 + 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 + if (num1 > num2) return 1 // v1 is higher + if (num1 < num2) return -1 // v2 is higher + } + return 0 // versions are equal } - 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 + 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 } - return true -} -function ifRequestTypeEqualsTo({ model, getValue, watchDependency }, type) { - const selectedType = getValue(model, '/spec/type') - watchDependency('model#/spec/type') + function ifRequestTypeEqualsTo(type) { + const selectedType = getValue(model, '/spec/type') + // watchDependency('model#/spec/type') - return selectedType === type -} + return selectedType === type + } -function onRequestTypeChange({ model, getValue, commit }) { - 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 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', + } -function disableOpsRequest({ itemCtx, discriminator, getValue, watchDependency }) { - if (itemCtx.value === 'HorizontalScaling') { - const dbType = getDbType({ - discriminator, - getValue, - watchDependency, + Object.keys(reqTypeMapping).forEach((key) => { + if (key !== selectedType) commit('wizard/model$delete', `/spec/${reqTypeMapping[key]}`) }) + } - if (dbType === 'Standalone') return true - else return false - } else return false -} + function getDbTls() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') -function getDbTls({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + const { spec } = dbDetails || {} + return spec?.tls || undefined + } - const { spec } = dbDetails || {} - return spec?.tls || undefined -} + function getDbType() { + // watchDependency('discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') + const { spec } = dbDetails || {} + const { topology } = spec || {} + if (topology) return 'Topology' + else return 'Combined' + } -function getDbType({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') - const { spec } = dbDetails || {} - const { topology } = spec || {} - if (topology) return 'Topology' - else return 'Combined' -} + function disableOpsRequest() { + if (itemCtx.value === 'HorizontalScaling') { + const dbType = getDbType({ + discriminator, + getValue, + }) -function initNamespace({ route }) { - const { namespace } = route.query || {} - return namespace || null -} + if (dbType === 'Standalone') return true + else return false + } else return false + } -function initDatabaseRef({ route, watchDependency }) { - watchDependency('model#/metadata/namespace') - const { name } = route.params || {} - return name -} + function initNamespace() { + const { namespace } = route.query || {} + return namespace || null + } -function asDatabaseOperation(route) { - return !!route.params.actions -} + function initDatabaseRef() { + // watchDependency('model#/metadata/namespace') + const { name } = route.params || {} + return name + } -function generateOpsRequestNameForClusterUI(getValue, model, route) { - const dbName = getValue(model, '/spec/databaseRef/name') + function asDatabaseOperation() { + return !!route.params.actions + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + function generateOpsRequestNameForClusterUI(getValue, model, route) { + const dbName = getValue(model, '/spec/databaseRef/name') - const resources = route.params.resource || '' - const resource = resources.slice(0, -1) + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' - const opsName = dbName ? dbName : resource - return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` -} + const resources = route.params.resource || '' + const resource = resources.slice(0, -1) -function showAndInitName({ route, commit, getValue, model, watchDependency }) { - watchDependency('model#/spec/type') - watchDependency('model#/spec/databaseRef/name') - const ver = asDatabaseOperation(route) + const opsName = dbName ? dbName : resource + return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + function showAndInitName() { + // watchDependency('model#/spec/type') + // watchDependency('model#/spec/databaseRef/name') + const ver = asDatabaseOperation() - 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, - }) + 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 } - return !ver -} -function showAndInitNamespace({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/metadata/namespace', - value: `${route.query.namespace}`, - force: true, + + 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(type) { + const presets = storeGet('/kubedbuiPresets') || {} + const dbDetails = getValue(discriminator, '/dbDetails') + // const limits = dbDetails?.spec?.podTemplate?.spec?.resources?.limits || {} + const limits = (type && type !== 'node' + ? dbDetails?.spec?.topology?.[type]?.podTemplate?.spec?.containers?.[0]?.resources?.requests + : dbDetails?.spec?.podTemplate?.spec?.containers?.[0]?.resources?.requests) || { + cpu: '', + memory: '', + } + + 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(type) { + const dbDetails = getValue(discriminator, '/dbDetails') + let limits = {} + 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 = {} + } + const machine = parsedInstance[type] || 'custom' + + const machinePresets = machinesFromPreset.find((item) => item.id === machine) + if (machinePresets) { + return { + machine: machine, + cpu: machinePresets.limits.cpu, + memory: machinePresets.limits.memory, + } + } else { + // For coordinator, get limits from containers + if (type === 'coordinator') { + const containers = + dbDetails?.spec?.topology?.aggregator?.podTemplate?.spec?.containers || [] + const kind = dbDetails?.kind + const resource = containers.filter((ele) => ele.name === kind?.toLowerCase()) + limits = resource[0]?.resources?.requests || {} + console.log({ limits }) + } else if (type === 'node') { + const containers = dbDetails?.spec?.podTemplate?.spec?.containers || [] + const kind = dbDetails?.kind + const resource = containers.filter((ele) => ele.name === kind?.toLowerCase()) + limits = resource[0]?.resources?.requests || {} + } else { + // For aggregator and leaf + const topologyLimits = + dbDetails?.spec?.topology?.[type]?.podTemplate?.spec?.containers?.[0]?.resources + ?.requests || {} + limits = topologyLimits + } + return { machine: 'custom', cpu: limits.cpu, memory: limits.memory } + } + } + + function onMachineChange(type, valPath) { + let selectedMachine = {} + selectedMachine = getValue(discriminator, `/machine-${type}`) + 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') || {} + const instance = annotations['kubernetes.io/instance-type'] + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = {} + } + parsedInstance[type] = selectedMachine.machine + annotations['kubernetes.io/instance-type'] = JSON.stringify(parsedInstance) + + if (machinesFromPreset.length) + commit('wizard/model$update', { + path: '/metadata/annotations', + value: annotations, + force: true, + }) + + if (parsedInstance && Object.keys(parsedInstance).length === 0) + commit('wizard/model$delete', '/metadata/annotations') + } + + function isMachineCustom(path) { + // watchDependency(`discriminator#${path}`) + const machine = getValue(discriminator, `${path}`) + return machine === 'custom' + } + + function setResource(path) { + // watchDependency('discriminator#/dbDetails') + const containers = getValue(discriminator, `/dbDetails${path}`) || [] + const kind = getValue(discriminator, '/dbDetails/kind') + const resource = containers.filter((ele) => ele.name === kind?.toLowerCase()) + return resource[0]?.resources + } + + // Fetch and store database Infos + // for secret configurations in reconfigure + let configSecrets = [] + let secretConfigData = [] + + 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) + } + } + + 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 } - return !ver -} -function showAndInitDatabaseRef({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/spec/databaseRef/name', - value: `${route.params.name}`, - force: true, + async function getConfigSecretsforAppyConfig() { + const secrets = secretConfigData.map((item) => { + return { text: item.componentName, value: item.componentName } }) + return secrets } - return !ver -} -function showConfigureOpsrequestLabel({ route }) { - return !asDatabaseOperation(route) -} -function showAndInitOpsRequestType({ route, commit }) { - const ver = asDatabaseOperation(route) - const opMap = { - upgrade: 'UpdateVersion', - updateVersion: 'UpdateVersion', - horizontalscaling: 'HorizontalScaling', - verticalscaling: 'VerticalScaling', - volumeexpansion: 'VolumeExpansion', - restart: 'Restart', - reconfiguretls: 'ReconfigureTLS', - reconfigure: 'Reconfigure', - } - if (ver) { - const operation = route.params.actions - const match = /^(.*)-opsrequest-(.*)$/.exec(operation) - const opstype = match[2] + 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: '/spec/type', - value: opMap[opstype], + path: `/temp/${type}applyConfig`, + value: result, force: true, }) + + return result } - return !ver -} + 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` -// vertical scaling -function ifDbTypeEqualsTo({ discriminator, getValue, watchDependency, commit }, value, opsReqType) { - const verd = getDbType({ - discriminator, - getValue, - watchDependency, - }) - return value === verd -} + const selectedConfiguration = + configType === 'create' ? getValue(model, path) : getValue(discriminator, path) -// machine profile stuffs -let machinesFromPreset = [] + 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) -function getMachines({ storeGet }) { - const presets = storeGet('/kubedbuiPresets') || {} - const avlMachines = presets.admin?.machineProfiles?.available || [] - let arr = [] - if (avlMachines.length) { - arr = avlMachines.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - 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 } - } else return { text: machine, value: machine } + 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 } }) - } else { - arr = machineList - .map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + + // 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])) + + 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', }) - .filter((val) => !!val) + 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 arr -} -function setMachine({ getValue, discriminator, storeGet }, type) { - const dbDetails = getValue(discriminator, '/dbDetails') - 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 = {} + 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 + ) } - const machine = parsedInstance[type] || 'custom' - machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] + function isCreateSecret(type) { + type = type ? type + '/' : '' + const selectedSecret = getValue(model, `spec/configuration/${type}configSecret/name`) + const res = selectedSecret === 'Create' - const machinePresets = machinesFromPreset.find((item) => item.id === machine) - if (machinePresets) return machine - else return 'custom' -} + if (res === true) { + commit('wizard/temp$update', { + path: `${type}createSecret/status`, + value: 'pending', + }) + } + return res + } + + function isNotCreateSecret(type) { + return !isCreateSecret(type) + } -function onMachineChange({ getValue, discriminator, commit, model }, type, valPath) { - let selectedMachine = '' - selectedMachine = getValue(discriminator, `/machine-${type}`) - const machine = machinesFromPreset.find((item) => item.id === selectedMachine) + 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 } : '' + } + } - let obj = {} - if (selectedMachine !== 'custom') { - if (machine) obj = { limits: { ...machine?.limits }, requests: { ...machine?.limits } } - else obj = machines[selectedMachine]?.resources - } else { - const val = getValue(discriminator, `/dbDetails${valPath}`) || {} - obj = Array.isArray(val) ? val[0]?.resources : { ...val } + 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', + }) } - const path = `/spec/verticalScaling/${type}/resources` + async function onApplyconfigChange(type) { + type = type ? type + '/' : '' + const configValue = getValue(discriminator, `${type}applyConfig`) - if (obj && Object.keys(obj).length) + if (!configValue) { + commit('wizard/model$delete', `/spec/configuration/${type}applyConfig`) + return + } + const tempConfigObj = {} + configValue.forEach((item) => { + if (item.name) { + 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: path, - value: obj, - force: true, + path: `/spec/configuration/${type}applyConfig`, + value: tempConfigObj, }) + } - // update metadata.annotations - const annotations = getValue(model, '/metadata/annotations') || {} - const instance = annotations['kubernetes.io/instance-type'] - let parsedInstance = {} - try { - if (instance) parsedInstance = JSON.parse(instance) - } catch (e) { - console.log(e) - parsedInstance = {} - } - if (selectedMachine === 'custom') delete parsedInstance[type] - else parsedInstance[type] = selectedMachine - annotations['kubernetes.io/instance-type'] = JSON.stringify(parsedInstance) - - if (machinesFromPreset.length) + 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], + }) + }) + } else { + configObj.push({ name: '', 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: '/metadata/annotations', - value: annotations, - force: true, + path: `/spec/configuration/${type}removeCustomConfig`, + value: true, }) - if (parsedInstance && Object.keys(parsedInstance).length === 0) - commit('wizard/model$delete', '/metadata/annotations') -} + const configuration = secretConfigData.find((item) => item.componentName === selectedConfig) -function isMachineCustom({ watchDependency, getValue, discriminator }, path) { - watchDependency(`discriminator#${path}`) - const machine = getValue(discriminator, `${path}`) - return machine === 'custom' -} + if (!configuration.data) { + return [{ name: '', content: '' }] + } -// for config secret -async function getConfigSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + 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 + } - const secrets = (resp && resp.data && resp.data.items) || [] + async function onNewConfigSecretChange(type) { + type = type ? type + '/' : '' + const path = `/spec/configuration/${type}configSecret/name` + const selectedSecret = getValue(model, path) - const filteredSecrets = secrets + if (!selectedSecret) { + commit('wizard/model$delete', `/spec/configuration/${type}configSecret`) + return [{ name: '', content: '' }] + } + if (selectedSecret === 'Create') return [{ name: '', content: '' }] - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return filteredSecrets -} + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = storeGet('/route/query/namespace') || getValue(model, '/metadata/namespace') -function createSecretUrl({ storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 + }) + } + }) - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/secrets/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/secrets/create` + return configObj + } catch (e) { + console.error('Error fetching secret:', e) + return [{ name: '', content: '' }] + } } -} - -function isEqualToValueFromType({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/valueFromType') - const valueFrom = getValue(discriminator, '/valueFromType') - return valueFrom === value -} -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function onSelectedSecretChange(index) { + const secretData = getValue(discriminator, 'createSecret/data') || [] + const selfSecrets = secretData.map((item) => item.key) - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + const remainingSecrets = configSecretKeys.filter((item) => !selfSecrets.includes(item)) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, + 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 = [] - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + function isConfigSelected() { + const path = `/spec/configuration/configSecret/name` + const selectedSecret = getValue(model, path) + return !!selectedSecret } - return ans -} -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function getSelectedConfigSecret() { + const path = `/spec/configuration/configSecret/name` + const selectedSecret = getValue(model, path) + // watchDependency(`model#${path}`) + return `You have selected ${selectedSecret} secret` || 'No secret selected' + } - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` + function objectToYaml(obj, indent = 0) { + if (obj === null || obj === undefined) return 'null' + if (typeof obj !== 'object') return JSON.stringify(obj) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }) + 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}:` - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + 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') } - return ans -} -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - group, - version, - resource, -) { - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/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) + function getSelectedConfigSecretValue() { + 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' } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + 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` } - }) -} -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - 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, + 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) } - }) -} -// reconfiguration type -function ifReconfigurationTypeEqualsTo({ discriminator, getValue, watchDependency }, value) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - watchDependency('discriminator#/reconfigurationType') + return ans + } + async function getResourceList({ group, version, resource }) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - return reconfigurationType === value -} + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` -function onApplyconfigChange({ discriminator, getValue, commit }) { - const applyconfig = getValue(discriminator, '/applyConfig') + let ans = [] + try { + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) - const configObj = {} - if (applyconfig) { - applyconfig.forEach((item) => { - const { key, value } = item - configObj[key] = value - }) + 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, + }) - commit('wizard/model$update', { - path: '/spec/configuration/applyConfig', - value: configObj, - force: true, - }) -} + 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, + }) -function onReconfigurationTypeChange({ commit, discriminator, getValue, setDiscriminatorValue }) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - setDiscriminatorValue('/applyConfig', []) - if (reconfigurationType === 'remove') { - commit('wizard/model$delete', `/spec/configuration`) + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } - commit('wizard/model$update', { - path: `/spec/configuration/removeCustomConfig`, - value: true, - force: true, + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } }) - } 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({ discriminator, getValue, watchDependency }) { - const tls = getDbTls({ - discriminator, - getValue, - watchDependency, - }) + // reconfiguration type + function ifReconfigurationTypeEqualsTo(value) { + const reconfigurationType = getValue(discriminator, '/reconfigurationType') - return !!tls -} + const watchPath = 'discriminator#/reconfigurationType' + // watchDependency(watchPath) + return reconfigurationType === value + } -function initIssuerRefApiGroup({ getValue, model, watchDependency, discriminator }) { - const kind = getValue(model, '/spec/tls/issuerRef/kind') - watchDependency('model#/spec/tls/issuerRef/kind') + function onReconfigurationTypeChange() { + setDiscriminatorValue('/applyConfig', []) + const reconfigurationType = getValue(discriminator, '/reconfigurationType') + if (reconfigurationType === 'remove') { + commit('wizard/model$delete', `/spec/configuration`) - if (kind) { - const apiGroup = getValue(discriminator, '/dbDetails/spec/tls/issuerRef/apiGroup') - if (apiGroup) return apiGroup - return 'cert-manager.io' - } else return undefined -} + 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`) + } + } -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - 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` + // for tls + function hasTlsField() { + const tls = getDbTls() - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + return !!tls + } + + function initIssuerRefApiGroup() { + const kind = getValue(model, '/spec/tls/issuerRef/kind') + // watchDependency('model#/spec/tls/issuerRef/kind') + + if (kind) { + 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 presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + 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) - presets.status = String(e.status) + return [] } } - 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 } - async function getIssuer(url) { - try { - const resp = await axios.get(url) - const resources = (resp && resp.data && resp.data.items) || [] + function initTlsOperation() { + return 'update' + } + function onTlsOperationChange() { + const tlsOperation = getValue(discriminator, '/tlsOperation') - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + commit('wizard/model$delete', '/spec/tls') + + if (tlsOperation === 'rotate') { + commit('wizard/model$update', { + path: '/spec/tls/rotateCertificates', + value: true, + force: true, + }) + } else if (tlsOperation === 'remove') { + commit('wizard/model$update', { + path: '/spec/tls/remove', + value: true, + force: true, }) - return resources - } catch (e) { - console.log(e) - return [] } } -} -function initTlsOperation() { - return 'update' -} -function onTlsOperationChange({ discriminator, getValue, commit }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + function showIssuerRefAndCertificates() { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // watchDependency('discriminator#/tlsOperation') + const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' - commit('wizard/model$delete', '/spec/tls') + return verd + } - 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 isIssuerRefRequired() { + const hasTls = hasTlsField() + return hasTls ? false : '' } -} -function showIssuerRefAndCertificates({ discriminator, getValue, watchDependency }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') - watchDependency('discriminator#/tlsOperation') - const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' + function getRequestTypeFromRoute() { + const isDbloading = isDbDetailsLoading() + const { query } = route || {} + const { requestType } = query || {} + return isDbloading ? '' : requestType || '' + } - return verd -} + function isDbDetailsLoading() { + // watchDependency('discriminator#/dbDetails') + // watchDependency('model#/spec/databaseRef/name') + const dbDetails = getValue(discriminator, '/dbDetails') + const dbName = getValue(model, '/spec/databaseRef/name') -function isIssuerRefRequired({ discriminator, getValue, watchDependency }) { - const hasTls = hasTlsField({ - discriminator, - getValue, - watchDependency, - }) + return !dbDetails || !dbName + } - return !hasTls -} + function setValueFromDbDetails(path, commitPath) { + const retValue = getValue(discriminator, `/dbDetails${path}`) -function getRequestTypeFromRoute({ route, model, discriminator, getValue, watchDependency }) { - const isDbloading = isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) - const { query } = route || {} - const { requestType } = query || {} - return isDbloading ? '' : requestType || '' -} + if (commitPath) { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // computed called when tls fields is not visible + if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined -// ************************************** Set db details ***************************************** + // 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 isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - watchDependency('model#/spec/databaseRef/name') - const dbDetails = getValue(discriminator, '/dbDetails') - const dbName = getValue(model, '/spec/databaseRef/name') + function getAliasOptions() { + return ['server', 'client', 'metrics-exporter'] + } - return !dbDetails || !dbName -} + function isNamespaceDisabled() { + const { namespace } = route.query || {} + return !!namespace + } -function setValueFromDbDetails( - { discriminator, getValue, watchDependency, commit }, - path, - commitPath, -) { - watchDependency('discriminator#/dbDetails') + function isDatabaseRefDisabled() { + const { name } = route.params || {} + return !!name + } - const retValue = getValue(discriminator, `/dbDetails${path}`) + function onNamespaceChange() { + commit('wizard/model$delete', '/spec/type') + } - if (commitPath && retValue) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + function onDbChange() { + commit('wizard/model$delete', '/spec/type') + getDbDetails() + } - // computed called when tls fields is not visible - if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined + function setApplyToIfReady() { + return 'IfReady' + } - // 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, - }) + 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' + } } - return retValue || undefined -} + 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, + } -function setResource({ discriminator, getValue, watchDependency, storeGet }, path) { - watchDependency('discriminator#/dbDetails') - const containers = getValue(discriminator, `/dbDetails${path}`) || [] - const kind = getValue(discriminator, '/dbDetails/kind') - const resource = containers.filter((ele) => ele.name === kind.toLowerCase()) - return resource[0]?.resources -} + const match = String(sizeStr).match(/^([0-9]+(?:\.[0-9]*)?)\s*([A-Za-z]*)$/) + if (!match) throw new Error('Invalid size format') -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} + const value = parseFloat(match[1]) + const unit = match[2] -function isNamespaceDisabled({ route }) { - const { namespace } = route.query || {} - return !!namespace -} + if (!(unit in units)) + throw new Error('Unrecognized unit. Available units are K, Ki, M, Mi, G, Gi etc') -function isDatabaseRefDisabled({ route }) { - const { name } = route.params || {} - return !!name -} + return value * units[unit] + } -function onNamespaceChange({ commit }) { - commit('wizard/model$delete', '/spec/type') -} + function fetchAliasOptions() { + return getAliasOptions ? getAliasOptions() : [] + } -function onDbChange({ commit, axios, storeGet, model, getValue, setDiscriminatorValue }) { - commit('wizard/model$delete', '/spec/type') - getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) -} + function validateNewCertificates({ itemCtx }) { + const addedAliases = (model && model.map((item) => item.alias)) || [] -function setApplyToIfReady() { - return 'IfReady' -} + if (addedAliases.includes(itemCtx.alias) && itemCtx.isCreate) { + return { isInvalid: true, message: 'Alias already exists' } + } + return {} + } -function isVerticalScaleTopologyRequired({ watchDependency, getValue, discriminator, commit }) { - watchDependency('discriminator#/topologyKey') - watchDependency('discriminator#/topologyValue') + function disableAlias() { + return !!(model && model.alias) + } - const key = getValue(discriminator, '/topologyKey') - const value = getValue(discriminator, '/topologyValue') - const path = `/spec/verticalScaling/singlestore/topology` + function isVerticalScaleTopologyRequired(type) { + // watchDependency(`discriminator#/topologyKey-${type}`) + // watchDependency(`discriminator#/topologyValue-${type}`) - if (key || value) { - commit('wizard/model$update', { - path: path, - value: { key, value }, - force: true, - }) - return true - } else { - commit('wizard/model$delete', path) - return false + const key = getValue(discriminator, `/topologyKey-${type}`) + const value = getValue(discriminator, `/topologyValue-${type}`) + const path = `/spec/verticalScaling/${type}/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({ model, discriminator, getValue }, initpath, path) { - const volume = getValue(discriminator, `/dbDetails${initpath}`) - const input = getValue(model, path) + function setExporter(type) { + let path = `/dbDetails/spec/monitor/prometheus/exporter/resources/limits/${type}` + const limitVal = getValue(discriminator, path) - try { - const sizeInBytes = parseSize(volume) - const inputSizeInBytes = parseSize(input) + if (!limitVal) { + path = `/dbDetails/spec/monitor/prometheus/exporter/resources/requests/${type}` + const reqVal = getValue(discriminator, path) - if (inputSizeInBytes >= sizeInBytes) return true - else return 'Cannot expand to lower volume!' - } catch (err) { - return err.message || 'Invalid' + if (reqVal) return reqVal + } + return limitVal } -} -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 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, + }) + } -return { - setResource, - fetchJsons, - returnFalse, - getNamespaces, - getDbs, - getDbDetails, - getDbVersions, - ifRequestTypeEqualsTo, - onRequestTypeChange, - getDbTls, - getDbType, - initNamespace, - initDatabaseRef, - isRancherManaged, - showAndInitName, - showAndInitNamespace, - showAndInitDatabaseRef, - showConfigureOpsrequestLabel, - showAndInitOpsRequestType, - - ifDbTypeEqualsTo, - getConfigSecrets, - createSecretUrl, - isEqualToValueFromType, - disableOpsRequest, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - ifReconfigurationTypeEqualsTo, - onReconfigurationTypeChange, - onApplyconfigChange, - hasTlsField, - initIssuerRefApiGroup, - getIssuerRefsName, - initTlsOperation, - onTlsOperationChange, - showIssuerRefAndCertificates, - isIssuerRefRequired, - getRequestTypeFromRoute, - isDbDetailsLoading, - setValueFromDbDetails, - getAliasOptions, - isNamespaceDisabled, - isDatabaseRefDisabled, - onNamespaceChange, - onDbChange, - setApplyToIfReady, - isVerticalScaleTopologyRequired, - getMachines, - setMachine, - onMachineChange, - isMachineCustom, - checkVolume, + return { + 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, + isConfigSelected, + getSelectedConfigSecret, + getSelectedConfigSecretValue, + createSecretUrl, + isEqualToValueFromType, + getNamespacedResourceList, + getResourceList, + resourceNames, + unNamespacedResourceNames, + ifReconfigurationTypeEqualsTo, + onReconfigurationTypeChange, + onApplyconfigChange, + hasTlsField, + initIssuerRefApiGroup, + getIssuerRefsName, + initTlsOperation, + onTlsOperationChange, + showIssuerRefAndCertificates, + isIssuerRefRequired, + getRequestTypeFromRoute, + isDbDetailsLoading, + setValueFromDbDetails, + getAliasOptions, + isNamespaceDisabled, + isDatabaseRefDisabled, + onDbChange, + onNamespaceChange, + setApplyToIfReady, + getMachines, + setMachine, + onMachineChange, + isMachineCustom, + checkVolume, + setResource, + isVerticalScaleTopologyRequired, + fetchConfigSecrets, + getConfigSecretsforAppyConfig, + getSelectedConfigurationData, + getSelectedConfigurationName, + getSelectedConfigurationValueForRemove, + createNewConfigSecret, + decodeError, + isCreateSecret, + isNotCreateSecret, + onCreateSecretChange, + cancelCreateSecret, + setApplyConfig, + onRemoveConfigChange, + onNewConfigSecretChange, + onSelectedSecretChange, + isTlsEnabled, + } } diff --git a/charts/opskubedbcom-solropsrequest-editor/ui/create-ui.yaml b/charts/opskubedbcom-solropsrequest-editor/ui/create-ui.yaml index 7b2e4cd97e..61b2f3003b 100644 --- a/charts/opskubedbcom-solropsrequest-editor/ui/create-ui.yaml +++ b/charts/opskubedbcom-solropsrequest-editor/ui/create-ui.yaml @@ -1,631 +1,1427 @@ -steps: -- form: - discriminator: - dbDetails: - type: object +type: multi-step-form +step: + - type: single-step-form + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - schema: - $ref: discriminator#/properties/dbDetails - type: input - - if: showAndInitName - label: - text: labels.op_req_name - required: true - schema: - $ref: schema#/properties/metadata/properties/name - type: input - - computed: initNamespace - disabled: isNamespaceDisabled - fetch: getNamespaces - hasGroup: isRancherManaged - if: showAndInitNamespace - label: - text: labels.namespace - onChange: onNamespaceChange - required: true - schema: - $ref: schema#/properties/metadata/properties/namespace - type: select - - computed: initDatabaseRef - disabled: isDatabaseRefDisabled - fetch: getDbs - if: showAndInitDatabaseRef - label: - text: labels.databaseRef - onChange: onDbChange - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/databaseRef/properties/name - type: select - - if: showConfigureOpsrequestLabel - label: - text: labels.config_ops_request - type: label-element - - computed: getRequestTypeFromRoute - disabled: isDbDetailsLoading - hasDescription: true - if: showAndInitOpsRequestType - individualItemDisabilityCheck: disableOpsRequest - label: - text: labels.ops_request_type - onChange: onRequestTypeChange - options: - - description: options.UpdateVersion.description - text: options.UpdateVersion.text - value: UpdateVersion - - description: options.HorizontalScaling.description - text: options.HorizontalScaling.text - value: HorizontalScaling - - description: options.VerticalScaling.description - text: options.VerticalScaling.text - value: VerticalScaling - - description: options.VolumeExpansion.description - text: options.VolumeExpansion.text - value: VolumeExpansion - - description: options.Restart.description - text: options.Restart.text - value: Restart - - description: options.Reconfigure.description - text: options.Reconfigure.text - value: Reconfigure - - description: options.ReconfigureTLS.description - text: options.ReconfigureTLS.text - value: ReconfigureTLS - schema: - $ref: schema#/properties/spec/properties/type - type: radio - - elements: - - computed: setValueFromDbDetails|/spec/version - fetch: getDbVersions - label: - text: labels.targetVersion - schema: - $ref: schema#/properties/spec/properties/updateVersion/properties/targetVersion - type: select - if: ifRequestTypeEqualsTo|UpdateVersion - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/topology/coordinator/replicas - if: ifDbTypeEqualsTo|Topology|VerticalScaling - label: - text: coordinator - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/coordinator - type: input - - computed: setValueFromDbDetails|/spec/topology/data/replicas - if: ifDbTypeEqualsTo|Topology|VerticalScaling - label: - text: data - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/data - type: input - - computed: setValueFromDbDetails|/spec/topology/overseer/replicas - if: ifDbTypeEqualsTo|Topology|VerticalScaling - label: - text: overseer - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/overseer - type: input - - computed: setValueFromDbDetails|/spec/replicas - if: ifDbTypeEqualsTo|Combined|VerticalScaling - label: - text: node - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/node - type: input - if: ifRequestTypeEqualsTo|HorizontalScaling - label: - text: Horizontal Scaling Form - type: single-step-form - - elements: - - discriminator: - machine-coordinator: - default: "" - type: string +# common + - type: input + label: op_req_name + if: + type: function + name: showAndInitName + validation: + type: required + schema: schema/properties/metadata/properties/name + - type: select + label: Namespace + if: + type: function + name: showAndInitNamespace + init: + type: func + value: initNamespace + disable: isNamespaceDisabled + loader: getNamespaces + validation: + type: required + hasGroup: isRancherManaged + schema: schema/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/metadata/properties/namespace + - type: select + label: Database Ref + if: + type: function + name: showAndInitDatabaseRef + loader: + name: getDbs + watchPaths: + - schema/properties/metadata/properties/namespace + init: + type: func + value: initDatabaseRef + validation: + type: required + disable: isDatabaseRefDisabled + refresh: true + watcher: + paths: + - schema/properties/spec/properties/databaseRef/properties/name + func: onDbChange + schema: schema/properties/spec/properties/databaseRef/properties/name + - type: label-element + label: config_ops_request + if: + type: function + name: showConfigureOpsrequestLabel + - type: radio + label: Type of Ops Request + if: + type: function + name: showAndInitOpsRequestType + 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 + init: + type: func + value: getRequestTypeFromRoute + disable: isDbDetailsLoading + watcher: + func: onRequestTypeChange + paths: + - schema/properties/spec/properties/type + isHorizontal: true + schema: schema/properties/spec/properties/type +# UpdateVersion + - type: block-layout + showLabels: true + label: Version + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|UpdateVersion elements: - - computed: setMachine|coordinator - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|coordinator|/spec/topology/coordinator/podTemplate/spec/containers - schema: - $ref: discriminator#/machine-coordinator - type: select - - if: isMachineCustom|/machine-coordinator - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/coordinator/properties/resources - type: resource-input-form - - label: - text: Node Selection Policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/coordinator/properties/nodeSelectionPolicy - type: select - - elements: - - label: - text: key - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/coordinator/properties/topology/properties/key - type: input - - label: - text: value - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/coordinator/properties/topology/properties/value - type: input - label: - text: Topology - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/coordinator/properties/topology - show_label: true - type: single-step-form - if: ifDbTypeEqualsTo|Topology|VerticalScaling - label: - text: Coordinator - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/coordinator - show_label: true - type: single-step-form - - discriminator: - machine-data: - default: "" - type: string + - type: select-compare + label: Target Version + subtitle: Select the desired Solr version to which you want to update your database. + init: + type: func + value: setValueFromDbDetails|/spec/version + loader: getDbVersions + schema: schema/properties/spec/properties/updateVersion/properties/targetVersion + - type: info + label: '' + loader: + name: getVersionInfo + watchPaths: + - temp/properties/filteredVersion + if: + type: function + name: isVersionEmpty +# Horizontal Scale + - type: block-layout + label: Horizontal Scaling Form + showLabels: true + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|HorizontalScaling elements: - - computed: setMachine|data - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|data|/spec/topology/data/podTemplate/spec/containers - schema: - $ref: discriminator#/machine-data - type: select - - if: isMachineCustom|/machine-data - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/data/properties/resources - type: resource-input-form - - label: - text: Node Selection Policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/data/properties/nodeSelectionPolicy - type: select - - elements: - - label: - text: key - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/data/properties/topology/properties/key - type: input - - label: - text: value - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/data/properties/topology/properties/value - type: input - label: - text: Topology - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/data/properties/topology - show_label: true - type: single-step-form - if: ifDbTypeEqualsTo|Topology|VerticalScaling - label: - text: Data - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/data - show_label: true - type: single-step-form - - discriminator: - machine-overseer: - default: "" - type: string + - type: horizontal-layout + elements: + - type: input-compare + label: Replicas + header: Node + subtitle: Define the total number of replicas for the database. Increasing replicas improves fault tolerance and load distribution , while reducing replicas conserves resources + if: + type: function + name: ifDbTypeEqualsTo|Combined|horizontalScaling + init: + type: func + value: setValueFromDbDetails|/spec/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/node + - type: info + 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. + if: + type: function + name: ifDbTypeEqualsTo|Combined|horizontalScaling + - type: block-layout + label: 'Topology horizontal scaling' + if: + name: ifDbTypeEqualsTo|Topology|horizontalScaling + type: function + elements: + - type: block-layout + label: Coordinator horizontal Scaling + elements: + - type: label-element + label: Coordinator + - type: horizontal-layout + elements: + - type: input-compare + label: Replicas + subtitle: Define the total number of replicas for the database. Increasing replicas improves fault tolerance and load distribution , while reducing replicas conserves resources + schema: schema/properties/spec/properties/horizontalScaling/properties/coordinator + init: + type: func + value: setValueFromDbDetails|/spec/topology/coordinator/replicas + - type: info + 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: block-layout + label: Data Horizontal Scaling + elements: + - type: label-element + label: Data + - type: horizontal-layout + elements: + - type: input-compare + label: Replicas + subtitle: Define the total number of replicas for the database. Increasing replicas improves fault tolerance and load distribution , while reducing replicas conserves resources + init: + type: func + value: setValueFromDbDetails|/spec/topology/data/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/data + - type: info + 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: block-layout + label: Overseer horizontal Scaling + elements: + - type: label-element + label: Overseer + - type: horizontal-layout + elements: + - type: input-compare + label: Replicas + subtitle: Define the total number of replicas for the database. Increasing replicas improves fault tolerance and load distribution , while reducing replicas conserves resources + init: + type: func + value: setValueFromDbDetails|/spec/topology/overseer/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/overseer + - type: info + 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. +# vertical Scale + - type: block-layout + if: + type: function + name: ifRequestTypeEqualsTo|VerticalScaling elements: - - computed: setMachine|overseer - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|overseer|/spec/topology/overseer/podTemplate/spec/containers - schema: - $ref: discriminator#/machine-overseer - type: select - - if: isMachineCustom|/machine-overseer - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/overseer/properties/resources - type: resource-input-form - - label: - text: Node Selection Policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/overseer/properties/nodeSelectionPolicy - type: select - - elements: - - label: - text: key - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/overseer/properties/topology/properties/key - type: input - - label: - text: value - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/overseer/properties/topology/properties/value - type: input - label: - text: Topology - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/overseer/properties/topology - show_label: true - type: single-step-form - if: ifDbTypeEqualsTo|Topology|VerticalScaling - label: - text: Overseer - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/overseer - show_label: true - type: single-step-form - - discriminator: - machine-node: - default: "" - type: string + - type: block-layout + label: Combined Vertical Scaling + if: + type: function + name: ifDbTypeEqualsTo|Combined|verticalScaling + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines|node + init: + type: func + value: setMachine|node + watcher: + func: onMachineChange|node|/spec/podTemplate/spec/containers + paths: + - temp/properties/machine-node + schema: temp/properties/machine-node + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/node/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|node + schema: temp/topologyKey-node + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|node + schema: temp/topologyValue-node + - type: block-layout + if: + type: function + name: ifDbTypeEqualsTo|Topology|verticalScaling + label: Topology Vertical Scaling + showLabels: false + elements: + - type: block-layout + label: Coordinator Vertical Scaling + showLabels: true + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines|coordinator + init: + type: func + value: setMachine|coordinator + watcher: + func: onMachineChange|coordinator|/spec/topology/coordinator/podTemplate/spec/containers + paths: + - temp/properties/machine-coordinator + schema: temp/properties/machine-coordinator + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/coordinator/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|coordinator + schema: temp/topologyKey-coordinator + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|coordinator + schema: temp/topologyValue-coordinator + - type: block-layout + label: Data Vertical Scaling + showLabels: true + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines|data + init: + type: func + value: setMachine|data + watcher: + func: onMachineChange|data|/spec/topology/data/podTemplate/spec/containers + paths: + - temp/properties/machine-data + schema: temp/properties/machine-data + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/data/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|data + schema: temp/topologyKey-data + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|data + schema: temp/topologyValue-data + - type: block-layout + label: Overseer Vertical Scaling + showLabels: true + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines|overseer + init: + type: func + value: setMachine|overseer + watcher: + func: onMachineChange|overseer|/spec/topology/overseer/podTemplate/spec/containers + paths: + - temp/properties/machine-overseer + schema: temp/properties/machine-overseer + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/overseer/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired|overseer + schema: temp/topologyKey-overseer + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired|overseer + schema: temp/topologyValue-overseer + - type: block-layout + label: Exporter + showLabels: true + hideBlock: true + elements: + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setExporter|cpu + type: input + 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 + watcher: + func: onExporterResourceChange|memory + paths: + - schema/properties/spec/properties/verticalScaling/properties/exporter/properties/resources/properties/limits/properties/memory +# Volume Expansion + + - type: block-layout + label: Volume Expansion Form + if: + type: function + name: ifRequestTypeEqualsTo|VolumeExpansion elements: - - computed: setMachine|node - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|node|/spec/podTemplate/spec/containers - schema: - $ref: discriminator#/machine-node - type: select - - if: isMachineCustom|/machine-node - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/resources - type: resource-input-form - - label: - text: Node Selection Policy - options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/nodeSelectionPolicy - type: select - - elements: - - label: - text: key - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/topology/properties/key - type: input - - label: - text: value - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/topology/properties/value - type: input - label: - text: Topology - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/topology - show_label: true - type: single-step-form - if: ifDbTypeEqualsTo|Combined|VerticalScaling - label: - text: Node - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|VerticalScaling - type: single-step-form - - elements: - - elements: - - computed: setValueFromDbDetails|/spec/topology/coordinator/storage/resources/requests/storage - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/coordinator - type: input - validationRuleObject: - func: checkVolume|/spec/topology/coordinator/storage/resources/requests/storage|/spec/volumeExpansion/coordinator - if: ifDbTypeEqualsTo|Topology|VolumeExpansion - label: - text: Coordinator - show_label: true - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/topology/data/storage/resources/requests/storage - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/data - type: input - validationRuleObject: - func: checkVolume|/spec/topology/data/storage/resources/requests/storage|/spec/volumeExpansion/data - if: ifDbTypeEqualsTo|Topology|VolumeExpansion - label: - text: Data - show_label: true - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/topology/overseer/storage/resources/requests/storage - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/overseer - type: input - validationRuleObject: - func: checkVolume|/spec/topology/overseer/storage/resources/requests/storage|/spec/volumeExpansion/overseer - if: ifDbTypeEqualsTo|Topology|VolumeExpansion - label: - text: Overseer - show_label: true - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/storage/resources/requests/storage - label: - text: labels.storage.size - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/node - type: input - validationRuleObject: - func: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/node - if: ifDbTypeEqualsTo|Combined|VolumeExpansion - label: - text: Node - show_label: true - type: single-step-form - - label: - text: Mode - options: - - text: Offline - value: Offline - - text: Online - value: Online - required: true - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/mode - type: select - if: ifRequestTypeEqualsTo|VolumeExpansion - label: - text: Volume Expansion Form - type: single-step-form - - elements: - - discriminator: - reconfigurationType: - type: string + - type: horizontal-layout + elements: + - type: block-layout + elements: + - type: label-element + 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: select + label: Mode + options: + - text: Offline + value: Offline + - text: Online + value: Online + validation: + type: required + schema: schema/properties/spec/properties/volumeExpansion/properties/mode + - type: block-layout + label: Combined volume expansion + showLabels: true + fixedBlock: true + if: + type: function + name: ifDbTypeEqualsTo|Combined|volumeExpansion + elements: + - type: horizontal-layout + elements: + - type: input-compare + header: Combined + subtitle: How much extra storage does your database need? Specify the size(e.g. 2Gi for 2 gigabytes) so we can allocate it correctly + label: Node + init: + type: func + value: setValueFromDbDetails|/spec/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/node + schema: schema/properties/spec/properties/volumeExpansion/properties/node + - type: block-layout + label: Topology volume expansion + showLabels: true + fixedBlock: true + if: + type: function + name: ifDbTypeEqualsTo|Topology|volumeExpansion + elements: + - type: horizontal-layout + elements: + - type: input-compare + header: Coordinator + label: Coordinator + subtitle: How much extra storage does your database need? Specify the size(e.g., 2Gi for 2 gigabytes) so we can allocate it correctly + init: + type: func + value: setValueFromDbDetails|/spec/topology/coordinator/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/topology/coordinator/storage/resources/requests/storage|/spec/volumeExpansion/coordinator + schema: schema/properties/spec/properties/volumeExpansion/properties/coordinator + - type: info + 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: horizontal-layout + elements: + - type: input-compare + header: Data + label: Data + subtitle: How much extra storage does your database need? Specify the size(e.g., 2Gi for 2 gigabytes) so we can allocate it correctly + init: + type: func + value: setValueFromDbDetails|/spec/topology/data/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/topology/data/storage/resources/requests/storage|/spec/volumeExpansion/data + schema: schema/properties/spec/properties/volumeExpansion/properties/data + - type: info + 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: horizontal-layout + elements: + - type: input-compare + header: Overseer + label: Overseer + subtitle: How much extra storage does your database need? Specify the size(e.g., 2Gi for 2 gigabytes) so we can allocate it correctly + init: + type: func + value: setValueFromDbDetails|/spec/topology/overseer/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/topology/overseer/storage/resources/requests/storage|/spec/volumeExpansion/overseer + schema: schema/properties/spec/properties/volumeExpansion/properties/overseer + - type: info + 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. +# Reconfigure + - type: block-layout + label: Reconfigure Form + if: + name: ifRequestTypeEqualsTo|Reconfigure + type: function + loader: + name: fetchConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace elements: - - label: - text: labels.reconfigurationType - onChange: onReconfigurationTypeChange - options: - - text: Select New Config Secret - value: selectNewConfigSecret - - text: Apply Config - value: applyConfig - - text: Remove - value: remove - required: true - schema: - $ref: discriminator#/properties/reconfigurationType - type: radio - - elements: - - add_new_button: - label: labels.createConfig - target: _blank - url: - function: createSecretUrl - computed: setValueFromDbDetails|/spec/configSecret/name - fetch: getConfigSecrets - label: - text: labels.configSecret - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret/properties/name - type: select - if: ifReconfigurationTypeEqualsTo|selectNewConfigSecret - label: - text: Configuration config secret - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret - type: single-step-form - - addFormLabel: labels.applyConfig.label - element: - discriminator: - configArray: - emitAs: applyConfig - type: array + - type: label-element + label: '' + subtitle: Select a new configuration secret, apply a custom configuration, or remove an existing setup to update your database settings + - type: block-layout + label: Combined + if: + name: ifDbTypeEqualsTo|Combined|configuration + type: function elements: - - label: - text: labels.applyConfig.key - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/key - type: input - - label: - text: labels.applyConfig.value - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/value - type: editor - type: single-step-form - if: ifReconfigurationTypeEqualsTo|applyConfig - label: - text: labels.applyConfig.label - onChange: onApplyconfigChange - required: true - schema: - $ref: discriminator#/properties/applyConfig - tableContents: - - inTableColumn: true - label: - text: labels.applyConfig.key - path: key - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.applyConfig.value - path: value - type: value - typeOfValue: code - type: single-step-form-array - - if: returnFalse - label: - text: labels.removeCustomConfig - schema: - $ref: schema#/properties/spec/properties/configuration/properties/removeCustomConfig - type: switch - label: - text: labels.configuration - schema: - $ref: schema#/properties/spec/properties/configuration - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|Reconfigure - label: - text: Reconfigure Form - type: single-step-form - - discriminator: - tlsOperation: - default: update - type: string - elements: - - computed: initTlsOperation - if: hasTlsField - label: - text: labels.tlsOperation - onChange: onTlsOperationChange - options: - - text: Update - value: update - - text: Rotate - value: rotate - - text: Remove - value: remove - schema: - $ref: discriminator#/properties/tlsOperation - type: radio - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/remove - type: switch - - if: returnFalse - schema: - $ref: schema#/properties/spec/properties/tls/properties/rotateCertificates - type: switch - - elements: - - computed: initIssuerRefApiGroup - disabled: true - label: - text: labels.api_group - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup - type: input - - computed: setValueFromDbDetails|/spec/tls/issuerRef/kind - label: - text: labels.kind - options: - - text: Issuer - value: Issuer - - text: ClusterIssuer - value: ClusterIssuer - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/kind - sortable: true - type: select - - allowUserDefinedOption: true - computed: setValueFromDbDetails|/spec/tls/issuerRef/name - fetch: getIssuerRefsName - label: - text: labels.name - required: isIssuerRefRequired - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef/properties/name - sortable: true - type: select - if: showIssuerRefAndCertificates - schema: - $ref: schema#/properties/spec/properties/tls/properties/issuerRef - type: single-step-form - - alias: reusable_certificates - chart: - name: uibytebuildersdev-component-certificates - version: v0.29.0 - computed: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates - functionCallbacks: - getAliasOptions: - $ref: functions#/getAliasOptions - if: showIssuerRefAndCertificates - moduleResolver: fetchJsons - schema: - $ref: schema#/properties/spec/properties/tls/properties/certificates - type: reusable-element - if: ifRequestTypeEqualsTo|ReconfigureTLS - label: - text: labels.tls - schema: - $ref: schema#/properties/spec/properties/tls - type: single-step-form - - label: - text: labels.timeout - options: - - text: 5 minutes - value: 5m - - text: 10 minutes - value: 10m - - text: 30 minutes - value: 30m - - text: 1 hour - value: 1h - - text: 2 hours - value: 2h - - text: 5 hours - value: 5h - - text: 10 hours - value: 10h - schema: - $ref: schema#/properties/spec/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: labels.apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/spec/properties/apply - type: radio - type: single-step-form - id: basic - title: steps.0.label -type: multi-step-form + - type: tab-layout + label: New Config Secret + schema: temp/properties/reconfigurationType + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + elements: + - type: block-layout + label: Config Secret + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret + type: function + elements: + - type: label-element + label: Config Secret + subtitle: Select a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: schema/properties/spec/properties/configuration/properties/node/properties/configSecret/properties/name + refresh: true + label: Config Secret + loader: + name: getConfigSecrets|node + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/node/properties/createSecret/properties/status + init: + type: func + value: setValueFromDbDetails|/spec/configSecret/name + watcher: + func: onCreateSecretChange|node + paths: + - temp/properties/node/properties/createSecret/properties/status + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|create|node + watchPaths: + - schema/properties/spec/properties/configuration/properties/node/properties/configSecret/properties/name + - type: block-layout + label: Create a New Config Secret + showLabels: true + if: + type: function + name: isCreateSecret|node + hasButton: + text: Save + hasCancel: cancelCreateSecret|node + action: createNewConfigSecret|node + elements: + - type: input + label: Secret Name + schema: temp/properties/node/properties/createSecret/properties/name + validation: + type: required + - type: array-object-form + label: String Data + schema: temp/properties/node/properties/createSecret/properties/data + buttonClass: is-light is-outlined + validation: + type: required + elements: + - type: select + label: Key + schema: key + loader: + name: onSelectedSecretChange|node + watchPaths: + - temp/properties/node/properties/createSecret/properties/data + validation: + type: required + - type: textarea + label: Value + schema: value + - type: multi-file-editor + editorHeight: 500px + readonly: true + if: + type: function + name: isNotCreateSecret|node + loader: + name: onNewConfigSecretChange|node + watchPaths: + - schema/properties/spec/properties/configuration/properties/node/properties/configSecret/properties/name + schema: temp/properties/node/newConfigSecret + - type: block-layout + label: ApplyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig + type: function + elements: + - type: label-element + 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). + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/node/selectedConfiguration + refresh: true + label: Configuration + loader: getConfigSecretsforAppyConfig + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|apply|node + watchPaths: + - temp/properties/node/selectedConfiguration + - type: multi-file-editor + editorHeight: 500px + schema: temp/properties/node/applyConfig + loader: + name: setApplyConfig|node + watchPaths: + - temp/properties/node/selectedConfiguration + watcher: + func: onApplyconfigChange|node + paths: + - temp/properties/node/applyConfig + - type: block-layout + label: Remove + if: + name: ifReconfigurationTypeEqualsTo|remove + type: function + elements: + - type: label-element + label: Remove + subtitle: Selected a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/node/selectedConfigurationRemove + refresh: true + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|remove|node + watchPaths: + - temp/properties/node/selectedConfigurationRemove + - type: multi-file-editor + editorHeight: 500px + readonly: true + init: + type: func + value: onRemoveConfigChange|node + watcher: + func: onRemoveConfigChange|node + paths: + - temp/properties/node/selectedConfigurationRemove + schema: temp/properties/node/removeConfig + - type: block-layout + elements: + - type: block-layout + label: Coordinator + showLabels: true + elements: + - type: tab-layout + label: New Config Secret + schema: temp/properties/reconfigurationType-coordinator + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + elements: + - type: block-layout + label: Config Secret + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret|coordinator|true + type: function + elements: + - type: label-element + label: Config Secret + subtitle: Select a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: schema/properties/spec/properties/configuration/properties/coordinator/properties/configSecret/properties/name + refresh: true + label: Config Secret + loader: + name: getConfigSecrets|coordinator + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/coordinator/properties/createSecret/properties/status + init: + type: func + value: setValueFromDbDetails|/spec/topology/coordinator/configSecret/name + watcher: + func: onCreateSecretChange|coordinator + paths: + - temp/properties/coordinator/properties/createSecret/properties/status + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|create|coordinator + watchPaths: + - schema/properties/spec/properties/configuration/properties/coordinator/properties/configSecret/properties/name + - type: block-layout + label: Create a New Config Secret + showLabels: true + if: + type: function + name: isCreateSecret|coordinator + hasButton: + text: Save + hasCancel: cancelCreateSecret|coordinator + action: createNewConfigSecret|coordinator + elements: + - type: input + label: Secret Name + schema: temp/properties/coordinator/properties/createSecret/properties/name + validation: + type: required + - type: array-object-form + label: String Data + schema: temp/properties/coordinator/properties/createSecret/properties/data + buttonClass: is-light is-outlined + validation: + type: required + elements: + - type: select + label: Key + schema: key + loader: + name: onSelectedSecretChange|coordinator + watchPaths: + - temp/properties/coordinator/properties/createSecret/properties/data + validation: + type: required + - type: textarea + label: Value + schema: value + - type: multi-file-editor + editorHeight: 500px + readonly: true + if: + type: function + name: isNotCreateSecret|coordinator + loader: + name: onNewConfigSecretChange|coordinator + watchPaths: + - schema/properties/spec/properties/configuration/properties/coordinator/properties/configSecret/properties/name + schema: temp/properties/coordinator/newConfigSecret + - type: block-layout + label: ApplyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig|coordinator|true + type: function + elements: + - type: label-element + 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). + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/coordinator/selectedConfiguration + refresh: true + label: Configuration + loader: getConfigSecretsforAppyConfig + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|apply|coordinator + watchPaths: + - temp/properties/coordinator/selectedConfiguration + - type: multi-file-editor + editorHeight: 500px + schema: temp/properties/coordinator/applyConfig + loader: + name: setApplyConfig|coordinator + watchPaths: + - temp/properties/coordinator/selectedConfiguration + watcher: + func: onApplyconfigChange|coordinator + paths: + - temp/properties/coordinator/applyConfig + - type: block-layout + label: Remove + if: + name: ifReconfigurationTypeEqualsTo|remove|coordinator|true + type: function + elements: + - type: label-element + label: Remove + subtitle: Selected a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/coordinator/selectedConfigurationRemove + refresh: true + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|remove|coordinator + watchPaths: + - temp/properties/coordinator/selectedConfigurationRemove + - type: multi-file-editor + editorHeight: 500px + readonly: true + init: + type: func + value: onRemoveConfigChange|coordinator + watcher: + func: onRemoveConfigChange|coordinator + paths: + - temp/properties/coordinator/selectedConfigurationRemove + schema: temp/properties/coordinator/removeConfig + - type: block-layout + label: Data + showLabels: true + elements: + - type: tab-layout + label: New Config Secret + schema: temp/properties/reconfigurationType-data + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + elements: + - type: block-layout + label: Config Secret + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret|data|true + type: function + elements: + - type: label-element + label: Config Secret + subtitle: Select a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: schema/properties/spec/properties/configuration/properties/data/properties/configSecret/properties/name + refresh: true + label: Config Secret + loader: + name: getConfigSecrets|data + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/data/properties/createSecret/properties/status + init: + type: func + value: setValueFromDbDetails|/spec/topology/data/configSecret/name + watcher: + func: onCreateSecretChange|data + paths: + - temp/properties/data/properties/createSecret/properties/status + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|create|data + watchPaths: + - schema/properties/spec/properties/configuration/properties/data/properties/configSecret/properties/name + - type: block-layout + label: Create a New Config Secret + showLabels: true + if: + type: function + name: isCreateSecret|data + hasButton: + text: Save + hasCancel: cancelCreateSecret|data + action: createNewConfigSecret|data + elements: + - type: input + label: Secret Name + schema: temp/properties/data/properties/createSecret/properties/name + validation: + type: required + - type: array-object-form + label: String Data + schema: temp/properties/data/properties/createSecret/properties/data + buttonClass: is-light is-outlined + validation: + type: required + elements: + - type: select + label: Key + schema: key + loader: + name: onSelectedSecretChange|data + watchPaths: + - temp/properties/data/properties/createSecret/properties/data + validation: + type: required + - type: textarea + label: Value + schema: value + - type: multi-file-editor + editorHeight: 500px + readonly: true + if: + type: function + name: isNotCreateSecret|data + loader: + name: onNewConfigSecretChange|data + watchPaths: + - schema/properties/spec/properties/configuration/properties/data/properties/configSecret/properties/name + schema: temp/properties/data/newConfigSecret + - type: block-layout + label: ApplyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig|data|true + type: function + elements: + - type: label-element + 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). + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/data/selectedConfiguration + refresh: true + label: Configuration + loader: getConfigSecretsforAppyConfig + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|apply|data + watchPaths: + - temp/properties/data/selectedConfiguration + - type: multi-file-editor + editorHeight: 500px + schema: temp/properties/data/applyConfig + loader: + name: setApplyConfig|data + watchPaths: + - temp/properties/data/selectedConfiguration + watcher: + func: onApplyconfigChange|data + paths: + - temp/properties/data/applyConfig + - type: block-layout + label: Remove + if: + name: ifReconfigurationTypeEqualsTo|remove|data|true + type: function + elements: + - type: label-element + label: Remove + subtitle: Selected a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/data/selectedConfigurationRemove + refresh: true + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|remove|data + watchPaths: + - temp/properties/data/selectedConfigurationRemove + - type: multi-file-editor + editorHeight: 500px + readonly: true + init: + type: func + value: onRemoveConfigChange|data + watcher: + func: onRemoveConfigChange|data + paths: + - temp/properties/data/selectedConfigurationRemove + schema: temp/properties/data/removeConfig + - type: block-layout + label: Overseer + showLabels: true + elements: + - type: tab-layout + label: New Config Secret + schema: temp/properties/reconfigurationType-overseer + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + elements: + - type: block-layout + label: Config Secret + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret|overseer|true + type: function + elements: + - type: label-element + label: Config Secret + subtitle: Select a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: schema/properties/spec/properties/configuration/properties/overseer/properties/configSecret/properties/name + refresh: true + label: Config Secret + loader: + name: getConfigSecrets|overseer + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/overseer/properties/createSecret/properties/status + init: + type: func + value: setValueFromDbDetails|/spec/topology/overseer/configSecret/name + watcher: + func: onCreateSecretChange|overseer + paths: + - temp/properties/overseer/properties/createSecret/properties/status + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|create|overseer + watchPaths: + - schema/properties/spec/properties/configuration/properties/overseer/properties/configSecret/properties/name + - type: block-layout + label: Create a New Config Secret + showLabels: true + if: + type: function + name: isCreateSecret|overseer + hasButton: + text: Save + hasCancel: cancelCreateSecret|overseer + action: createNewConfigSecret|overseer + elements: + - type: input + label: Secret Name + schema: temp/properties/overseer/properties/createSecret/properties/name + validation: + type: required + - type: array-object-form + label: String Data + schema: temp/properties/overseer/properties/createSecret/properties/data + buttonClass: is-light is-outlined + validation: + type: required + elements: + - type: select + label: Key + schema: key + loader: + name: onSelectedSecretChange|overseer + watchPaths: + - temp/properties/overseer/properties/createSecret/properties/data + validation: + type: required + - type: textarea + label: Value + schema: value + - type: multi-file-editor + editorHeight: 500px + readonly: true + if: + type: function + name: isNotCreateSecret|overseer + loader: + name: onNewConfigSecretChange|overseer + watchPaths: + - schema/properties/spec/properties/configuration/properties/overseer/properties/configSecret/properties/name + schema: temp/properties/overseer/newConfigSecret + - type: block-layout + label: ApplyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig|overseer|true + type: function + elements: + - type: label-element + 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). + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/overseer/selectedConfiguration + refresh: true + label: Configuration + loader: getConfigSecretsforAppyConfig + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|apply|overseer + watchPaths: + - temp/properties/overseer/selectedConfiguration + - type: multi-file-editor + editorHeight: 500px + schema: temp/properties/overseer/applyConfig + loader: + name: setApplyConfig|overseer + watchPaths: + - temp/properties/overseer/selectedConfiguration + watcher: + func: onApplyconfigChange|overseer + paths: + - temp/properties/overseer/applyConfig + - type: block-layout + label: Remove + if: + name: ifReconfigurationTypeEqualsTo|remove|overseer|true + type: function + elements: + - type: label-element + label: Remove + subtitle: Selected a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/overseer/selectedConfigurationRemove + refresh: true + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|remove|overseer + watchPaths: + - temp/properties/overseer/selectedConfigurationRemove + - type: multi-file-editor + editorHeight: 500px + readonly: true + init: + type: func + value: onRemoveConfigChange|overseer + watcher: + func: onRemoveConfigChange|overseer + paths: + - temp/properties/overseer/selectedConfigurationRemove + schema: temp/properties/overseer/removeConfig + label: Topology Reconfigure form + if: + name: ifDbTypeEqualsTo|Topology|configuration + type: function +# Reconfigure TLS + - type: block-layout + label: TLS + if: + name: ifRequestTypeEqualsTo|ReconfigureTLS + type: function + elements: + - type: radio + label: TLS Operation + schema: temp/properties/tlsOperation + if: + name: hasTlsField + type: function + options: + - text: Update + value: update + - text: Rotate + value: rotate + - text: Remove + value: remove + init: + type: func + value: initTlsOperation + watcher: + func: onTlsOperationChange + paths: + - temp/properties/tlsOperation + - type: switch + label: Remove TLS + fullwidth: true + if: + name: isTlsEnabled + type: function + schema: schema/properties/spec/properties/tls/properties/remove + - type: switch + label: Rotate Certificates + fullwidth: true + schema: schema/properties/spec/properties/tls/properties/rotateCertificates + if: + name: isTlsEnabled + type: function + - type: block-layout + label: Issuer Reference + showLabels: true + if: + name: showIssuerRefAndCertificates + type: function + elements: + - type: input + label: API Group + init: + type: func + value: initIssuerRefApiGroup + watcher: + func: initIssuerRefApiGroup + paths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + disable: true + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/apiGroup + - type: select + label: Kind + options: + - text: Issuer + value: Issuer + - text: ClusterIssuer + value: ClusterIssuer + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/kind + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - type: select + label: Name + loader: + name: getIssuerRefsName + watchPaths: + - schema/properties/spec/properties/tls/properties/issuerRef/properties/kind + - schema/properties/metadata/properties/namespace + init: + type: func + value: setValueFromDbDetails|/spec/tls/issuerRef/name + validation: + type: custom + name: isIssuerRefRequired + schema: schema/properties/spec/properties/tls/properties/issuerRef/properties/name + - type: block-layout + label: Certificates + showLabels: false + if: + name: showIssuerRefAndCertificates + type: function + loader: setValueFromDbDetails|/spec/tls/certificates|/spec/tls/certificates + elements: + - type: array-object-form + label: Certificates + buttonClass: is-light is-outlined + schema: schema/properties/spec/properties/tls/properties/certificates + elements: + - type: select + label: Alias + loader: fetchAliasOptions + disable: disableAlias + schema: alias + validation: + type: required + - type: input + label: Secret Name + schema: secretName + - type: input + label: Duration + schema: duration + - type: input + label: Renew Before + schema: renewBefore + - type: array-item-form + label: Organizations + buttonClass: is-light is-outlined + schema: subject/properties/organizations + element: + type: input + label: Organization + - type: array-item-form + label: Countries + buttonClass: is-light is-outlined + schema: subject/properties/countries + element: + type: input + label: Country + - type: array-item-form + label: Organizational Units + buttonClass: is-light is-outlined + schema: subject/properties/organizationalUnits + element: + type: input + label: Organizational Unit + - type: array-item-form + label: Provinces + buttonClass: is-light is-outlined + schema: subject/properties/provinces + element: + type: input + label: Province + - type: array-item-form + label: DNS Names + buttonClass: is-light is-outlined + schema: dnsNames + element: + type: input + label: DNS Name + - type: array-item-form + label: IP Addresses + buttonClass: is-light is-outlined + schema: ipAddresses + element: + type: input + label: IP Address +# common + - type: block-layout + label: OpsRequest Options + showLabels: true + elements: + - type: time-picker + label: Timeout + schema: 'schema/properties/spec/properties/timeout' + subtitle: Specify the maximum time allowed for the scaling operation to complete. Use formats like 30sec, 1min(1 minute) or 2h(2 hours). + - type: radio + label: Apply + schema: 'schema/properties/spec/properties/apply' + init: + type: func + value: setApplyToIfReady + options: + - text: IfReady (OpsRequest will be applied if database is ready) + value: IfReady + - text: Always (OpsRequest will always be applied) + value: Always diff --git a/charts/opskubedbcom-solropsrequest-editor/ui/functions.js b/charts/opskubedbcom-solropsrequest-editor/ui/functions.js index 952b82d198..edcd1dd6b3 100644 --- a/charts/opskubedbcom-solropsrequest-editor/ui/functions.js +++ b/charts/opskubedbcom-solropsrequest-editor/ui/functions.js @@ -1,3 +1,4 @@ +const { axios, useOperator, store, useToast } = window.vueHelpers || {} const machines = { 'db.t.micro': { resources: { @@ -304,181 +305,235 @@ const machineList = [ 'db.r.24xlarge', ] -async function fetchJsons({ axios, itemCtx }) { - let ui = {} - let language = {} - let functions = {} - const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart +let machinesFromPreset = [] +const configSecretKeys = ['solr.xml'] - 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) - } +export const useFunc = (model) => { + const route = store.state?.route + const toast = useToast() - return { - ui: ui.data || {}, - language: language.data || {}, - functions, - } -} - -function returnFalse() { - return false -} + const { getValue, storeGet, discriminator, setDiscriminatorValue, commit } = useOperator( + model, + store.state, + ) -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + showAndInitOpsRequestType() -async function getNamespaces({ axios, storeGet }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + // for config secret + let secretArray = [] - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + async function fetchJsons({ axios, itemCtx }) { + let ui = {} + let language = {} + let functions = {} + const { name, sourceRef, version, packageviewUrlPrefix } = itemCtx.chart - const resources = (resp && resp.data && resp.data.items) || [] + 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 resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' return { - text: name, - value: name, + ui: ui.data || {}, + language: language.data || {}, + functions, } - }) -} + } + + function returnFalse() { + return true + } + + function isTlsEnabled() { + const dbDetails = getValue(discriminator, '/dbDetails') + return ( + (dbDetails?.spec?.sslMode && + dbDetails?.spec?.sslMode !== 'disabled' && + dbDetails?.spec?.sslMode !== 'disable') || + dbDetails?.spec?.tls + ) + } -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/namespace') + 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/kubedb.com/v1alpha2/namespaces/${namespace}/solrs`, - { + 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) || [] + const resources = (resp && resp.data && resp.data.items) || [] - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -async function getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) { - 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') + async function getDbs() { + if (storeGet('/route/params/actions')) return [] + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - if (namespace && name) { - const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/solrs/${name}` - const resp = await axios.get(url) + const namespace = getValue(model, '/metadata/namespace') + // watchDependency('model#/metadata/namespace') - setDiscriminatorValue('/dbDetails', resp.data || {}) + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/solrs`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) - return resp.data || {} - } else return {} -} + 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 || [] -async function getDbVersions({ axios, storeGet, getValue, discriminator }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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}/solrs/${name}` + const resp = await axios.get(url) - const url = `/clusters/${owner}/${cluster}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/kubedb-ui-presets` + setDiscriminatorValue('/dbDetails', resp.data || {}) - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + 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 { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + presetVersions = presets.admin?.databases?.Solr?.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/solrversions`, + { + 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 allowed = found?.spec?.updateConstraints?.allowlist || [] + 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 filteredSolrVersions = 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.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.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.includes(item.metadata?.name)) && + isVersionWithinConstraints(item.spec?.version, limit) + ) + }) + setDiscriminatorValue('/filteredVersion', filteredSolrVersions) + return filteredSolrVersions.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) - presets.status = String(e.status) + return [] } } - try { - const presetVersions = presets.admin?.databases?.Solr?.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/solrversions`, - { - params: queryParams, - }, - ) + function getVersionInfo() { + const filteredVersion = getValue(discriminator, '/filteredVersion') + if (filteredVersion.length) return '' - const resources = (resp && resp.data && resp.data.items) || [] + let txt = 'No versions from this list can be selected as the target version: [ ' - 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 allowed = found?.spec?.updateConstraints?.allowlist || [] - 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 filteredSolrVersions = 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.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.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.includes(item.metadata?.name)) && - isVersionWithinConstraints(item.spec?.version, limit) - ) + presetVersions.forEach((v, idx) => { + txt = `${txt}"${v}"` + if (idx !== presetVersions.length - 1) txt = txt + ', ' + else txt = txt + ' ]' }) - return filteredSolrVersions.map((item) => { + return txt + } + + function getVersion() { + return filteredVersion.map((item) => { const name = (item.metadata && item.metadata.name) || '' const specVersion = (item.spec && item.spec.version) || '' return { @@ -486,831 +541,1349 @@ async function getDbVersions({ axios, storeGet, getValue, discriminator }) { value: name, } }) - } catch (e) { - console.log(e) - return [] } -} -function versionCompare(v1, v2) { - const arr1 = v1.split('.').map(Number) - const arr2 = v2.split('.').map(Number) + 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 + 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 + if (num1 > num2) return 1 // v1 is higher + if (num1 < num2) return -1 // v2 is higher + } + return 0 // versions are equal } - return 0 // versions are equal -} -function isVersionWithinConstraints(version, constraints) { - let constraintsArr = [] - if (constraints.includes(',')) constraintsArr = constraints?.split(',')?.map((c) => c.trim()) - else constraintsArr = [constraints] + 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 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 || {} + if (topology) return 'Topology' + else return 'Combined' + } - for (let constraint of constraintsArr) { - let match = constraint.match(/^(>=|<=|>|<)/) - let operator = match ? match[0] : '' - let constraintVersion = constraint.replace(/^(>=|<=|>|<)/, '').trim() + function disableOpsRequest() { + if (itemCtx.value === 'HorizontalScaling') { + const dbType = getDbType() - let comparison = versionCompare(version, constraintVersion) + if (dbType === 'Combined') return true + else return false + } else return false + } + + function initNamespace() { + const { namespace } = route.query || {} + return namespace || null + } + + function initDatabaseRef() { + // watchDependency('model#/metadata/namespace') + const { name } = route.params || {} + return name + } + + function clearOpsReqSpec(verd, opsReqType) { if ( - (operator === '>=' && comparison < 0) || - (operator === '<=' && comparison > 0) || - (operator === '>' && comparison <= 0) || - (operator === '<' && comparison >= 0) - ) - return false + opsReqType === 'verticalScaling' || + opsReqType === 'horizontalScaling' || + opsReqType === 'volumeExpansion' || + opsReqType === 'configuration' + ) { + if (verd === 'Topology') { + commit('wizard/model$delete', `/spec/${opsReqType}/node`) + } else { + commit('wizard/model$delete', `/spec/${opsReqType}/coordinator`) + commit('wizard/model$delete', `/spec/${opsReqType}/data`) + commit('wizard/model$delete', `/spec/${opsReqType}/overseer`) + } + } } - return true -} -function ifRequestTypeEqualsTo({ model, getValue, watchDependency }, type) { - const selectedType = getValue(model, '/spec/type') - watchDependency('model#/spec/type') + function asDatabaseOperation() { + return !!route.params.actions + } - return selectedType === type -} + function generateOpsRequestNameForClusterUI(getValue, model, route) { + const dbName = getValue(model, '/spec/databaseRef/name') -function onRequestTypeChange({ model, getValue, commit }) { - 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]}`) - }) -} + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' -function disableOpsRequest({ itemCtx, discriminator, getValue, watchDependency }) { - if (itemCtx.value === 'HorizontalScaling') { - const dbType = getDbType({ - discriminator, - getValue, - watchDependency, - }) + const resources = route.params.resource || '' + const resource = resources.slice(0, -1) - if (dbType === 'Standalone') return true - else return false - } else return false -} + const opsName = dbName ? dbName : resource + return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` + } -function getDbTls({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + function showAndInitName() { + // watchDependency('model#/spec/type') + // watchDependency('model#/spec/databaseRef/name') + const ver = asDatabaseOperation() - const { spec } = dbDetails || {} - return spec?.tls || undefined -} + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' -function getDbType({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') - const { spec } = dbDetails || {} - const { topology } = spec || {} - if (topology) return 'Topology' - else return 'Combined' -} + 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 initNamespace({ route }) { - const { namespace } = route.query || {} - return namespace || null -} + function showAndInitNamespace() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/metadata/namespace', + value: `${route.query.namespace}`, + force: true, + }) + } -function initDatabaseRef({ route, watchDependency }) { - watchDependency('model#/metadata/namespace') - const { name } = route.params || {} - return name -} + return !ver + } -function asDatabaseOperation(route) { - return !!route.params.actions -} + function showAndInitDatabaseRef() { + const ver = asDatabaseOperation() + if (ver) { + commit('wizard/model$update', { + path: '/spec/databaseRef/name', + value: `${route.params.name}`, + force: true, + }) + } -function generateOpsRequestNameForClusterUI(getValue, model, route) { - const dbName = getValue(model, '/spec/databaseRef/name') + return !ver + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + function showConfigureOpsrequestLabel() { + return !asDatabaseOperation() + } - const resources = route.params.resource || '' - const resource = resources.slice(0, -1) + 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, + }) + } + } - const opsName = dbName ? dbName : resource - return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` -} + return !ver + } -function showAndInitName({ route, commit, getValue, model, watchDependency }) { - watchDependency('model#/spec/type') - watchDependency('model#/spec/databaseRef/name') - const ver = asDatabaseOperation(route) + // // vertical scaling + function ifDbTypeEqualsTo(value, opsReqType) { + const verd = getDbType() - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + clearOpsReqSpec(verd, opsReqType) + return value === verd + } - 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, - }) + // // machine profile stuffs + // let machinesFromPreset = [] + + function getMachines(type) { + const presets = storeGet('/kubedbuiPresets') || {} + const dbDetails = getValue(discriminator, '/dbDetails') + // const limits = dbDetails?.spec?.podTemplate?.spec?.resources?.limits || {} + const limits = (type && type !== 'node' + ? dbDetails?.spec?.topology?.[type]?.podTemplate?.spec?.containers?.[0]?.resources?.requests + : dbDetails?.spec?.podTemplate?.spec?.containers?.[0]?.resources?.requests) || { + cpu: '', + memory: '', + } + + 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 } - return !ver -} -function showAndInitNamespace({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/metadata/namespace', - value: `${route.query.namespace}`, - force: true, + + function setMachine(type) { + const dbDetails = getValue(discriminator, '/dbDetails') + // const limits = dbDetails?.spec?.podTemplate?.spec?.resources?.limits || {} + const limits = (type && type !== 'node' + ? dbDetails?.spec?.topology?.[type]?.podTemplate?.spec?.containers?.[0]?.resources?.requests + : dbDetails?.spec?.podTemplate?.spec?.containers?.[0]?.resources?.requests) || { + cpu: '', + memory: '', + } + 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 = {} + } + const machine = parsedInstance[type] || '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-${type}`) + 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') || {} + const instance = annotations['kubernetes.io/instance-type'] + let parsedInstance = {} + try { + if (instance) parsedInstance = JSON.parse(instance) + } catch (e) { + console.log(e) + parsedInstance = {} + } + parsedInstance[type] = selectedMachine.machine + annotations['kubernetes.io/instance-type'] = JSON.stringify(parsedInstance) + + if (machinesFromPreset.length) + commit('wizard/model$update', { + path: '/metadata/annotations', + value: annotations, + force: true, + }) + + if (parsedInstance && Object.keys(parsedInstance).length === 0) + commit('wizard/model$delete', '/metadata/annotations') + } + + function isMachineCustom(path) { + // watchDependency(`discriminator#${path}`) + const machine = getValue(discriminator, `${path}`) + return machine === 'custom' + } + + // Fetch and store database Infos + // for secret configurations in reconfigure + let configSecrets = [] + let secretConfigData = [] + + 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: ['solr.xml'], + }, + }, + ) + configSecrets = resp?.data?.response?.availableSecrets || [] + secretConfigData = resp?.data?.response?.configurations || [] + } 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 } - return !ver -} -function showAndInitDatabaseRef({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/spec/databaseRef/name', - value: `${route.params.name}`, - force: true, + async function getConfigSecretsforAppyConfig() { + const secrets = secretConfigData.map((item) => { + return { text: item.componentName, value: item.componentName } }) + return secrets } - return !ver -} -function showConfigureOpsrequestLabel({ route }) { - return !asDatabaseOperation(route) -} -function showAndInitOpsRequestType({ route, commit }) { - const ver = asDatabaseOperation(route) - const opMap = { - upgrade: 'UpdateVersion', - updateVersion: 'UpdateVersion', - horizontalscaling: 'HorizontalScaling', - verticalscaling: 'VerticalScaling', - volumeexpansion: 'VolumeExpansion', - restart: 'Restart', - reconfiguretls: 'ReconfigureTLS', - reconfigure: 'Reconfigure', - } - if (ver) { - const operation = route.params.actions - const match = /^(.*)-opsrequest-(.*)$/.exec(operation) - const opstype = match[2] + 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: '/spec/type', - value: opMap[opstype], + path: `/temp/${type}applyConfig`, + value: result, force: true, }) + + return result } - return !ver -} + 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` -// vertical scaling -function ifDbTypeEqualsTo({ discriminator, getValue, watchDependency, commit }, value, opsReqType) { - const verd = getDbType({ - discriminator, - getValue, - watchDependency, - }) - return value === verd -} + const selectedConfiguration = + configType === 'create' ? getValue(model, path) : getValue(discriminator, path) -// machine profile stuffs -let machinesFromPreset = [] + 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 '' + } -function getMachines({ storeGet }) { - const presets = storeGet('/kubedbuiPresets') || {} - const avlMachines = presets.admin?.machineProfiles?.available || [] - let arr = [] - if (avlMachines.length) { - arr = avlMachines.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - 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 } - } else return { text: machine, value: machine } + 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 } }) - } else { - arr = machineList - .map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + + // 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])) + + 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', }) - .filter((val) => !!val) + 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 arr -} -function setMachine({ getValue, discriminator, storeGet }, type) { - const dbDetails = getValue(discriminator, '/dbDetails') - 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 = {} + 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 + ) } - const machine = parsedInstance[type] || 'custom' - machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] + function isCreateSecret(type) { + type = type ? type + '/' : '' + const selectedSecret = getValue(model, `spec/configuration/${type}configSecret/name`) + const res = selectedSecret === 'Create' - const machinePresets = machinesFromPreset.find((item) => item.id === machine) - if (machinePresets) return machine - else return 'custom' -} + 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`) -function onMachineChange({ getValue, discriminator, commit, model }, type, valPath) { - let selectedMachine = '' - selectedMachine = getValue(discriminator, `/machine-${type}`) - const machine = machinesFromPreset.find((item) => item.id === selectedMachine) + const configFound = configSecrets.find((item) => item === name) + return configFound ? { text: name, value: name } : '' + } + } - let obj = {} - if (selectedMachine !== 'custom') { - if (machine) obj = { limits: { ...machine?.limits }, requests: { ...machine?.limits } } - else obj = machines[selectedMachine]?.resources - } else { - const val = getValue(discriminator, `/dbDetails${valPath}`) || {} - obj = Array.isArray(val) ? val[0]?.resources : { ...val } + 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', + }) } - const path = `/spec/verticalScaling/${type}/resources` + async function onApplyconfigChange(type) { + type = type ? type + '/' : '' + const configValue = getValue(discriminator, `${type}applyConfig`) - if (obj && Object.keys(obj).length) + if (!configValue) { + commit('wizard/model$delete', `/spec/configuration/${type}applyConfig`) + return + } + const tempConfigObj = {} + configValue.forEach((item) => { + if (item.name) { + 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: path, - value: obj, - force: true, + 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], + }) + }) + } else { + configObj.push({ name: '', content: '' }) + } + return configObj + } - // update metadata.annotations - const annotations = getValue(model, '/metadata/annotations') || {} - const instance = annotations['kubernetes.io/instance-type'] - let parsedInstance = {} - try { - if (instance) parsedInstance = JSON.parse(instance) - } catch (e) { - console.log(e) - parsedInstance = {} - } - if (selectedMachine === 'custom') delete parsedInstance[type] - else parsedInstance[type] = selectedMachine - annotations['kubernetes.io/instance-type'] = JSON.stringify(parsedInstance) - - if (machinesFromPreset.length) + 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: '/metadata/annotations', - value: annotations, - force: true, + path: `/spec/configuration/${type}removeCustomConfig`, + value: true, }) - if (parsedInstance && Object.keys(parsedInstance).length === 0) - commit('wizard/model$delete', '/metadata/annotations') -} + const configuration = secretConfigData.find((item) => item.componentName === selectedConfig) -function isMachineCustom({ watchDependency, getValue, discriminator }, path) { - watchDependency(`discriminator#${path}`) - const machine = getValue(discriminator, `${path}`) - return machine === 'custom' -} + if (!configuration.data) { + return [{ name: '', content: '' }] + } -// for config secret -async function getConfigSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + 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 + } - const secrets = (resp && resp.data && resp.data.items) || [] + async function onNewConfigSecretChange(type) { + type = type ? type + '/' : '' + const path = `/spec/configuration/${type}configSecret/name` + const selectedSecret = getValue(model, path) - const filteredSecrets = secrets + if (!selectedSecret) { + commit('wizard/model$delete', `/spec/configuration/${type}configSecret`) + return [{ name: '', content: '' }] + } + if (selectedSecret === 'Create') return [{ name: '', content: '' }] - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return filteredSecrets -} + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = storeGet('/route/query/namespace') || getValue(model, '/metadata/namespace') -function createSecretUrl({ storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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 + }) + } + }) - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/secrets/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/secrets/create` + return configObj + } catch (e) { + console.error('Error fetching secret:', e) + return [{ name: '', content: '' }] + } } -} -function isEqualToValueFromType({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/valueFromType') - const valueFrom = getValue(discriminator, '/valueFromType') - return valueFrom === value -} - -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function onSelectedSecretChange(type, index) { + type = type ? type + '/' : '' + const secretData = getValue(discriminator, `${type}createSecret/data`) || [] + const selfSecrets = secretData.map((item) => item.key) - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + const remainingSecrets = configSecretKeys.filter((item) => !selfSecrets.includes(item)) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, + const selfKey = getValue(discriminator, `${type}createSecret/data/${index}/key`) + if (selfKey) { + remainingSecrets.push(selfKey) + } + const resSecret = remainingSecrets.map((item) => { + return { text: item, value: item } }) + return resSecret + } + + function createSecretUrl() { + const user = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + 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` + } } - return ans -} -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function isEqualToValueFromType(value) { + // watchDependency('discriminator#/valueFromType') + const valueFrom = getValue(discriminator, '/valueFromType') + return valueFrom === value + } - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` + async function getNamespacedResourceList({ namespace, group, version, resource }) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }) + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) - } + let ans = [] + try { + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) - return ans -} -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - group, - version, - resource, -) { - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/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) - }) + 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') - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + 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) } - }) -} -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) - - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) - }) + + 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, + }) - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) } - }) -} -// reconfiguration type -function ifReconfigurationTypeEqualsTo({ discriminator, getValue, watchDependency }, value) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - watchDependency('discriminator#/reconfigurationType') - - return reconfigurationType === value -} + 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, + }) -function onApplyconfigChange({ discriminator, getValue, commit }) { - const applyconfig = getValue(discriminator, '/applyConfig') + if (resource === 'secrets') { + resources = resources.filter((item) => { + const validType = ['kubernetes.io/service-account-token', 'Opaque'] + return validType.includes(item.type) + }) + } - const configObj = {} - if (applyconfig) { - applyconfig.forEach((item) => { - const { key, value } = item - configObj[key] = value + return resources.map((resource) => { + const name = (resource.metadata && resource.metadata.name) || '' + return { + text: name, + value: name, + } }) } - commit('wizard/model$update', { - path: '/spec/configuration/applyConfig', - value: configObj, - force: true, - }) -} + // reconfiguration type + function ifReconfigurationTypeEqualsTo(value, property, isShard) { + let path = '/reconfigurationType' + if (isShard) path += `-${property}` + const reconfigurationType = getValue(discriminator, path) -function onReconfigurationTypeChange({ commit, discriminator, getValue, setDiscriminatorValue }) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - setDiscriminatorValue('/applyConfig', []) - if (reconfigurationType === 'remove') { - commit('wizard/model$delete', `/spec/configuration`) + const watchPath = `discriminator#${path}` + // watchDependency(watchPath) + return reconfigurationType === value + } - 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`) + function onReconfigurationTypeChange(property, isShard) { + setDiscriminatorValue(`/${property}/applyConfig`, []) + let path = '/reconfigurationType' + if (isShard) path += `-${property}` + const reconfigurationType = getValue(discriminator, path) + if (reconfigurationType === 'remove') { + commit('wizard/model$delete', `/spec/configuration/${property}`) + + commit('wizard/model$update', { + path: `/spec/configuration/${property}/removeCustomConfig`, + value: true, + force: true, + }) + } else { + commit('wizard/model$delete', `/spec/configuration/${property}/configSecret`) + commit('wizard/model$delete', `/spec/configuration/${property}/applyConfig`) + commit('wizard/model$delete', `/spec/configuration/${property}/removeCustomConfig`) + } } -} -// for tls -function hasTlsField({ discriminator, getValue, watchDependency }) { - const tls = getDbTls({ - discriminator, - getValue, - watchDependency, - }) + // for tls + function hasTlsField() { + const tls = getDbTls() - return !!tls -} + return !!tls + } -function initIssuerRefApiGroup({ getValue, model, watchDependency, discriminator }) { - const kind = getValue(model, '/spec/tls/issuerRef/kind') - watchDependency('model#/spec/tls/issuerRef/kind') + 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 -} + if (kind) { + return 'cert-manager.io' + } else return undefined + } -async function getIssuerRefsName({ axios, storeGet, getValue, model, watchDependency }) { - 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` + 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') - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { + 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 presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + 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) - presets.status = String(e.status) + return [] } } - let clusterIssuers = presets.admin?.clusterIssuers?.available || [] - if (presets.status === '404') { - const url = `/clusters/${owner}/${cluster}/proxy/cert-manager.io/v1/clusterissuers` - return getIssuer(url) + } + + 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, + }) + } else if (tlsOperation === 'remove') { + commit('wizard/model$update', { + path: '/spec/tls/remove', + value: true, + force: true, + }) } - return clusterIssuers } - async function getIssuer(url) { - try { - const resp = await axios.get(url) - const resources = (resp && resp.data && resp.data.items) || [] + function showIssuerRefAndCertificates() { + const tlsOperation = getValue(discriminator, '/tlsOperation') + // watchDependency('discriminator#/tlsOperation') + const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' - resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true + return verd + } + + function isIssuerRefRequired() { + const hasTls = hasTlsField() + return hasTls ? false : '' + } + + function getRequestTypeFromRoute() { + const isDbloading = isDbDetailsLoading() + const { query } = route || {} + const { requestType } = query || {} + return isDbloading ? '' : requestType || '' + } + + 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) { + const retValue = getValue(discriminator, `/dbDetails${path}`) + + if (commitPath) { + 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 resources - } catch (e) { - console.log(e) - return [] } + return retValue || undefined } -} -function initTlsOperation() { - return 'update' -} -function onTlsOperationChange({ discriminator, getValue, commit }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + function getAliasOptions() { + return ['server', 'client', 'metrics-exporter'] + } - commit('wizard/model$delete', '/spec/tls') + function isNamespaceDisabled() { + const { namespace } = route.query || {} + return !!namespace + } - 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 isDatabaseRefDisabled() { + const { name } = route.params || {} + return !!name } -} -function showIssuerRefAndCertificates({ discriminator, getValue, watchDependency }) { - const tlsOperation = getValue(discriminator, '/tlsOperation') - watchDependency('discriminator#/tlsOperation') - const verd = tlsOperation !== 'remove' && tlsOperation !== 'rotate' + function onNamespaceChange() { + commit('wizard/model$delete', '/spec/type') + } - return verd -} + function onDbChange() { + commit('wizard/model$delete', '/spec/type') + getDbDetails() + } -function isIssuerRefRequired({ discriminator, getValue, watchDependency }) { - const hasTls = hasTlsField({ - discriminator, - getValue, - watchDependency, - }) + function setApplyToIfReady() { + return 'IfReady' + } - return !hasTls -} + function isVerticalScaleTopologyRequired(type) { + // watchDependency(`discriminator#/topologyKey-${type}`) + // watchDependency(`discriminator#/topologyValue-${type}`) -function getRequestTypeFromRoute({ route, model, discriminator, getValue, watchDependency }) { - const isDbloading = isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) - const { query } = route || {} - const { requestType } = query || {} - return isDbloading ? '' : requestType || '' -} + const key = getValue(discriminator, `/topologyKey-${type}`) + const value = getValue(discriminator, `/topologyValue-${type}`) + const path = `/spec/verticalScaling/${type}/topology` + + if (key || value) { + commit('wizard/model$update', { + path: path, + value: { key, value }, + force: true, + }) + return '' + } else { + commit('wizard/model$delete', path) + return false + } + } -// ************************************** Set db details ***************************************** + function checkVolume(initpath, path) { + const volume = getValue(discriminator, `/dbDetails${initpath}`) + const input = getValue(model, path) -function isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - watchDependency('model#/spec/databaseRef/name') - const dbDetails = getValue(discriminator, '/dbDetails') - const dbName = getValue(model, '/spec/databaseRef/name') + try { + const sizeInBytes = parseSize(volume) + const inputSizeInBytes = parseSize(input) - return !dbDetails || !dbName -} + if (inputSizeInBytes >= sizeInBytes) return + else return 'Cannot expand to lower volume!' + } catch (err) { + return err.message || 'Invalid' + } + } -function setValueFromDbDetails( - { discriminator, getValue, watchDependency, commit }, - path, - commitPath, -) { - watchDependency('discriminator#/dbDetails') + 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 retValue = getValue(discriminator, `/dbDetails${path}`) + const match = String(sizeStr).match(/^([0-9]+(?:\.[0-9]*)?)\s*([A-Za-z]*)$/) + if (!match) throw new Error('Invalid size format') - if (commitPath && retValue) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + const value = parseFloat(match[1]) + const unit = match[2] - // computed called when tls fields is not visible - if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined + if (!(unit in units)) + throw new Error('Unrecognized unit. Available units are K, Ki, M, Mi, G, Gi etc') - // 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 value * units[unit] } - return retValue || undefined -} + function fetchAliasOptions() { + return getAliasOptions ? getAliasOptions() : [] + } -function setResource({ discriminator, getValue, watchDependency, storeGet }, path) { - watchDependency('discriminator#/dbDetails') - const containers = getValue(discriminator, `/dbDetails${path}`) || [] - const kind = getValue(discriminator, '/dbDetails/kind') - const resource = containers.filter((ele) => ele.name === kind.toLowerCase()) - return resource[0].resources -} + function validateNewCertificates({ itemCtx }) { + const addedAliases = (model && model.map((item) => item.alias)) || [] -function getAliasOptions() { - return ['server', 'client', 'metrics-exporter'] -} + if (addedAliases.includes(itemCtx.alias) && itemCtx.isCreate) { + return { isInvalid: true, message: 'Alias already exists' } + } + return {} + } -function isNamespaceDisabled({ route }) { - const { namespace } = route.query || {} - return !!namespace -} + function disableAlias() { + return !!(model && model.alias) + } -function isDatabaseRefDisabled({ route }) { - const { name } = route.params || {} - return !!name -} + function getSelectedConfigSecret(type) { + const path = `/spec/configuration/${type}/configSecret/name` + const selectedSecret = getValue(model, path) + // watchDependency(`model#${path}`) + return `You have selected ${selectedSecret} secret` || 'No secret selected' + } -function onNamespaceChange({ commit }) { - commit('wizard/model$delete', '/spec/type') -} + function objectToYaml(obj, indent = 0) { + if (obj === null || obj === undefined) return 'null' + if (typeof obj !== 'object') return JSON.stringify(obj) -function onDbChange({ commit, axios, storeGet, model, getValue, setDiscriminatorValue }) { - commit('wizard/model$delete', '/spec/type') - getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) -} + const spaces = ' '.repeat(indent) -function setApplyToIfReady() { - return 'IfReady' -} + if (Array.isArray(obj)) { + return obj + .map((item) => `${spaces}- ${objectToYaml(item, indent + 1).trimStart()}`) + .join('\n') + } -function isVerticalScaleTopologyRequired({ watchDependency, getValue, discriminator, commit }) { - watchDependency('discriminator#/topologyKey') - watchDependency('discriminator#/topologyValue') + return Object.keys(obj) + .map((key) => { + const value = obj[key] + const keyLine = `${spaces}${key}:` - const key = getValue(discriminator, '/topologyKey') - const value = getValue(discriminator, '/topologyValue') - const path = `/spec/verticalScaling/solr/topology` + if (value === null || value === undefined) { + return `${keyLine} null` + } - if (key || value) { - commit('wizard/model$update', { - path: path, - value: { key, value }, - force: true, + 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/${type}/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 true - } else { - commit('wizard/model$delete', path) - return false + return data || 'No Data Found' } -} -function checkVolume({ model, discriminator, getValue }, initpath, path) { - const volume = getValue(discriminator, `/dbDetails${initpath}`) - const input = getValue(model, path) + function setExporter(type) { + let path = `/dbDetails/spec/monitor/prometheus/exporter/resources/limits/${type}` + const limitVal = getValue(discriminator, path) - try { - const sizeInBytes = parseSize(volume) - const inputSizeInBytes = parseSize(input) + if (!limitVal) { + path = `/dbDetails/spec/monitor/prometheus/exporter/resources/requests/${type}` + const reqVal = getValue(discriminator, path) - if (inputSizeInBytes >= sizeInBytes) return true - else return 'Cannot expand to lower volume!' - } catch (err) { - return err.message || 'Invalid' + if (reqVal) return reqVal + } + return limitVal } -} -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 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, + }) + } -return { - setResource, - fetchJsons, - returnFalse, - getNamespaces, - getDbs, - getDbDetails, - getDbVersions, - ifRequestTypeEqualsTo, - onRequestTypeChange, - getDbTls, - getDbType, - initNamespace, - initDatabaseRef, - isRancherManaged, - showAndInitName, - showAndInitNamespace, - showAndInitDatabaseRef, - showConfigureOpsrequestLabel, - showAndInitOpsRequestType, - - ifDbTypeEqualsTo, - getConfigSecrets, - createSecretUrl, - isEqualToValueFromType, - disableOpsRequest, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - ifReconfigurationTypeEqualsTo, - onReconfigurationTypeChange, - onApplyconfigChange, - hasTlsField, - initIssuerRefApiGroup, - getIssuerRefsName, - initTlsOperation, - onTlsOperationChange, - showIssuerRefAndCertificates, - isIssuerRefRequired, - getRequestTypeFromRoute, - isDbDetailsLoading, - setValueFromDbDetails, - getAliasOptions, - isNamespaceDisabled, - isDatabaseRefDisabled, - onNamespaceChange, - onDbChange, - setApplyToIfReady, - isVerticalScaleTopologyRequired, - getMachines, - setMachine, - onMachineChange, - isMachineCustom, - checkVolume, + return { + setExporter, + onExporterResourceChange, + fetchAliasOptions, + validateNewCertificates, + disableAlias, + isRancherManaged, + fetchJsons, + returnFalse, + getNamespaces, + getDbs, + getDbDetails, + getDbVersions, + getVersionInfo, + isVersionEmpty, + getVersion, + ifRequestTypeEqualsTo, + onRequestTypeChange, + getDbTls, + getDbType, + disableOpsRequest, + initNamespace, + initDatabaseRef, + clearOpsReqSpec, + showAndInitName, + showAndInitNamespace, + showAndInitDatabaseRef, + showConfigureOpsrequestLabel, + showAndInitOpsRequestType, + ifDbTypeEqualsTo, + getConfigSecrets, + getSelectedConfigSecret, + createSecretUrl, + isEqualToValueFromType, + getNamespacedResourceList, + getResourceList, + resourceNames, + unNamespacedResourceNames, + ifReconfigurationTypeEqualsTo, + onReconfigurationTypeChange, + onApplyconfigChange, + hasTlsField, + initIssuerRefApiGroup, + getIssuerRefsName, + initTlsOperation, + onTlsOperationChange, + showIssuerRefAndCertificates, + isIssuerRefRequired, + getRequestTypeFromRoute, + isDbDetailsLoading, + setValueFromDbDetails, + getAliasOptions, + isNamespaceDisabled, + isDatabaseRefDisabled, + onDbChange, + onNamespaceChange, + setApplyToIfReady, + isVerticalScaleTopologyRequired, + getMachines, + setMachine, + onMachineChange, + isMachineCustom, + checkVolume, + getSelectedConfigSecretValue, + objectToYaml, + fetchConfigSecrets, + getConfigSecretsforAppyConfig, + getSelectedConfigurationData, + getSelectedConfigurationName, + getSelectedConfigurationValueForRemove, + createNewConfigSecret, + decodeError, + isCreateSecret, + isNotCreateSecret, + onCreateSecretChange, + cancelCreateSecret, + setApplyConfig, + onRemoveConfigChange, + onNewConfigSecretChange, + onSelectedSecretChange, + isTlsEnabled, + } } diff --git a/charts/opskubedbcom-zookeeperopsrequest-editor/ui/create-ui.yaml b/charts/opskubedbcom-zookeeperopsrequest-editor/ui/create-ui.yaml index 7d7020daa3..393ce8310a 100644 --- a/charts/opskubedbcom-zookeeperopsrequest-editor/ui/create-ui.yaml +++ b/charts/opskubedbcom-zookeeperopsrequest-editor/ui/create-ui.yaml @@ -1,313 +1,466 @@ -steps: -- form: - discriminator: - dbDetails: - type: object +type: multi-step-form +step: + - type: single-step-form + loader: getDbDetails elements: - - computed: getDbDetails - if: returnFalse - schema: - $ref: discriminator#/properties/dbDetails - type: input - - if: showAndInitName - label: - text: labels.op_req_name - required: true - schema: - $ref: schema#/properties/metadata/properties/name - type: input - - computed: initNamespace - disabled: isNamespaceDisabled - fetch: getNamespaces - hasGroup: isRancherManaged - if: showAndInitNamespace - label: - text: labels.namespace - onChange: onNamespaceChange - required: true - schema: - $ref: schema#/properties/metadata/properties/namespace - type: select - - computed: initDatabaseRef - disabled: isDatabaseRefDisabled - fetch: getDbs - if: showAndInitDatabaseRef - label: - text: labels.databaseRef - onChange: onDbChange - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/databaseRef/properties/name - type: select - - if: showConfigureOpsrequestLabel - label: - text: labels.config_ops_request - type: label-element - - computed: getRequestTypeFromRoute - disabled: isDbDetailsLoading - hasDescription: true - if: showAndInitOpsRequestType - individualItemDisabilityCheck: disableOpsRequest - label: - text: labels.ops_request_type - onChange: onRequestTypeChange - options: - - description: options.UpdateVersion.description - text: options.UpdateVersion.text - value: UpdateVersion - - description: options.HorizontalScaling.description - text: options.HorizontalScaling.text - value: HorizontalScaling - - description: options.VerticalScaling.description - text: options.VerticalScaling.text - value: VerticalScaling - - description: options.VolumeExpansion.description - text: options.VolumeExpansion.text - value: VolumeExpansion - - description: options.Restart.description - text: options.Restart.text - value: Restart - - description: options.Reconfigure.description - text: options.Reconfigure.text - value: Reconfigure - - description: options.ReconfigureTLS.description - text: options.ReconfigureTLS.text - value: ReconfigureTLS - schema: - $ref: schema#/properties/spec/properties/type - type: radio - - elements: - - computed: setValueFromDbDetails|/spec/version - fetch: getDbVersions - label: - text: labels.targetVersion - schema: - $ref: schema#/properties/spec/properties/updateVersion/properties/targetVersion - type: select - if: ifRequestTypeEqualsTo|UpdateVersion - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/replicas - label: - text: labels.replicas - schema: - $ref: schema#/properties/spec/properties/horizontalScaling/properties/replicas - type: input - if: ifRequestTypeEqualsTo|HorizontalScaling - label: - text: Horizontal Scaling Form - type: single-step-form - - discriminator: - machine: - default: "" - type: string - elements: - - computed: setMachine - customClass: mt-20 - disableUnselect: true - fetch: getMachines - label: - text: Machine Profile - onChange: onMachineChange|node|/spec/podTemplate/spec/containers - schema: - $ref: discriminator#/machine - type: select - - if: isMachineCustom - label: - text: labels.resources - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/resources - type: resource-input-form - - label: - text: labels.node_selection_policy +# common + - type: input + label: op_req_name + if: + type: function + name: showAndInitName + validation: + type: required + schema: schema/properties/metadata/properties/name + - type: select + label: Namespace + if: + type: function + name: showAndInitNamespace + init: + type: func + value: initNamespace + disable: isNamespaceDisabled + loader: getNamespaces + validation: + type: required + hasGroup: isRancherManaged + schema: schema/properties/metadata/properties/namespace + watcher: + func: onNamespaceChange + paths: + - schema/properties/metadata/properties/namespace + - type: select + label: Database Ref + if: + type: function + name: showAndInitDatabaseRef + loader: + name: getDbs + watchPaths: + - schema/properties/metadata/properties/namespace + init: + type: func + value: initDatabaseRef + validation: + type: required + disable: isDatabaseRefDisabled + refresh: true + watcher: + paths: + - schema/properties/spec/properties/databaseRef/properties/name + func: onDbChange + schema: schema/properties/spec/properties/databaseRef/properties/name + - type: label-element + label: config_ops_request + if: + type: function + name: showConfigureOpsrequestLabel + - type: radio + label: Type of Ops Request + if: + type: function + name: showAndInitOpsRequestType options: - - text: LabelSelector - value: LabelSelector - - text: Taint - value: Taint - schema: - $ref: schema#/properties/spec/properties/verticalScaling/properties/node/properties/nodeSelectionPolicy - type: select - - discriminator: - topologyKey: - default: "" - type: string - topologyValue: - default: "" - type: string + - 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 + init: + type: func + value: getRequestTypeFromRoute + disable: isDbDetailsLoading + watcher: + func: onRequestTypeChange + paths: + - schema/properties/spec/properties/type + isHorizontal: true + schema: schema/properties/spec/properties/type +# UpdateVersion + - type: block-layout + showLabels: true + label: Version + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|UpdateVersion elements: - - label: - text: labels.key - required: isVerticalScaleTopologyRequired - schema: - $ref: discriminator#/topologyKey - type: input - - label: - text: labels.value - required: isVerticalScaleTopologyRequired - schema: - $ref: discriminator#/topologyValue - type: input - label: - text: labels.topology - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|VerticalScaling - type: single-step-form - - elements: - - computed: setValueFromDbDetails|/spec/storage/resources/requests/storage - label: - text: labels.node - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/node - type: input - validationRuleObject: - func: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/node - - label: - text: Mode - options: - - text: Offline - value: Offline - - text: Online - value: Online - required: true - schema: - $ref: schema#/properties/spec/properties/volumeExpansion/properties/mode - type: select - if: ifRequestTypeEqualsTo|VolumeExpansion - label: - text: Volume Expansion Form - type: single-step-form - - elements: - - discriminator: - reconfigurationType: - type: string + - type: select-compare + label: Target Version + subtitle: Select the desired ZooKeeper version to which you want to update your database. + init: + type: func + value: setValueFromDbDetails|/spec/version + loader: getDbVersions + schema: schema/properties/spec/properties/updateVersion/properties/targetVersion + - type: info + label: '' + loader: + name: getVersionInfo + watchPaths: + - temp/properties/filteredVersion + if: + type: function + name: isVersionEmpty +# Horizontal Scale + - type: block-layout + label: Horizontal Scaling Form + showLabels: true + fixedBlock: true + if: + type: function + name: ifRequestTypeEqualsTo|HorizontalScaling elements: - - label: - text: labels.reconfigurationType - onChange: onReconfigurationTypeChange - options: - - text: Select New Config Secret - value: selectNewConfigSecret - - text: Apply Config - value: applyConfig - - text: Remove - value: remove - required: true - schema: - $ref: discriminator#/properties/reconfigurationType - type: radio - - elements: - - add_new_button: - label: labels.createConfig - target: _blank - url: - function: createSecretUrl - computed: setValueFromDbDetails|/spec/configSecret/name - fetch: getConfigSecrets - label: - text: labels.configSecret - refresh: true - required: true - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret/properties/name - type: select - if: ifReconfigurationTypeEqualsTo|selectNewConfigSecret - label: - text: Configuration config secret - schema: - $ref: schema#/properties/spec/properties/configuration/properties/configSecret - type: single-step-form - - addFormLabel: labels.applyConfig.label - element: - discriminator: - configArray: - emitAs: applyConfig - type: array + - type: horizontal-layout elements: - - label: - text: labels.applyConfig.key - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/key - type: input - - label: - text: labels.applyConfig.value - required: true - schema: - $ref: discriminator#/properties/configArray/items/properties/value - type: editor - type: single-step-form - if: ifReconfigurationTypeEqualsTo|applyConfig - label: - text: labels.applyConfig.label - onChange: onApplyconfigChange - required: true - schema: - $ref: discriminator#/properties/applyConfig - tableContents: - - inTableColumn: true - label: - text: labels.applyConfig.key - path: key - type: value - typeOfValue: string - - inTableColumn: true - label: - text: labels.applyConfig.value - path: value - type: value - typeOfValue: code - type: single-step-form-array - - if: returnFalse - label: - text: labels.removeCustomConfig - schema: - $ref: schema#/properties/spec/properties/configuration/properties/removeCustomConfig - type: switch - label: - text: labels.configuration - schema: - $ref: schema#/properties/spec/properties/configuration - show_label: true - type: single-step-form - if: ifRequestTypeEqualsTo|Reconfigure - label: - text: Reconfigure Form - type: single-step-form - - label: - text: labels.timeout - options: - - text: 5 minutes - value: 5m - - text: 10 minutes - value: 10m - - text: 30 minutes - value: 30m - - text: 1 hour - value: 1h - - text: 2 hours - value: 2h - - text: 5 hours - value: 5h - - text: 10 hours - value: 10h - schema: - $ref: schema#/properties/spec/properties/timeout - type: select - - computed: setApplyToIfReady - label: - text: labels.apply - options: - - text: IfReady (OpsRequest will be applied if database is ready) - value: IfReady - - text: Always (OpsRequest will always be applied) - value: Always - schema: - $ref: schema#/properties/spec/properties/apply - type: radio - type: single-step-form - id: basic - title: steps.0.label -type: multi-step-form + - type: input-compare + label: Replicas + header: Replicas + subtitle: Define the total number of replicas for the database. Increasing replicas improves fault tolerance and load distribution, while reducing replicas conserves resources + init: + type: func + value: setValueFromDbDetails|/spec/replicas + schema: schema/properties/spec/properties/horizontalScaling/properties/replicas + - type: info + 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. +# vertical Scale + - type: block-layout + if: + type: function + name: ifRequestTypeEqualsTo|VerticalScaling + elements: + - type: machine-compare + label: Resources + subtitle: Compare your current machine configuration with the proposed memory adjustments and make informed decisions for your database setup + loader: getMachines + init: + type: func + value: setMachine + watcher: + func: onMachineChange|node|/spec/podTemplate/spec/containers + paths: + - temp/properties/machine + schema: temp/properties/machine + - type: block-layout + label: Node Selection + showLabels: true + elements: + - type: horizontal-layout + elements: + - type: block-layout + showLabels: false + hideBorder: true + elements: + - type: label-element + 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: select + label: Node Selection Policy + schema: schema/properties/spec/properties/verticalScaling/properties/node/properties/nodeSelectionPolicy + options: + - text: LabelSelector + value: LabelSelector + - text: Taint + value: Taint + - type: info + 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" + customClass: mt-20 + - type: label-element + 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: horizontal-layout + elements: + - type: input + label: Key + validation: + type: custom + name: isVerticalScaleTopologyRequired + schema: temp/topologyKey + - type: input + label: Value + validation: + type: custom + name: isVerticalScaleTopologyRequired + schema: temp/topologyValue + - type: block-layout + label: Exporter + showLabels: true + hideBlock: true + elements: + - type: horizontal-layout + showLabels: true + elements: + - init: + type: func + value: setExporter|cpu + type: input + 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 + watcher: + func: onExporterResourceChange|memory + paths: + - schema/properties/spec/properties/verticalScaling/properties/exporter/properties/resources/properties/limits/properties/memory +# Volume Expansion + + - type: block-layout + label: Volume Expansion Form + if: + type: function + name: ifRequestTypeEqualsTo|VolumeExpansion + elements: + - type: horizontal-layout + elements: + - type: block-layout + elements: + - type: label-element + 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: select + label: Mode + options: + - text: Offline + value: Offline + - text: Online + value: Online + validation: + type: required + schema: schema/properties/spec/properties/volumeExpansion/properties/mode + - type: block-layout + label: ZooKeeper volume expansion + showLabels: true + fixedBlock: true + elements: + - type: horizontal-layout + elements: + - type: input-compare + header: Storage + subtitle: How much extra storage does your database need? Specify the size (e.g., 2Gi for 2 gigabytes) so we can allocate it correctly + label: Node + init: + type: func + value: setValueFromDbDetails|/spec/storage/resources/requests/storage + validation: + type: custom + name: checkVolume|/spec/storage/resources/requests/storage|/spec/volumeExpansion/node + schema: schema/properties/spec/properties/volumeExpansion/properties/node +# Reconfigure + - type: block-layout + label: Reconfigure Form + if: + name: ifRequestTypeEqualsTo|Reconfigure + type: function + loader: + name: fetchConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + elements: + - type: block-layout + label: Configuration + elements: + - type: label-element + label: '' + subtitle: Select a new configuration secret, apply a custom configuration, or remove an existing setup to update your database settings + - type: tab-layout + label: New Config Secret + schema: temp/properties/reconfigurationType + options: + - text: NEW CONFIG SECRET + value: selectNewConfigSecret + - text: APPLY CONFIG + value: applyConfig + - text: REMOVE + value: remove + elements: + - type: block-layout + label: Config Secret + if: + name: ifReconfigurationTypeEqualsTo|selectNewConfigSecret + type: function + elements: + - type: label-element + label: Config Secret + subtitle: Select a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: schema/properties/spec/properties/configuration/properties/configSecret/properties/name + refresh: true + label: Config Secret + loader: + name: getConfigSecrets + watchPaths: + - schema/properties/metadata/properties/namespace + - temp/properties/createSecret/properties/status + init: + type: func + value: setValueFromDbDetails|/spec/configSecret/name + watcher: + func: onCreateSecretChange + paths: + - temp/properties/createSecret/properties/status + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|create + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + - type: block-layout + label: Create a New Config Secret + showLabels: true + if: + type: function + name: isCreateSecret + hasButton: + text: Save + hasCancel: cancelCreateSecret + action: createNewConfigSecret + elements: + - type: input + label: Secret Name + schema: temp/properties/createSecret/properties/name + validation: + type: required + - type: array-object-form + label: String Data + schema: temp/properties/createSecret/properties/data + buttonClass: is-light is-outlined + validation: + type: required + elements: + - type: select + label: Key + schema: key + loader: + name: onSelectedSecretChange + watchPaths: + - temp/properties/createSecret/properties/data + validation: + type: required + - type: textarea + label: Value + schema: value + - type: multi-file-editor + editorHeight: 500px + readonly: true + if: + type: function + name: isNotCreateSecret + loader: + name: onNewConfigSecretChange + watchPaths: + - schema/properties/spec/properties/configuration/properties/configSecret/properties/name + schema: temp/properties/newConfigSecret + - type: block-layout + label: ApplyConfig + if: + name: ifReconfigurationTypeEqualsTo|applyConfig + type: function + elements: + - type: label-element + 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). + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfiguration + refresh: true + label: Configuration + loader: getConfigSecretsforAppyConfig + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|apply + watchPaths: + - temp/properties/selectedConfiguration + - type: multi-file-editor + editorHeight: 500px + schema: temp/properties/applyConfig + loader: + name: setApplyConfig + watchPaths: + - temp/properties/selectedConfiguration + watcher: + func: onApplyconfigChange + paths: + - temp/properties/applyConfig + - type: block-layout + label: Remove + if: + name: ifReconfigurationTypeEqualsTo|remove + type: function + elements: + - type: label-element + label: Remove + subtitle: Selected a configuration secret from the available list to update your database settings + customClass: mb-10 + - type: select + customClass: mb-2 + schema: temp/properties/selectedConfigurationRemove + refresh: true + label: Configuration + loader: + name: getConfigSecretsforAppyConfig + watchPaths: + - schema/properties/metadata/properties/namespace + - type: label-element + label: '' + loader: + name: getSelectedConfigurationName|remove + watchPaths: + - temp/properties/selectedConfigurationRemove + - type: multi-file-editor + editorHeight: 500px + readonly: true + init: + type: func + value: onRemoveConfigChange + watcher: + func: onRemoveConfigChange + paths: + - temp/properties/selectedConfigurationRemove + schema: temp/properties/removeConfig + +# common + - type: block-layout + label: OpsRequest Options + showLabels: true + elements: + - type: time-picker + label: Timeout + schema: 'schema/properties/spec/properties/timeout' + subtitle: Specify the maximum time allowed for the scaling operation to complete. Use formats like 30sec, 1min(1 minute) or 2h(2 hours). + - type: radio + label: Apply + schema: 'schema/properties/spec/properties/apply' + init: + type: func + value: setApplyToIfReady + options: + - text: IfReady (OpsRequest will be applied if database is ready) + value: IfReady + - text: Always (OpsRequest will always be applied) + value: Always diff --git a/charts/opskubedbcom-zookeeperopsrequest-editor/ui/functions.js b/charts/opskubedbcom-zookeeperopsrequest-editor/ui/functions.js index ececbe335a..c99b7dda10 100644 --- a/charts/opskubedbcom-zookeeperopsrequest-editor/ui/functions.js +++ b/charts/opskubedbcom-zookeeperopsrequest-editor/ui/functions.js @@ -1,3 +1,5 @@ +const { axios, useOperator, store, useToast } = window.vueHelpers || {} + const machines = { 'db.t.micro': { resources: { @@ -304,151 +306,202 @@ const machineList = [ 'db.r.24xlarge', ] -function returnFalse() { - return false -} - -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} +let machinesFromPreset = [] +const configSecretKeys = ['zoo.cfg'] -async function getNamespaces({ axios, storeGet }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') +export const useFunc = (model) => { + const route = store.state?.route + const toast = useToast() - const resp = await axios.get(`/clusters/${owner}/${cluster}/proxy/core/v1/namespaces`, { - params: { filter: { items: { metadata: { name: null } } } }, - }) + const { getValue, storeGet, discriminator, setDiscriminatorValue, commit } = useOperator( + model, + store.state, + ) - const resources = (resp && resp.data && resp.data.items) || [] + showAndInitOpsRequestType() - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + function returnFalse() { + return false + } -async function getDbs({ axios, storeGet, model, getValue, watchDependency }) { - if (storeGet('/route/params/actions')) return [] - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/namespace') + 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/kubedb.com/v1alpha2/namespaces/${namespace}/zookeepers`, - { + 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) || [] + const resources = (resp && resp.data && resp.data.items) || [] - return resources.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + return resources.map((item) => { + const name = (item.metadata && item.metadata.name) || '' + return { + text: name, + value: name, + } + }) + } -async function getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) { - 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') + async function getDbs() { + if (storeGet('/route/params/actions')) return [] + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - if (namespace && name) { - const url = `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/zookeepers/${name}` - const resp = await axios.get(url) + const namespace = getValue(model, '/metadata/namespace') + // watchDependency'model#/metadata/namespace') - setDiscriminatorValue('/dbDetails', resp.data || {}) + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/kubedb.com/v1alpha2/namespaces/${namespace}/zookeepers`, + { + params: { filter: { items: { metadata: { name: null } } } }, + }, + ) - return resp.data || {} - } else return {} -} + 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 getDbVersions({ axios, storeGet, getValue, discriminator }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + async function getDbDetails() { + machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] - const url = `/clusters/${owner}/${cluster}/proxy/charts.x-helm.dev/v1alpha1/clusterchartpresets/kubedb-ui-presets` + 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}/zookeepers/${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) + } + } - let presets = storeGet('/kubedbuiPresets') || {} - if (!storeGet('/route/params/actions')) { try { - const presetResp = await axios.get(url) - presets = presetResp.data?.spec?.values?.spec + presetVersions = presets.admin?.databases?.ZooKeeper?.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/zookeeperversions`, + { + 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 allowed = found?.spec?.updateConstraints?.allowlist || [] + 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 filteredZooKeeperVersions = 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.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.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.includes(item.metadata?.name)) && + isVersionWithinConstraints(item.spec?.version, limit) + ) + }) + + setDiscriminatorValue('/filteredVersion', filteredZooKeeperVersions) + return filteredZooKeeperVersions.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) - presets.status = String(e.status) + return [] } } - try { - const presetVersions = presets.admin?.databases?.ZooKeeper?.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/zookeeperversions`, - { - params: queryParams, - }, - ) + function getVersionInfo() { + const filteredVersion = getValue(discriminator, '/filteredVersion') + if (filteredVersion.length) return '' - const resources = (resp && resp.data && resp.data.items) || [] + let txt = 'No versions from this list can be selected as the target version: [ ' - 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 allowed = found?.spec?.updateConstraints?.allowlist || [] - 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 filteredZooKeeperVersions = 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.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.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.includes(item.metadata?.name)) && - isVersionWithinConstraints(item.spec?.version, limit) - ) + presetVersions.forEach((v, idx) => { + txt = `${txt}"${v}"` + if (idx !== presetVersions.length - 1) txt = txt + ', ' + else txt = txt + ' ]' }) - return filteredZooKeeperVersions.map((item) => { + return txt + } + + function getVersion() { + return filteredVersion.map((item) => { const name = (item.metadata && item.metadata.name) || '' const specVersion = (item.spec && item.spec.version) || '' return { @@ -456,572 +509,1024 @@ async function getDbVersions({ axios, storeGet, getValue, discriminator }) { value: name, } }) - } catch (e) { - console.log(e) - return [] } -} -function versionCompare(v1, v2) { - const arr1 = v1.split('.').map(Number) - const arr2 = v2.split('.').map(Number) + 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 + 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 + if (num1 > num2) return 1 // v1 is higher + if (num1 < num2) return -1 // v2 is higher + } + return 0 // versions are equal } - 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 + 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 } - return true -} -function ifRequestTypeEqualsTo({ model, getValue, watchDependency }, type) { - const selectedType = getValue(model, '/spec/type') - watchDependency('model#/spec/type') + function ifRequestTypeEqualsTo(type) { + const selectedType = getValue(model, '/spec/type') + // watchDependency'model#/spec/type') - return selectedType === type -} + return selectedType === type + } -function onRequestTypeChange({ model, getValue, commit }) { - 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 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', + } -function disableOpsRequest({ itemCtx, discriminator, getValue, watchDependency }) { - if (itemCtx.value === 'HorizontalScaling') { - const dbType = getDbType({ - discriminator, - getValue, - watchDependency, + Object.keys(reqTypeMapping).forEach((key) => { + if (key !== selectedType) commit('wizard/model$delete', `/spec/${reqTypeMapping[key]}`) }) + } - if (dbType === 'Standalone') return true - else return false - } else return false -} + function disableOpsRequest() { + if (itemCtx.value === 'HorizontalScaling') { + const dbType = getDbType({ + discriminator, + getValue, + }) -function getDbTls({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + if (dbType === 'Standalone') return true + else return false + } else return false + } - const { spec } = dbDetails || {} - return spec?.tls || undefined -} + function getDbTls() { + // watchDependency'discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') -function getDbType({ discriminator, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - const dbDetails = getValue(discriminator, '/dbDetails') + const { spec } = dbDetails || {} + return spec?.tls || undefined + } - const { spec } = dbDetails || {} - const { mode } = spec || {} + function getDbType() { + // watchDependency'discriminator#/dbDetails') + const dbDetails = getValue(discriminator, '/dbDetails') - return mode || 'Standalone' -} + const { spec } = dbDetails || {} + const { mode } = spec || {} -function initNamespace({ route }) { - const { namespace } = route.query || {} - return namespace || null -} + return mode || 'Standalone' + } -function initDatabaseRef({ route, watchDependency }) { - watchDependency('model#/metadata/namespace') - const { name } = route.params || {} - return name -} + function initNamespace() { + const { namespace } = route.query || {} + return namespace || null + } -function asDatabaseOperation(route) { - return !!route.params.actions -} + function initDatabaseRef() { + // watchDependency'model#/metadata/namespace') + const { name } = route.params || {} + return name + } -function generateOpsRequestNameForClusterUI(getValue, model, route) { - const dbName = getValue(model, '/spec/databaseRef/name') + function asDatabaseOperation(route) { + return !!route.params.actions + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + function generateOpsRequestNameForClusterUI() { + const dbName = getValue(model, '/spec/databaseRef/name') - const resources = route.params.resource || '' - const resource = resources.slice(0, -1) + const selectedType = getValue(model, '/spec/type') + const lowerType = selectedType ? String(selectedType).toLowerCase() : '' - const opsName = dbName ? dbName : resource - return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` -} + const resources = route.params.resource || '' + const resource = resources.slice(0, -1) -function showAndInitName({ route, commit, getValue, model, watchDependency }) { - watchDependency('model#/spec/type') - watchDependency('model#/spec/databaseRef/name') - const ver = asDatabaseOperation(route) + const opsName = dbName ? dbName : resource + return `${opsName}-${Math.floor(Date.now() / 1000)}${lowerType ? '-' + lowerType : ''}` + } - const selectedType = getValue(model, '/spec/type') - const lowerType = selectedType ? String(selectedType).toLowerCase() : '' + function showAndInitName() { + // watchDependency'model#/spec/type') + // watchDependency'model#/spec/databaseRef/name') + const ver = asDatabaseOperation(route) - 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, - }) + 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 } - return !ver -} -function showAndInitNamespace({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/metadata/namespace', - value: `${route.query.namespace}`, - force: true, + function showAndInitNamespace() { + const ver = asDatabaseOperation(route) + if (ver) { + commit('wizard/model$update', { + path: '/metadata/namespace', + value: `${route.query.namespace}`, + force: true, + }) + } + + return !ver + } + function showAndInitDatabaseRef() { + const ver = asDatabaseOperation(route) + if (ver) { + commit('wizard/model$update', { + path: '/spec/databaseRef/name', + value: `${route.params.name}`, + force: true, + }) + } + + return !ver + } + function showConfigureOpsrequestLabel() { + return !asDatabaseOperation(route) + } + function showAndInitOpsRequestType() { + const ver = asDatabaseOperation(route) + 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 + } + + // Fetch and store database Infos + // for secret configurations in reconfigure + let configSecrets = [] + let secretConfigData = [] + + 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: ['zoo.cfg'], + }, + }, + ) + configSecrets = resp?.data?.response?.availableSecrets || [] + secretConfigData = resp?.data?.response?.configurations || [] + } 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 } - return !ver -} -function showAndInitDatabaseRef({ route, commit }) { - const ver = asDatabaseOperation(route) - if (ver) { - commit('wizard/model$update', { - path: '/spec/databaseRef/name', - value: `${route.params.name}`, - force: true, + async function getConfigSecretsforAppyConfig() { + const secrets = secretConfigData.map((item) => { + return { text: item.componentName, value: item.componentName } }) + return secrets } - return !ver -} -function showConfigureOpsrequestLabel({ route }) { - return !asDatabaseOperation(route) -} -function showAndInitOpsRequestType({ route, commit }) { - const ver = asDatabaseOperation(route) - const opMap = { - upgrade: 'UpdateVersion', - updateVersion: 'UpdateVersion', - horizontalscaling: 'HorizontalScaling', - verticalscaling: 'VerticalScaling', - volumeexpansion: 'VolumeExpansion', - restart: 'Restart', - reconfiguretls: 'ReconfigureTLS', - reconfigure: 'Reconfigure', - } - if (ver) { - const operation = route.params.actions - const match = /^(.*)-opsrequest-(.*)$/.exec(operation) - const opstype = match[2] + 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: '/spec/type', - value: opMap[opstype], + path: `/temp/${type}applyConfig`, + value: result, force: true, }) + + return result } - return !ver -} + 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` -// for config secret -async function getConfigSecrets({ storeGet, axios, model, getValue, watchDependency }) { - 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/core/v1/namespaces/${namespace}/secrets`, - { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }, - ) + 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' } + } - const secrets = (resp && resp.data && resp.data.items) || [] + function getSelectedConfigurationValueForRemove(type) { + type = type ? type + '/' : '' + const path = `/${type}selectedConfigurationRemove` + const selectedConfiguration = getValue(discriminator, path) - const filteredSecrets = secrets + if (!selectedConfiguration) { + return '' + } - filteredSecrets.map((item) => { - const name = (item.metadata && item.metadata.name) || '' - item.text = name - item.value = name - return true - }) - return filteredSecrets -} + const configuration = secretConfigData.find( + (item) => item.componentName === selectedConfiguration, + ) -function createSecretUrl({ storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + if (!configuration) { + return '' + } - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/secrets/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/secrets/create` + 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) } -} -function isEqualToValueFromType({ discriminator, getValue, watchDependency }, value) { - watchDependency('discriminator#/valueFromType') - const valueFrom = getValue(discriminator, '/valueFromType') - return valueFrom === value -} + 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])) -async function getNamespacedResourceList(axios, storeGet, { namespace, group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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() + } + } - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` + 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 + ) + } - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, - }) + function isCreateSecret(type) { + type = type ? type + '/' : '' + const selectedSecret = getValue(model, `spec/configuration/${type}configSecret/name`) + const res = selectedSecret === 'Create' - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + if (res === true) { + commit('wizard/temp$update', { + path: `${type}createSecret/status`, + value: 'pending', + }) + } + return res } - return ans -} + 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 } : '' + } + } -async function getResourceList(axios, storeGet, { group, version, resource }) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + 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', + }) + } - const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/${resource}` + async function onApplyconfigChange(type) { + type = type ? type + '/' : '' + const configValue = getValue(discriminator, `${type}applyConfig`) - let ans = [] - try { - const resp = await axios.get(url, { - params: { - filter: { items: { metadata: { name: null }, type: null } }, - }, + if (!configValue) { + commit('wizard/model$delete', `/spec/configuration/${type}applyConfig`) + return + } + const tempConfigObj = {} + configValue.forEach((item) => { + if (item.name) { + 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, }) + } - const items = (resp && resp.data && resp.data.items) || [] - ans = items - } catch (e) { - console.log(e) + 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], + }) + }) + } else { + configObj.push({ name: '', content: '' }) + } + return configObj } - return ans -} + function onRemoveConfigChange(type) { + type = type ? type + '/' : '' + const configPath = `/${type}selectedConfigurationRemove` + const selectedConfig = getValue(discriminator, configPath) -async function resourceNames( - { axios, getValue, model, watchDependency, storeGet }, - group, - version, - resource, -) { - const namespace = getValue(model, '/metadata/namespace') - watchDependency('model#/metadata/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) + if (!selectedConfig) { + commit('wizard/model$delete', `/spec/configuration/${type}removeCustomConfig`) + return [{ name: '', content: '' }] + } + commit('wizard/model$update', { + path: `/spec/configuration/${type}removeCustomConfig`, + value: true, }) - } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, + const configuration = secretConfigData.find((item) => item.componentName === selectedConfig) + + if (!configuration.data) { + return [{ name: '', content: '' }] } - }) -} -async function unNamespacedResourceNames({ axios, storeGet }, group, version, resource) { - let resources = await getResourceList(axios, storeGet, { - group, - version, - resource, - }) - - if (resource === 'secrets') { - resources = resources.filter((item) => { - const validType = ['kubernetes.io/service-account-token', 'Opaque'] - return validType.includes(item.type) + 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 } - return resources.map((resource) => { - const name = (resource.metadata && resource.metadata.name) || '' - return { - text: name, - value: name, - } - }) -} + async function onNewConfigSecretChange(type) { + type = type ? type + '/' : '' + const path = `/spec/configuration/${type}configSecret/name` + const selectedSecret = getValue(model, path) -// reconfiguration type -function ifReconfigurationTypeEqualsTo({ discriminator, getValue, watchDependency }, value) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - watchDependency('discriminator#/reconfigurationType') + if (!selectedSecret) { + commit('wizard/model$delete', `/spec/configuration/${type}configSecret`) + return [{ name: '', content: '' }] + } + if (selectedSecret === 'Create') return [{ name: '', content: '' }] - return reconfigurationType === value -} + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + const namespace = storeGet('/route/query/namespace') || getValue(model, '/metadata/namespace') -function onApplyconfigChange({ discriminator, getValue, commit }) { - const applyconfig = getValue(discriminator, '/applyConfig') + 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 + }) + } + }) - const configObj = {} - if (applyconfig) { - applyconfig.forEach((item) => { - const { key, value } = item - configObj[key] = value - }) + return configObj + } catch (e) { + console.error('Error fetching secret:', e) + return [{ name: '', content: '' }] + } } - commit('wizard/model$update', { - path: '/spec/configuration/applyConfig', - value: configObj, - force: true, - }) -} + function onSelectedSecretChange(index) { + const secretData = getValue(discriminator, 'createSecret/data') || [] + const selfSecrets = secretData.map((item) => item.key) -function onReconfigurationTypeChange({ commit, discriminator, getValue, setDiscriminatorValue }) { - const reconfigurationType = getValue(discriminator, '/reconfigurationType') - setDiscriminatorValue('/applyConfig', []) - if (reconfigurationType === 'remove') { - commit('wizard/model$delete', `/spec/configuration`) + const remainingSecrets = configSecretKeys.filter((item) => !selfSecrets.includes(item)) - commit('wizard/model$update', { - path: `/spec/configuration/removeCustomConfig`, - value: true, - force: true, + const selfKey = getValue(discriminator, `createSecret/data/${index}/key`) + if (selfKey) { + remainingSecrets.push(selfKey) + } + const resSecret = remainingSecrets.map((item) => { + return { text: item, value: item } }) - } else { - commit('wizard/model$delete', `/spec/configuration/configSecret`) - commit('wizard/model$delete', `/spec/configuration/applyConfig`) - commit('wizard/model$delete', `/spec/configuration/removeCustomConfig`) + return resSecret } -} -function getRequestTypeFromRoute({ route, model, discriminator, getValue, watchDependency }) { - const isDbloading = isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) - const { query } = route || {} - const { requestType } = query || {} - return isDbloading ? '' : requestType || '' -} + let secretArray = [] -// ************************************** Set db details ***************************************** + function objectToYaml(obj, indent = 0) { + if (obj === null || obj === undefined) return 'null' + if (typeof obj !== 'object') return JSON.stringify(obj) -function isDbDetailsLoading({ discriminator, model, getValue, watchDependency }) { - watchDependency('discriminator#/dbDetails') - watchDependency('model#/spec/databaseRef/name') - const dbDetails = getValue(discriminator, '/dbDetails') - const dbName = getValue(model, '/spec/databaseRef/name') + const spaces = ' '.repeat(indent) - return !dbDetails || !dbName -} + if (Array.isArray(obj)) { + return obj + .map((item) => `${spaces}- ${objectToYaml(item, indent + 1).trimStart()}`) + .join('\n') + } -function setValueFromDbDetails( - { discriminator, getValue, watchDependency, commit }, - path, - commitPath, -) { - watchDependency('discriminator#/dbDetails') + return Object.keys(obj) + .map((key) => { + const value = obj[key] + const keyLine = `${spaces}${key}:` - const retValue = getValue(discriminator, `/dbDetails${path}`) + if (value === null || value === undefined) { + return `${keyLine} null` + } - if (commitPath && retValue) { - const tlsOperation = getValue(discriminator, '/tlsOperation') + if (typeof value === 'object') { + const nested = objectToYaml(value, indent + 1) + return `${keyLine}\n${nested}` + } - // computed called when tls fields is not visible - if (commitPath.includes('/spec/tls') && tlsOperation !== 'update') return undefined + if (typeof value === 'string') { + return `${keyLine} "${value}"` + } - // 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 `${keyLine} ${value}` + }) + .join('\n') + } + + function getSelectedConfigSecret() { + const path = '/spec/configuration/configSecret/name' + const selectedSecret = getValue(model, path) + // watchDependency(`model#${path}`) + return `You have selected ${selectedSecret} secret` || 'No secret selected' + } + + function getSelectedConfigSecretValue() { + 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' } - return retValue || undefined -} + function createSecretUrl() { + const user = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function setResource({ discriminator, getValue, watchDependency }, path) { - watchDependency('discriminator#/dbDetails') - const containers = getValue(discriminator, `/dbDetails${path}`) || [] - const kind = getValue(discriminator, '/dbDetails/kind') - const resource = containers.filter((ele) => ele.name === kind.toLowerCase()) - return resource[0].resources -} + 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 isNamespaceDisabled({ route }) { - const { namespace } = route.query || {} - return !!namespace -} + function isEqualToValueFromType(value) { + // watchDependency'discriminator#/valueFromType') + const valueFrom = getValue(discriminator, '/valueFromType') + return valueFrom === value + } -function isDatabaseRefDisabled({ route }) { - const { name } = route.params || {} - return !!name -} + async function getNamespacedResourceList( + axios, + storeGet, + { namespace, group, version, resource }, + ) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') -function onNamespaceChange({ commit }) { - commit('wizard/model$delete', '/spec/type') -} + const url = `/clusters/${owner}/${cluster}/proxy/${group}/${version}/namespaces/${namespace}/${resource}` -function onDbChange({ commit, axios, storeGet, model, getValue, setDiscriminatorValue }) { - commit('wizard/model$delete', '/spec/type') - getDbDetails({ axios, storeGet, model, getValue, setDiscriminatorValue }) -} + let ans = [] + try { + const resp = await axios.get(url, { + params: { + filter: { items: { metadata: { name: null }, type: null } }, + }, + }) -function setApplyToIfReady() { - return 'IfReady' -} + const items = (resp && resp.data && resp.data.items) || [] + ans = items + } catch (e) { + console.log(e) + } -function isVerticalScaleTopologyRequired({ watchDependency, getValue, discriminator, commit }) { - watchDependency('discriminator#/topologyKey') - watchDependency('discriminator#/topologyValue') + return ans + } - const key = getValue(discriminator, '/topologyKey') - const value = getValue(discriminator, '/topologyValue') - const path = `/spec/verticalScaling/zookeeper/topology` + async function getResourceList(axios, storeGet, { group, version, resource }) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - if (key || value) { - commit('wizard/model$update', { - path: path, - value: { key, value }, - force: true, + 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(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, + } }) - return true - } else { - commit('wizard/model$delete', path) - return false } -} -// machine profile stuffs -let machinesFromPreset = [] + async function unNamespacedResourceNames(group, version, resource) { + let resources = await getResourceList(axios, storeGet, { + group, + version, + resource, + }) -function getMachines({ storeGet }) { - const presets = storeGet('/kubedbuiPresets') || {} - const avlMachines = presets.admin?.machineProfiles?.available || [] - let arr = [] - if (avlMachines.length) { - arr = avlMachines.map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - 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 } - } else return { text: machine, value: machine } + 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, } }) - } else { - arr = machineList - .map((machine) => { - if (machine === 'custom') return { text: machine, value: machine } - const subText = `CPU: ${machines[machine].resources.limits.cpu}, Memory: ${machines[machine].resources.limits.memory}` - const text = machine - return { text, subText, value: machine } + } + + // 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, }) - .filter((val) => !!val) + } else { + commit('wizard/model$delete', `/spec/configuration/configSecret`) + commit('wizard/model$delete', `/spec/configuration/applyConfig`) + commit('wizard/model$delete', `/spec/configuration/removeCustomConfig`) + } } - return arr -} -function setMachine({ getValue, discriminator, storeGet }) { - const dbDetails = getValue(discriminator, '/dbDetails') - const annotations = dbDetails?.metadata?.annotations || {} - const machine = annotations['kubernetes.io/instance-type'] || 'custom' + function getRequestTypeFromRoute() { + const isDbloading = isDbDetailsLoading({ discriminator, model, getValue }) + const { query } = route || {} + const { requestType } = query || {} + return isDbloading ? '' : requestType || '' + } - machinesFromPreset = storeGet('/kubedbuiPresets')?.admin?.machineProfiles?.machines || [] + // ************************************** Set db details ***************************************** - const machinePresets = machinesFromPreset.find((item) => item.id === machine) - if (machinePresets) return machine - else return 'custom' -} + 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}`) -function onMachineChange({ getValue, discriminator, commit, model }, type, valPath) { - let selectedMachine = '' - selectedMachine = getValue(discriminator, '/machine') - const machine = machinesFromPreset.find((item) => item.id === selectedMachine) + if (commitPath && retValue) { + const tlsOperation = getValue(discriminator, '/tlsOperation') - let obj = {} - if (selectedMachine !== 'custom') { - if (machine) obj = { limits: { ...machine?.limits }, requests: { ...machine?.limits } } - else obj = machines[selectedMachine]?.resources - } else { - const val = getValue(discriminator, `/dbDetails${valPath}`) || {} - obj = Array.isArray(val) ? val[0]?.resources : { ...val } + // 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 } - const path = `/spec/verticalScaling/${type}/resources` + function setResource(path) { + // watchDependency'discriminator#/dbDetails') + const containers = getValue(discriminator, `/dbDetails${path}`) || [] + const kind = getValue(discriminator, '/dbDetails/kind') + const resource = containers.filter((ele) => ele.name === kind.toLowerCase()) + return resource[0].resources + } - if (obj && Object.keys(obj).length) - commit('wizard/model$update', { - path: path, - value: obj, - force: true, - }) + 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({ axios, storeGet, model, getValue, setDiscriminatorValue }) + } + + 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/zookeeper/topology` + + if (key || value) { + commit('wizard/model$update', { + path: path, + value: { key, value }, + force: true, + }) + return + } else { + commit('wizard/model$delete', path) + return false + } + } + + // machine profile stuffs + function getMachines() { + const presets = storeGet('/kubedbuiPresets') || {} + const dbDetails = getValue(discriminator, '/dbDetails') + // const limits = dbDetails?.spec?.podTemplate?.spec?.resources?.limits || {} + const limits = dbDetails?.spec?.podTemplate?.spec?.containers?.[0]?.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?.limits || {} + const limits = dbDetails?.spec?.podTemplate?.spec?.containers?.[0]?.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 }, + } + } - // update metadata.annotations - const annotations = getValue(model, '/metadata/annotations') || {} - if (selectedMachine === 'custom') commit('wizard/model$delete', '/metadata/annotations') - else { - annotations['kubernetes.io/instance-type'] = selectedMachine + 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', @@ -1029,102 +1534,148 @@ function onMachineChange({ getValue, discriminator, commit, model }, type, valPa force: true, }) } -} -function isMachineCustom({ watchDependency, getValue, discriminator }) { - watchDependency('discriminator#/machine') - const machine = getValue(discriminator, '/machine') - return machine === 'custom' -} + function isMachineCustom() { + // watchDependency'discriminator#/machine') + const machine = getValue(discriminator, '/machine') + return machine === 'custom' + } -function checkVolume({ model, discriminator, getValue }, initpath, path) { - const volume = getValue(discriminator, `/dbDetails${initpath}`) - const input = getValue(model, path) + function checkVolume(initpath, path) { + const volume = getValue(discriminator, `/dbDetails${initpath}`) + const input = getValue(model, path) - try { - const sizeInBytes = parseSize(volume) - const inputSizeInBytes = parseSize(input) + try { + const sizeInBytes = parseSize(volume) + const inputSizeInBytes = parseSize(input) - if (inputSizeInBytes >= sizeInBytes) return true - else return 'Cannot expand to lower volume!' - } catch (err) { - return err.message || 'Invalid' + 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 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] + } -return { - returnFalse, - getNamespaces, - getDbs, - getDbDetails, - getDbVersions, - ifRequestTypeEqualsTo, - onRequestTypeChange, - getDbTls, - getDbType, - initNamespace, - initDatabaseRef, - isRancherManaged, - showAndInitName, - showAndInitNamespace, - showAndInitDatabaseRef, - showConfigureOpsrequestLabel, - showAndInitOpsRequestType, - - getConfigSecrets, - createSecretUrl, - isEqualToValueFromType, - disableOpsRequest, - getNamespacedResourceList, - getResourceList, - resourceNames, - unNamespacedResourceNames, - ifReconfigurationTypeEqualsTo, - onReconfigurationTypeChange, - onApplyconfigChange, - getRequestTypeFromRoute, - isDbDetailsLoading, - setValueFromDbDetails, - setResource, - isNamespaceDisabled, - isDatabaseRefDisabled, - onNamespaceChange, - onDbChange, - setApplyToIfReady, - isVerticalScaleTopologyRequired, - - getMachines, - setMachine, - onMachineChange, - isMachineCustom, - checkVolume, + 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, + }) + } + + return { + setExporter, + onExporterResourceChange, + returnFalse, + getNamespaces, + getDbs, + getDbDetails, + getDbVersions, + getVersionInfo, + isVersionEmpty, + getVersion, + ifRequestTypeEqualsTo, + onRequestTypeChange, + getDbTls, + getDbType, + initNamespace, + initDatabaseRef, + isRancherManaged, + showAndInitName, + showAndInitNamespace, + showAndInitDatabaseRef, + showConfigureOpsrequestLabel, + showAndInitOpsRequestType, + getConfigSecrets, + objectToYaml, + getSelectedConfigSecret, + getSelectedConfigSecretValue, + createSecretUrl, + isEqualToValueFromType, + disableOpsRequest, + getNamespacedResourceList, + getResourceList, + resourceNames, + unNamespacedResourceNames, + ifReconfigurationTypeEqualsTo, + onReconfigurationTypeChange, + onApplyconfigChange, + getRequestTypeFromRoute, + isDbDetailsLoading, + setValueFromDbDetails, + setResource, + isNamespaceDisabled, + isDatabaseRefDisabled, + onNamespaceChange, + onDbChange, + setApplyToIfReady, + isVerticalScaleTopologyRequired, + getMachines, + setMachine, + onMachineChange, + isMachineCustom, + checkVolume, + fetchConfigSecrets, + getConfigSecretsforAppyConfig, + getSelectedConfigurationData, + getSelectedConfigurationName, + getSelectedConfigurationValueForRemove, + createNewConfigSecret, + decodeError, + isCreateSecret, + isNotCreateSecret, + onCreateSecretChange, + cancelCreateSecret, + setApplyConfig, + onRemoveConfigChange, + onNewConfigSecretChange, + onSelectedSecretChange, + } } diff --git a/charts/storagekubestashcom-backupstorage-editor-options/ui/create-ui.yaml b/charts/storagekubestashcom-backupstorage-editor-options/ui/create-ui.yaml index 2164805b2b..c3b163d736 100644 --- a/charts/storagekubestashcom-backupstorage-editor-options/ui/create-ui.yaml +++ b/charts/storagekubestashcom-backupstorage-editor-options/ui/create-ui.yaml @@ -1,287 +1,184 @@ -steps: -- form: - elements: +step: +- type: single-step-form + elements: + - loader: getNamespaces + hasGroup: isRancherManaged + label: Namespace + schema: schema/properties/metadata/properties/release/properties/namespace + type: select + - label: Name + schema: schema/properties/metadata/properties/release/properties/name + type: input + - elements: + - type: object-item + label: Labels + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + schema: schema/properties/spec/properties/annotations + label: Labels & Annotations + showLabels: true + hideBlock: true + type: block-layout + - customClass: mt-10 + label: Deletion Policy + options: + - description: options.deletionPolicy.delete.description + text: Delete (Keep only database Secrets and backed up data) + value: Delete + - description: options.deletionPolicy.wipeOut.description + text: WipeOut (Delete everything including backed up data) + value: WipeOut + schema: schema/properties/spec/properties/deletionPolicy + type: select + - label: Security Context + schema: schema/properties/spec/properties/runtimeSettings/properties/securityContext + type: input + - elements: + - label: Provider + options: + - text: Azure + value: azure + - text: S3 + value: s3 + - text: GCS + value: gcs + - text: Local + value: local + init: + type: func + value: initBackendProvider + watcher: + func: onBackendProviderChange + paths: + - schema/properties/spec/properties/backend/properties/provider + schema: schema/properties/spec/properties/backend/properties/provider + type: select - elements: - - fetch: getNamespaces - hasGroup: isRancherManaged - label: - text: Namespace - schema: - $ref: schema#/properties/metadata/properties/release/properties/namespace - type: select - - label: - text: Name - schema: - $ref: schema#/properties/metadata/properties/release/properties/name - type: input - elements: - - isArray: true - keys: - label: - text: Key - label: - text: Labels - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: Value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties - type: input - - isArray: true - keys: - label: - text: Key - label: - text: Annotations - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: Value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties - type: input - hideForm: true - label: - text: Labels & Annotations - show_label: true - type: single-step-form - - customClass: mt-20 - label: - text: Deletion Policy - options: - - description: options.deletionPolicy.delete.description - text: Delete (Keep only database Secrets and backed up data) - value: Delete - - description: options.deletionPolicy.wipeOut.description - text: WipeOut (Delete everything including backed up data) - value: WipeOut - schema: - $ref: schema#/properties/spec/properties/deletionPolicy - type: select - - label: - text: Security Context - schema: - $ref: schema#/properties/spec/properties/runtimeSettings/properties/securityContext + - label: Account Key + schema: schema/properties/spec/properties/backend/properties/azure/properties/auth/properties/AZURE_ACCOUNT_KEY + type: input + - label: Account Name + schema: schema/properties/spec/properties/backend/properties/azure/properties/auth/properties/AZURE_ACCOUNT_NAME + type: input + label: Auth + showLabels: true + type: block-layout + - elements: + - label: Container + schema: schema/properties/spec/properties/backend/properties/azure/properties/spec/properties/container + type: input + - label: Max Connections + schema: schema/properties/spec/properties/backend/properties/azure/properties/spec/properties/maxConnections + type: input + - label: Prefix + schema: schema/properties/spec/properties/backend/properties/azure/properties/spec/properties/prefix + type: input + label: Spec + showLabels: true + type: block-layout + if: + type: function + name: isProvider|azure + label: Azure + showLabels: true + type: block-layout + - elements: + - elements: + - label: Google Project ID + schema: schema/properties/spec/properties/backend/properties/gcs/properties/auth/properties/GOOGLE_PROJECT_ID + type: input + - label: Google Service Account JSON Key + schema: schema/properties/spec/properties/backend/properties/gcs/properties/auth/properties/GOOGLE_SERVICE_ACCOUNT_JSON_KEY + type: input + label: Auth + showLabels: true + type: block-layout + - elements: + - label: Bucket + schema: schema/properties/spec/properties/backend/properties/gcs/properties/spec/properties/bucket + type: input + - label: Max Connections + schema: schema/properties/spec/properties/backend/properties/gcs/properties/spec/properties/maxConnections + type: input + - label: Prefix + schema: schema/properties/spec/properties/backend/properties/gcs/properties/spec/properties/prefix + type: input + label: Spec + showLabels: true + type: block-layout + if: + type: function + name: isProvider|gcs + label: GCS + showLabels: true + type: block-layout + - elements: + - elements: + - label: AWS Access Key ID + schema: schema/properties/spec/properties/backend/properties/s3/properties/auth/properties/AWS_ACCESS_KEY_ID + type: input + - label: AWS Secret Access Key + schema: schema/properties/spec/properties/backend/properties/s3/properties/auth/properties/AWS_SECRET_ACCESS_KEY + type: input + - label: CA Cert Data + schema: schema/properties/spec/properties/backend/properties/s3/properties/auth/properties/CA_CERT_DATA + type: textarea + label: Auth + showLabels: true + type: block-layout + - elements: + - label: Insecure TLS + schema: schema/properties/spec/properties/backend/properties/s3/properties/spec/properties/insecureTLS + type: switch + - label: Bucket + schema: schema/properties/spec/properties/backend/properties/s3/properties/spec/properties/bucket + type: input + - label: End Point + schema: schema/properties/spec/properties/backend/properties/s3/properties/spec/properties/endpoint + type: input + - label: Prefix + schema: schema/properties/spec/properties/backend/properties/s3/properties/spec/properties/prefix + type: input + - label: Region + schema: schema/properties/spec/properties/backend/properties/s3/properties/spec/properties/region + type: input + label: Spec + showLabels: true + type: block-layout + if: + type: function + name: isProvider|s3 + label: S3 + showLabels: true + type: block-layout + - elements: + - label: Mount Path + schema: schema/properties/spec/properties/backend/properties/local/properties/mountPath + type: input + - label: Sub Path + schema: schema/properties/spec/properties/backend/properties/local/properties/subPath type: input - elements: - - label: - text: Provider - options: - - text: Azure - value: azure - - text: S3 - value: s3 - - text: GCS - value: gcs - - text: Local - value: local - schema: - $ref: schema#/properties/spec/properties/backend/properties/provider - type: select - - elements: - - elements: - - label: - text: Account Key - schema: - $ref: schema#/properties/spec/properties/backend/properties/azure/properties/auth/properties/AZURE_ACCOUNT_KEY - type: input - - label: - text: Account Name - schema: - $ref: schema#/properties/spec/properties/backend/properties/azure/properties/auth/properties/AZURE_ACCOUNT_NAME - type: input - label: - text: Auth - schema: - $ref: schema#/properties/spec/properties/backend/properties/azure/properties/auth - show_label: true - type: single-step-form - - elements: - - label: - text: Container - schema: - $ref: schema#/properties/spec/properties/backend/properties/azure/properties/spec/properties/container - type: input - - label: - text: Max Connections - schema: - $ref: schema#/properties/spec/properties/backend/properties/azure/properties/spec/properties/maxConnections - type: input - - label: - text: Prefix - schema: - $ref: schema#/properties/spec/properties/backend/properties/azure/properties/spec/properties/prefix - type: input - label: - text: Spec - schema: - $ref: schema#/properties/spec/properties/backend/properties/azure/properties/spec - show_label: true - type: single-step-form - if: isProvider|azure - label: - text: Azure - schema: - $ref: schema#/properties/spec/properties/backend/properties/azure - show_label: true - type: single-step-form - - elements: - - elements: - - label: - text: Google Project ID - schema: - $ref: schema#/properties/spec/properties/backend/properties/gcs/properties/auth/properties/GOOGLE_PROJECT_ID - type: input - - label: - text: Google Service Account JSON Key - schema: - $ref: schema#/properties/spec/properties/backend/properties/gcs/properties/auth/properties/GOOGLE_SERVICE_ACCOUNT_JSON_KEY - type: input - label: - text: Auth - schema: - $ref: schema#/properties/spec/properties/backend/properties/gcs/properties/auth - show_label: true - type: single-step-form - - elements: - - label: - text: Bucket - schema: - $ref: schema#/properties/spec/properties/backend/properties/gcs/properties/spec/properties/bucket - type: input - - label: - text: Max Connections - schema: - $ref: schema#/properties/spec/properties/backend/properties/gcs/properties/spec/properties/maxConnections - type: input - - label: - text: Prefix - schema: - $ref: schema#/properties/spec/properties/backend/properties/gcs/properties/spec/properties/prefix - type: input - label: - text: Spec - schema: - $ref: schema#/properties/spec/properties/backend/properties/gcs/properties/spec - show_label: true - type: single-step-form - if: isProvider|gcs - label: - text: GCS - schema: - $ref: schema#/properties/spec/properties/backend/properties/gcs - show_label: true - type: single-step-form - - elements: - - elements: - - label: - text: AWS Access Key ID - schema: - $ref: schema#/properties/spec/properties/backend/properties/s3/properties/auth/properties/AWS_ACCESS_KEY_ID - type: input - - label: - text: AWS Secret Access Key - schema: - $ref: schema#/properties/spec/properties/backend/properties/s3/properties/auth/properties/AWS_SECRET_ACCESS_KEY - type: input - - label: - text: CA Cert Data - schema: - $ref: schema#/properties/spec/properties/backend/properties/s3/properties/auth/properties/CA_CERT_DATA - type: textarea - label: - text: Auth - schema: - $ref: schema#/properties/spec/properties/backend/properties/s3/properties/auth - show_label: true - type: single-step-form - - elements: - - label: - text: Insecure TLS - schema: - $ref: schema#/properties/spec/properties/backend/properties/s3/properties/spec/properties/insecureTLS - type: switch - - label: - text: Bucket - schema: - $ref: schema#/properties/spec/properties/backend/properties/s3/properties/spec/properties/bucket - type: input - - label: - text: End Point - schema: - $ref: schema#/properties/spec/properties/backend/properties/s3/properties/spec/properties/endpoint - type: input - - label: - text: Prefix - schema: - $ref: schema#/properties/spec/properties/backend/properties/s3/properties/spec/properties/prefix - type: input - - label: - text: Region - schema: - $ref: schema#/properties/spec/properties/backend/properties/s3/properties/spec/properties/region - type: input - label: - text: Spec - schema: - $ref: schema#/properties/spec/properties/backend/properties/s3/properties/spec - show_label: true - type: single-step-form - if: isProvider|s3 - label: - text: S3 - schema: - $ref: schema#/properties/spec/properties/backend/properties/s3 - show_label: true - type: single-step-form - - elements: - - label: - text: Mount Path - schema: - $ref: schema#/properties/spec/properties/backend/properties/local/properties/mountPath - type: input - - label: - text: Sub Path - schema: - $ref: schema#/properties/spec/properties/backend/properties/local/properties/subPath - type: input - - elements: - - label: - text: claim Name - schema: - $ref: schema#/properties/spec/properties/backend/properties/local/properties/persistentVolumeClaim/properties/claimName - type: input - - label: - text: ReadOnly? - schema: - $ref: schema#/properties/spec/properties/backend/properties/local/properties/persistentVolumeClaim/properties/readOnly - type: switch - label: - text: Persistent Volume Claim - schema: - $ref: schema#/properties/spec/properties/backend/properties/local/properties/persistentVolumeClaim - show_label: true - type: single-step-form - if: isProvider|local - label: - text: Local - schema: - $ref: schema#/properties/spec/properties/backend/properties/local - show_label: true - type: single-step-form - label: - text: Backend - show_label: true - type: single-step-form - schema: - $ref: schema#/properties/spec - type: single-step-form - type: single-step-form + - label: claim Name + schema: schema/properties/spec/properties/backend/properties/local/properties/persistentVolumeClaim/properties/claimName + type: input + - label: ReadOnly? + schema: schema/properties/spec/properties/backend/properties/local/properties/persistentVolumeClaim/properties/readOnly + type: switch + label: Persistent Volume Claim + showLabels: true + type: block-layout + if: + type: function + name: isProvider|local + label: Local + showLabels: true + type: block-layout + label: Backend + showLabels: true + type: block-layout id: options - title: steps.0.label + # title: steps.0.label type: multi-step-form diff --git a/charts/storagekubestashcom-backupstorage-editor-options/ui/functions.js b/charts/storagekubestashcom-backupstorage-editor-options/ui/functions.js index 6e10409e34..f00073e8d2 100644 --- a/charts/storagekubestashcom-backupstorage-editor-options/ui/functions.js +++ b/charts/storagekubestashcom-backupstorage-editor-options/ui/functions.js @@ -1,140 +1,4 @@ -async function getResources( - { axios, storeGet, model, getValue, watchDependency }, - group, - version, - resource, - namespaced, -) { - const owner = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') - let namespace = '' - if (namespaced) { - namespace = getValue(model, '/metadata/release/namespace') - watchDependency('model#/metadata/release/namespace') - } - - if (!namespaced || namespace) { - // call api if resource is either not namespaced - // or namespaced and user has selected a namespace - try { - const resp = await axios.get( - `/clusters/${owner}/${cluster}/proxy/${group}/${version}${ - namespace ? '/namespaces/' + namespace : '' - }/${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 [] - } - } else return [] -} - -function initNamespace({ route }) { - const { namespace } = route.query || {} - return namespace || null -} -function isNamespaceDisabled({ route }) { - return !!initNamespace({ route }) || !isVariantAvailable -} - -function labelsDisabilityChecker({ itemCtx }) { - const { key } = itemCtx - if (key.startsWith('app.kubernetes.io') || key.includes('helm')) return true - else return false -} - -async function fetchJsons({ axios, itemCtx, setDiscriminatorValue }, discriminatorPath) { - 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) - } - - if (discriminatorPath) { - setDiscriminatorValue(discriminatorPath, { - ui: ui.data || {}, - language: language.data || {}, - functions, - }) - } - - return { - ui: ui.data || {}, - language: language.data || {}, - functions, - } -} - -function showExistingSecretSelection({ discriminator, getValue, watchDependency }) { - const useExistingAuthSecret = getValue(discriminator, '/useExistingAuthSecret') - const isExistingAuthSecretsFetching = getValue(discriminator, '/isExistingAuthSecretsFetching') - watchDependency('discriminator#/useExistingAuthSecret') - watchDependency('discriminator#/isExistingAuthSecretsFetching') - - return !isExistingAuthSecretsFetching && useExistingAuthSecret -} - -function onChoiseChange({ discriminator, getValue, commit }) { - const useExistingAuthSecret = getValue(discriminator, '/useExistingAuthSecret') - // remove spec.storageSecret - commit('wizard/model$delete', '/spec/storageSecret') - if (useExistingAuthSecret) { - // remove the auth from each backend - Object.keys(backendMap).forEach((backend) => { - commit('wizard/model$delete', `/spec/backend/${backend}/auth`) - }) - } -} - -async function initExistingAuthSecrets(ctx) { - ctx.setDiscriminatorValue('/isExistingAuthSecretsFetching', true) - const secrets = await getResources(ctx, 'core', 'v1', 'secrets', true) - // set secrets; - ctx.setDiscriminatorValue('/existingAuthSecrets', secrets) - ctx.setDiscriminatorValue('/isExistingAuthSecretsFetching', false) - - return true -} - -async function getExistingAuthSecrets({ discriminator, getValue, watchDependency }) { - const existingAuthSecrets = getValue(discriminator, '/existingAuthSecrets') - watchDependency('discriminator#/existingAuthSecrets') - return existingAuthSecrets -} - -function showCreateSecretForm({ discriminator, getValue, watchDependency }) { - const useExistingAuthSecret = getValue(discriminator, '/useExistingAuthSecret') - watchDependency('discriminator#/useExistingAuthSecret') - return !useExistingAuthSecret -} +const { ref, computed, axios, watch, useOperator, store } = window.vueHelpers || {} // backend configuration const backendMap = { @@ -179,144 +43,290 @@ const backendMap = { }, } -function initBackendProvider({ model, getValue }) { - const backend = getValue(model, '/spec/backend') - const selectedBackend = Object.keys(backendMap).find((key) => { - const value = backend && backend[key] +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) + + setDiscriminatorValue('useExistingAuthSecret', false) + setDiscriminatorValue('isExistingAuthSecretsFetching', false) + setDiscriminatorValue('existingAuthSecrets', []) + + async function getResources(group, version, resource, namespaced) { + const owner = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') + let namespace = '' + if (namespaced) { + namespace = getValue(model, '/metadata/release/namespace') + // watchDependency('model#/metadata/release/namespace') + } - return value ? true : false - }) - return selectedBackend || 'gcs' -} + if (!namespaced || namespace) { + // call api if resource is either not namespaced + // or namespaced and user has selected a namespace + try { + const resp = await axios.get( + `/clusters/${owner}/${cluster}/proxy/${group}/${version}${ + namespace ? '/namespaces/' + namespace : '' + }/${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 [] + } + } else return [] + } -function valueExists(value, getValue, path) { - const val = getValue(value, path) - if (val) return true - else return false -} + function initNamespace() { + const route = storeGet('/route') + const { namespace } = route.query || {} + return namespace || null + } + + function isNamespaceDisabled() { + const route = storeGet('/route') + return !!initNamespace() || !isVariantAvailable() + } + + function labelsDisabilityChecker(key) { + if (key.startsWith('app.kubernetes.io') || key.includes('helm')) return true + else return false + } + + async function fetchJsons(discriminatorPath) { + let ui = {} + let language = {} + let functions = {} + const itemCtx = storeGet('/itemCtx') + 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) + } -function onBackendProviderChange({ commit, getValue, model }) { - const selectedBackendProvider = getValue(model, '/spec/backend/provider') + if (discriminatorPath) { + setDiscriminatorValue(discriminatorPath, { + ui: ui.data || {}, + language: language.data || {}, + functions, + }) + } - // delete every other backend type from model exect the selected one - Object.keys(backendMap).forEach((key) => { - if (key !== selectedBackendProvider) { - commit('wizard/model$delete', `/spec/backend/${key}`) + return { + ui: ui.data || {}, + language: language.data || {}, + functions, } - }) + } - // set the selectedBackend type object in + function showExistingSecretSelection() { + const useExistingAuthSecret = getValue(discriminator, '/useExistingAuthSecret') + const isExistingAuthSecretsFetching = getValue(discriminator, '/isExistingAuthSecretsFetching') + // watchDependency('discriminator#/useExistingAuthSecret') + // watchDependency('discriminator#/isExistingAuthSecretsFetching') + + return !isExistingAuthSecretsFetching && useExistingAuthSecret + } - if (!valueExists(model, getValue, `/${selectedBackendProvider}`)) { - commit('wizard/model$update', { - path: `/spec/backend/${selectedBackendProvider}`, - value: {}, - force: true, + function onChoiseChange() { + const useExistingAuthSecret = getValue(discriminator, '/useExistingAuthSecret') + // remove spec.storageSecret + commit('wizard/model$delete', '/spec/storageSecret') + if (useExistingAuthSecret) { + // remove the auth from each backend + Object.keys(backendMap).forEach((backend) => { + commit('wizard/model$delete', `/spec/backend/${backend}/auth`) + }) + } + } + + async function initExistingAuthSecrets() { + setDiscriminatorValue('/isExistingAuthSecretsFetching', true) + const secrets = await getResources('core', 'v1', 'secrets', true) + // set secrets; + setDiscriminatorValue('/existingAuthSecrets', secrets) + setDiscriminatorValue('/isExistingAuthSecretsFetching', false) + + return true + } + + async function getExistingAuthSecrets() { + const existingAuthSecrets = getValue(discriminator, '/existingAuthSecrets') + // watchDependency('discriminator#/existingAuthSecrets') + return existingAuthSecrets + } + + function showCreateSecretForm() { + const useExistingAuthSecret = getValue(discriminator, '/useExistingAuthSecret') + // watchDependency('discriminator#/useExistingAuthSecret') + return !useExistingAuthSecret + } + + function initBackendProvider() { + const backend = getValue(model, '/spec/backend') + const selectedBackend = Object.keys(backendMap).find((key) => { + const value = backend && backend[key] + + return value ? true : false }) + return selectedBackend || 'gcs' } -} -function showBackendForm({ getValue, model, watchDependency }, value) { - const backendProvider = getValue(model, '/spec/backend/provider') - watchDependency('model#/spec/backend/provider') - return backendProvider === value -} + function valueExists(value, path) { + const val = getValue(value, path) + if (val) return true + else return false + } -function showSecretForm({ model, getValue, watchDependency }, value) { - const backendProvider = getValue(model, '/spec/backend/provider') - watchDependency('model#/spec/backend/provider') - return backendProvider === value -} + function onBackendProviderChange() { + const selectedBackendProvider = getValue(model, '/spec/backend/provider') -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + // delete every other backend type from model exect the selected one + Object.keys(backendMap).forEach((key) => { + if (key !== selectedBackendProvider) { + commit('wizard/model$delete', `/spec/backend/${key}`) + } + }) - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + // set the selectedBackend type object in + + if (!valueExists(model, `/${selectedBackendProvider}`)) { + commit('wizard/model$update', { + path: `/spec/backend/${selectedBackendProvider}`, + value: {}, + force: true, + }) + } } -} -function isVariantAvailable({ storeGet }) { - const variant = storeGet('/route/query/variant') - return variant ? true : false -} + function showBackendForm(value) { + const backendProvider = getValue(model, '/spec/backend/provider') + // watchDependency('model#/spec/backend/provider') + return backendProvider === value + } -async function getNamespaces({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], - }, - }, - ) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace + function showSecretForm(value) { + const backendProvider = getValue(model, '/spec/backend/provider') + // watchDependency('model#/spec/backend/provider') + return backendProvider === value + } + + function getCreateNameSpaceUrl() { + 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/${user}/kubernetes/${cluster}/core/v1/namespaces/create` } else { - return resp.data?.status?.namespaces || [] + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` } - } catch (e) { - console.log(e) } - return [] -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + function isVariantAvailable() { + const variant = storeGet('/route/query/variant') + return variant ? true : false + } -function isProvider({ watchDependency, model, getValue }, type) { - watchDependency('model#/spec/backend/provider') - const Provider = getValue(model, '/spec/backend/provider') - return type === Provider -} + async function getNamespaces() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, + }, + ) + if (resp.data?.status?.projects) { + const projects = resp.data?.status?.projects + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } + } catch (e) { + console.log(e) + } + return [] + } + + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } -return { - isRancherManaged, - isProvider, - getNamespaces, - isVariantAvailable, - getResources, - initNamespace, - isNamespaceDisabled, - labelsDisabilityChecker, - fetchJsons, - showExistingSecretSelection, - initExistingAuthSecrets, - onChoiseChange, - getExistingAuthSecrets, - showCreateSecretForm, - initBackendProvider, - onBackendProviderChange, - showBackendForm, - showSecretForm, - getCreateNameSpaceUrl, + function isProvider(type) { + // watchDependency('model#/spec/backend/provider') + const Provider = getValue(model, '/spec/backend/provider') + return type === Provider + } + + return { + isRancherManaged, + isProvider, + getNamespaces, + isVariantAvailable, + getResources, + initNamespace, + isNamespaceDisabled, + labelsDisabilityChecker, + fetchJsons, + showExistingSecretSelection, + initExistingAuthSecrets, + onChoiseChange, + getExistingAuthSecrets, + showCreateSecretForm, + initBackendProvider, + onBackendProviderChange, + showBackendForm, + showSecretForm, + getCreateNameSpaceUrl, + } } diff --git a/charts/storagekubestashcom-repository-editor-options/ui/create-ui.yaml b/charts/storagekubestashcom-repository-editor-options/ui/create-ui.yaml index 4dbb2a9289..ccfd9931af 100644 --- a/charts/storagekubestashcom-repository-editor-options/ui/create-ui.yaml +++ b/charts/storagekubestashcom-repository-editor-options/ui/create-ui.yaml @@ -1,169 +1,123 @@ -steps: -- form: - discriminator: - nameSpaceApi: - default: false - type: boolean - elements: - - computed: init - if: returnFalse - type: input - - elements: - - fetch: getNamespacesApi - hasGroup: isRancherManaged - label: - text: labels.namespace - schema: - $ref: schema#/properties/metadata/properties/release/properties/namespace - type: select - - label: - text: labels.repository.name - schema: - $ref: schema#/properties/metadata/properties/release/properties/name - type: input - schema: - $ref: schema#/properties/metadata/properties/release - type: single-step-form - - discriminator: - existingAuthSecrets: - default: [] - type: Array - isExistingAuthSecretsFetching: - default: true - type: boolean - useExistingAuthSecret: - default: true - type: boolean - elements: - - isArray: true - keys: - label: - text: labels.key - label: - text: labels.repository.labels - schema: - $ref: schema#/properties/spec/properties/labels - type: key-value-input-form - values: - label: - text: labels.value - schema: - $ref: schema#/properties/spec/properties/labels/additionalProperties - type: input - - isArray: true - keys: - label: - text: labels.key - label: - text: labels.repository.annotations - schema: - $ref: schema#/properties/spec/properties/annotations - type: key-value-input-form - values: - label: - text: labels.value - schema: - $ref: schema#/properties/spec/properties/annotations/additionalProperties - type: input - - label: - text: Deletion Policy - options: - - Delete - - WipeOut - schema: - $ref: schema#/properties/spec/properties/deletionPolicy - type: select - - elements: - - disableUnselect: true - fetch: fetchNamespaces - hasGroup: isRancherManaged - label: - text: labels.namespace - refresh: true - schema: - $ref: schema#/properties/spec/properties/storageRef/properties/namespace - type: select - - disableUnselect: true - fetch: fetchNames|storageRef - label: - text: labels.name - refresh: true - schema: - $ref: schema#/properties/spec/properties/storageRef/properties/name - type: select - label: - text: labels.storageRef - schema: - $ref: schema#/properties/spec/properties/storageRef - show_label: true - type: single-step-form - - elements: - - disableUnselect: true - fetch: fetchNamespaces - hasGroup: isRancherManaged - label: - text: labels.namespace - refresh: true - schema: - $ref: schema#/properties/spec/properties/encryptionSecret/properties/namespace - type: select - - disableUnselect: true - fetch: fetchNames|encryptionSecret - label: - text: labels.name - refresh: true - schema: - $ref: schema#/properties/spec/properties/encryptionSecret/properties/name - type: select - label: - text: labels.encryptionSecret - schema: - $ref: schema#/properties/spec/properties/encryptionSecret - show_label: true - type: single-step-form - - label: - text: Path - schema: - $ref: schema#/properties/spec/properties/path - type: input - - elements: - - fetch: getApiGroup - label: - text: Api Group - schema: - $ref: schema#/properties/spec/properties/appRef/properties/apiGroup - type: select - - fetch: getKinds - label: - text: Kind - onChange: setVersion - schema: - $ref: schema#/properties/spec/properties/appRef/properties/kind - sortable: true - type: select - - fetch: fetchNamespaces - hasGroup: isRancherManaged - label: - text: Namespace - schema: - $ref: schema#/properties/spec/properties/appRef/properties/namespace - type: select - - fetch: getTargetName - label: - text: Name - schema: - $ref: schema#/properties/spec/properties/appRef/properties/name - type: select - label: - text: App Ref - schema: - $ref: schema#/properties/spec/properties/appRef - show_label: true - type: single-step-form - schema: - $ref: schema#/properties/spec - type: single-step-form - type: single-step-form +step: +- type: single-step-form + loader: init + elements: + - loader: getNamespacesApi + hasGroup: isRancherManaged + label: Namespace + schema: schema/properties/metadata/properties/release/properties/namespace + type: select + - label: Repository Name + schema: schema/properties/metadata/properties/release/properties/name + type: input + - elements: + - type: object-item + label: Labels + schema: schema/properties/spec/properties/labels + - type: object-item + label: Annotations + schema: schema/properties/spec/properties/annotations + label: Labels & Annotations + showLabels: true + hideBlock: true + type: block-layout + - label: Deletion Policy + customClass: mt-10 + options: + - Delete + - WipeOut + schema: schema/properties/spec/properties/deletionPolicy + type: select + - elements: + - disableUnselect: true + loader: fetchNamespaces + hasGroup: isRancherManaged + label: Namespace + refresh: true + watcher: + func: onStorageRefNamespaceChange + paths: + - schema/properties/spec/properties/storageRef/properties/namespace + schema: schema/properties/spec/properties/storageRef/properties/namespace + type: select + - disableUnselect: true + loader: + name: fetchNames|storageRef + watchPaths: + - schema/properties/spec/properties/storageRef/properties/namespace + label: Name + refresh: true + schema: schema/properties/spec/properties/storageRef/properties/name + type: select + label: Storage Ref + showLabels: true + type: block-layout + - elements: + - disableUnselect: true + loader: fetchNamespaces + hasGroup: isRancherManaged + label: Namespace + refresh: true + watcher: + func: onEncryptionSecretNamespaceChange + paths: + - schema/properties/spec/properties/encryptionSecret/properties/namespace + schema: schema/properties/spec/properties/encryptionSecret/properties/namespace + type: select + - disableUnselect: true + loader: + name: fetchNames|encryptionSecret + watchPaths: + - schema/properties/spec/properties/encryptionSecret/properties/namespace + label: Name + refresh: true + schema: schema/properties/spec/properties/encryptionSecret/properties/name + type: select + label: Encryption Secret + showLabels: true + type: block-layout + - label: Path + schema: schema/properties/spec/properties/path + type: input + - elements: + - loader: getApiGroup + label: Api Group + watcher: + func: onApiGroupChange + paths: + - schema/properties/spec/properties/appRef/properties/apiGroup + schema: schema/properties/spec/properties/appRef/properties/apiGroup + type: select + - loader: + name: getKinds + watchPaths: + - schema/properties/spec/properties/appRef/properties/apiGroup + label: Kind + watcher: + func: setVersion + paths: + - schema/properties/spec/properties/appRef/properties/kind + schema: schema/properties/spec/properties/appRef/properties/kind + type: select + - loader: fetchNamespaces + hasGroup: isRancherManaged + label: Namespace + watcher: + func: onAppRefNamespaceChange + paths: + - schema/properties/spec/properties/appRef/properties/namespace + schema: schema/properties/spec/properties/appRef/properties/namespace + type: select + - loader: + name: getTargetName + watchPaths: + - schema/properties/spec/properties/appRef/properties/kind + - schema/properties/spec/properties/appRef/properties/namespace + label: Name + schema: schema/properties/spec/properties/appRef/properties/name + type: select + label: App Ref + showLabels: true + type: block-layout id: options - title: steps.0.label type: multi-step-form diff --git a/charts/storagekubestashcom-repository-editor-options/ui/functions.js b/charts/storagekubestashcom-repository-editor-options/ui/functions.js index 01c87284b4..61d9e85fc4 100644 --- a/charts/storagekubestashcom-repository-editor-options/ui/functions.js +++ b/charts/storagekubestashcom-repository-editor-options/ui/functions.js @@ -1,3 +1,5 @@ +const { axios, store, useOperator } = window.vueHelpers || {} + let namespaces = [] let appKind = [] let coreKind = [] @@ -6,237 +8,303 @@ let availableKinds = {} let kindToResourceMap = {} let version = '' -function init({ watchDependency, model, getValue, storeGet, axios, setDiscriminatorValue }) { - namespaces = getNamespacesApi({ axios, storeGet }) - getKindsApi({ watchDependency, model, getValue, storeGet, axios }) - setDiscriminatorValue('/nameSpaceApi', true) -} +export const useFunc = (model) => { + const { getValue, setDiscriminatorValue, commit, storeGet, discriminator } = useOperator( + model, + store.state, + ) -function getKinds({ watchDependency, getValue, model }) { - watchDependency(`model#/spec/appRef/apiGroup`) - const apiGroup = getValue(model, `/spec/appRef/apiGroup`) - console.log(apiGroup) + setDiscriminatorValue('nameSpaceApi', false) + setDiscriminatorValue('existingAuthSecrets', []) + setDiscriminatorValue('isExistingAuthSecretsFetching', true) + setDiscriminatorValue('useExistingAuthSecret', true) - if (apiGroup === 'core') return coreKind - else if (apiGroup === 'apps') return appKind - else return kubedbKind -} + async function init() { + namespaces = await getNamespacesApi() + await getKindsApi() + setDiscriminatorValue('/nameSpaceApi', true) + } -function setVersion({ getValue, model }) { - let apiGroup = getValue(model, `/spec/appRef/apiGroup`) - const kind = getValue(model, `/spec/appRef/kind`) - if (apiGroup === 'core') apiGroup = '' - console.log(availableKinds) + function getKinds() { + // watchDependency(`model#/spec/appRef/apiGroup`) + const apiGroup = getValue(model, `/spec/appRef/apiGroup`) - Object.keys(availableKinds[apiGroup]).forEach((vs) => { - availableKinds[apiGroup][vs].forEach((ele) => { - if (ele.Kind === kind) { - version = vs - } - }) - }) -} + if (apiGroup === 'core') return coreKind + else if (apiGroup === 'apps') return appKind + else return kubedbKind + } -async function getKindsApi({ storeGet, axios }) { - const params = storeGet('/route/params') - const { user, cluster } = params - let url = `/clusters/${user}/${cluster}/available-types?groups=core,apps,kubedb.com` - try { - const resp = await axios.get(url) - - kindToResourceMap['kubedb.com'] = {} - kindToResourceMap['apps'] = {} - kindToResourceMap['core'] = {} - - availableKinds = resp.data - appKind = Object.values(availableKinds['apps']) - .flat() - .map((ele) => { - kindToResourceMap['apps'][ele.Kind] = ele.Resource - return ele.Kind - }) - kubedbKind = Object.values(availableKinds['kubedb.com']) - .flat() - .map((ele) => { - kindToResourceMap['kubedb.com'][ele.Kind] = ele.Resource - return ele.Kind - }) - coreKind = Object.values(availableKinds['']) - .flat() - .map((ele) => { - kindToResourceMap['core'][ele.Kind] = ele.Resource - return ele.Kind + function setVersion() { + let apiGroup = getValue(model, `/spec/appRef/apiGroup`) + const kind = getValue(model, `/spec/appRef/kind`) + if (apiGroup === 'core') apiGroup = '' + + Object.keys(availableKinds[apiGroup]).forEach((vs) => { + availableKinds[apiGroup][vs].forEach((ele) => { + if (ele.Kind === kind) { + version = vs + } }) - } catch (e) { - console.log(e) + }) } - return [] -} -function isRancherManaged({ storeGet }) { - const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') - const found = managers.find((item) => item === 'Rancher') - return !!found -} + async function getKindsApi() { + const params = storeGet('/route/params') + const { user, cluster } = params + let url = `/clusters/${user}/${cluster}/available-types?groups=core,apps,kubedb.com` + try { + const resp = await axios.get(url) -function fetchNamespaces({ watchDependency }) { - watchDependency('discriminator#/nameSpaceApi') - return namespaces -} -async function getNamespacesApi({ axios, storeGet }) { - const params = storeGet('/route/params') - const { user, cluster, group, version, resource } = params - try { - const resp = await axios.post( - `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, - { - apiVersion: 'identity.k8s.appscode.com/v1alpha1', - kind: 'SelfSubjectNamespaceAccessReview', - spec: { - resourceAttributes: [ - { - verb: 'create', - group: group, - version: version, - resource: resource, - }, - ], + kindToResourceMap['kubedb.com'] = {} + kindToResourceMap['apps'] = {} + kindToResourceMap['core'] = {} + + availableKinds = resp.data + appKind = Object.values(availableKinds['apps']) + .flat() + .map((ele) => { + kindToResourceMap['apps'][ele.Kind] = ele.Resource + return ele.Kind + }) + kubedbKind = Object.values(availableKinds['kubedb.com']) + .flat() + .map((ele) => { + kindToResourceMap['kubedb.com'][ele.Kind] = ele.Resource + return ele.Kind + }) + coreKind = Object.values(availableKinds['']) + .flat() + .map((ele) => { + kindToResourceMap['core'][ele.Kind] = ele.Resource + return ele.Kind + }) + } catch (e) { + console.log(e) + } + return [] + } + + function isRancherManaged() { + const managers = storeGet('/cluster/clusterDefinition/result/clusterManagers') + const found = managers.find((item) => item === 'Rancher') + return !!found + } + + function fetchNamespaces() { + // watchDependency('discriminator#/nameSpaceApi') + return namespaces + } + + async function getNamespacesApi() { + const params = storeGet('/route/params') + const { user, cluster, group, version, resource } = params + try { + const resp = await axios.post( + `/clusters/${user}/${cluster}/proxy/identity.k8s.appscode.com/v1alpha1/selfsubjectnamespaceaccessreviews`, + { + apiVersion: 'identity.k8s.appscode.com/v1alpha1', + kind: 'SelfSubjectNamespaceAccessReview', + spec: { + resourceAttributes: [ + { + verb: 'create', + group: group, + version: version, + resource: resource, + }, + ], + }, }, - }, - ) - if (resp.data?.status?.projects) { - const projects = resp.data?.status?.projects - let projectsNamespace = [] - projectsNamespace = Object.keys(projects).map((project) => ({ - project: project, - namespaces: projects[project].map((namespace) => ({ - text: namespace, - value: namespace, - })), - })) - return projectsNamespace - } else { - return resp.data?.status?.namespaces || [] + ) + if (resp.data?.status?.projects) { + const projects = resp.data?.status?.projects + let projectsNamespace = [] + projectsNamespace = Object.keys(projects).map((project) => ({ + project: project, + namespaces: projects[project].map((namespace) => ({ + text: namespace, + value: namespace, + })), + })) + return projectsNamespace + } else { + return resp.data?.status?.namespaces || [] + } + } catch (e) { + console.log(e) } - } catch (e) { - console.log(e) + return [] } - return [] -} -async function fetchNames({ getValue, model, storeGet, watchDependency, axios }, type) { - watchDependency(`model#/spec/${type}/namespace`) || '' - const user = storeGet('/route/params/user') || '' - const cluster = storeGet('/route/params/cluster') || '' - const namespace = getValue(model, `/spec/${type}/namespace`) || '' - let suffix = type - if (type === 'encryptionSecret') suffix = 'secrets' - else if (type === 'repository') suffix = 'repositories' - else if (type === 'storageRef') suffix = 'backupstorages' - const core = suffix === 'secrets' ? 'core' : 'storage.kubestash.com' - const version = suffix === 'secrets' ? 'v1' : 'v1alpha1' - const url = `/clusters/${user}/${cluster}/proxy/${core}/${version}/namespaces/${namespace}/${suffix}` - - try { - if (namespace) { - const resp = await axios.get(url) - let names = resp?.data?.items - names.map((item) => { - item.value = item?.metadata?.name || '' - item.text = item?.metadata?.name || '' - return true - }) + async function fetchNames(type) { + // watchDependency(`model#/spec/${type}/namespace`) + const user = storeGet('/route/params/user') || '' + const cluster = storeGet('/route/params/cluster') || '' + const namespace = getValue(model, `/spec/${type}/namespace`) || '' + let suffix = type + if (type === 'encryptionSecret') suffix = 'secrets' + else if (type === 'repository') suffix = 'repositories' + else if (type === 'storageRef') suffix = 'backupstorages' + const core = suffix === 'secrets' ? 'core' : 'storage.kubestash.com' + const version = suffix === 'secrets' ? 'v1' : 'v1alpha1' + const url = `/clusters/${user}/${cluster}/proxy/${core}/${version}/namespaces/${namespace}/${suffix}` - if (type === 'repository') { - const resource = storeGet('/resource/layout/result/resource') || {} - let group = resource?.group || '' - let kind = resource?.kind || '' + try { + if (namespace) { + const resp = await axios.get(url) + let names = resp?.data?.items + names.map((item) => { + item.value = item?.metadata?.name || '' + item.text = item?.metadata?.name || '' + return true + }) - if (isConsole({ storeGet })) { - group = getValue(model, '/spec/appRef/apiGroup') || '' - kind = getValue(model, '/spec/appRef/kind') || '' + if (type === 'repository') { + const resource = storeGet('/resource/layout/result/resource') || {} + let group = resource?.group || '' + let kind = resource?.kind || '' + + if (isConsole()) { + group = getValue(model, '/spec/appRef/apiGroup') || '' + kind = getValue(model, '/spec/appRef/kind') || '' + } + + const filteredRepo = names.filter((item) => { + const appRef = item?.spec?.appRef || {} + return appRef?.apiGroup === group && appRef?.kind === kind + }) + return filteredRepo } + return names + } + } catch (e) { + console.log(e) + } + return [] + } + + function isConsole() { + const urlPrefix = storeGet('/route/params/urlPrefix') || '' + return urlPrefix.includes('console') + } + + function getCreateNameSpaceUrl() { + const user = storeGet('/route/params/user') + const cluster = storeGet('/route/params/cluster') - const filteredRepo = names.filter((item) => { - const appRef = item?.spec?.appRef || {} - return appRef?.apiGroup === group && appRef?.kind === kind + const domain = storeGet('/domain') || '' + if (domain.includes('bb.test')) { + return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } else { + const editedDomain = domain.replace('kubedb', 'console') + return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + } + } + + function getApiGroup() { + return ['core', 'apps', 'kubedb.com'] + } + + async function getTargetName() { + // watchDependency('model#/spec/appRef/apiGroup') + // watchDependency('model#/spec/appRef/namespace') + // watchDependency('model#/spec/appRef/kind') + const apiGroup = getValue(model, `/spec/appRef/apiGroup`) + const namespace = getValue(model, `/spec/appRef/namespace`) + const resource = getResourceName() + const params = storeGet('/route/params') + const { user, cluster } = params + + const url = `/clusters/${user}/${cluster}/proxy/${apiGroup}/${version}/namespaces/${namespace}/${resource}` + if (apiGroup && version && resource && namespace) { + try { + const resp = await axios.get(url) + const items = resp.data?.items + const options = items.map((ele) => { + return ele.metadata.name }) - return filteredRepo + return options + } catch (e) { + console.log(e) } - return names } - } catch (e) { - console.log(e) + return [] } - return [] -} -function getCreateNameSpaceUrl({ model, getValue, storeGet }) { - const user = storeGet('/route/params/user') - const cluster = storeGet('/route/params/cluster') + function getResourceName() { + const apiGroup = getValue(model, `/spec/appRef/apiGroup`) + const kind = getValue(model, `/spec/appRef/kind`) + if (!kind || !apiGroup) return '' + return kindToResourceMap[apiGroup][kind] + } - const domain = storeGet('/domain') || '' - if (domain.includes('bb.test')) { - return `http://console.bb.test:5990/${user}/kubernetes/${cluster}/core/v1/namespaces/create` - } else { - const editedDomain = domain.replace('kubedb', 'console') - return `${editedDomain}/${user}/kubernetes/${cluster}/core/v1/namespaces/create` + function returnFalse() { + return false } -} -function getApiGroup() { - return ['core', 'apps', 'kubedb.com'] -} + function onStorageRefNamespaceChange() { + // Clear the name when namespace changes + commit('wizard/model$update', { + path: '/spec/storageRef/name', + value: '', + force: true, + }) + } -async function getTargetName({ watchDependency, getValue, model, axios, storeGet }) { - watchDependency('model#/spec/appRef/apiGroup') - watchDependency('model#/spec/appRef/namespace') - watchDependency('model#/spec/appRef/kind') - const apiGroup = getValue(model, `/spec/appRef/apiGroup`) - const namespace = getValue(model, `/spec/appRef/namespace`) - const resource = getResourceName({ getValue, model }) - const params = storeGet('/route/params') - const { user, cluster } = params - - const url = `/clusters/${user}/${cluster}/proxy/${apiGroup}/${version}/namespaces/${namespace}/${resource}` - if (apiGroup && version && resource && namespace) { - try { - const resp = await axios.get(url) - const items = resp.data?.items - const options = items.map((ele) => { - return ele.metadata.name - }) - return options - } catch (e) { - console.log(e) - } + function onEncryptionSecretNamespaceChange() { + // Clear the name when namespace changes + commit('wizard/model$update', { + path: '/spec/encryptionSecret/name', + value: '', + force: true, + }) } - return [] -} -function getResourceName({ getValue, model }) { - const apiGroup = getValue(model, `/spec/appRef/apiGroup`) - const kind = getValue(model, `/spec/appRef/kind`) - if (!kind || !apiGroup) return '' - return kindToResourceMap[apiGroup][kind] -} + function onApiGroupChange() { + // Clear kind, namespace, and name when apiGroup changes + commit('wizard/model$update', { + path: '/spec/appRef/kind', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/spec/appRef/namespace', + value: '', + force: true, + }) + commit('wizard/model$update', { + path: '/spec/appRef/name', + value: '', + force: true, + }) + } -function returnFalse() { - return false -} + function onAppRefNamespaceChange() { + // Clear the name when namespace changes + commit('wizard/model$update', { + path: '/spec/appRef/name', + value: '', + force: true, + }) + } -return { - getKindsApi, - getNamespacesApi, - init, - getCreateNameSpaceUrl, - isRancherManaged, - fetchNamespaces, - fetchNames, - getApiGroup, - getTargetName, - getKinds, - getResourceName, - returnFalse, - setVersion, + return { + getKindsApi, + getNamespacesApi, + init, + getCreateNameSpaceUrl, + isRancherManaged, + fetchNamespaces, + fetchNames, + getApiGroup, + getTargetName, + getKinds, + getResourceName, + returnFalse, + setVersion, + onStorageRefNamespaceChange, + onEncryptionSecretNamespaceChange, + onApiGroupChange, + onAppRefNamespaceChange, + } } diff --git a/schemas/ui-schema.json b/schemas/ui-schema.json index 04472dee3d..3176b085f8 100644 --- a/schemas/ui-schema.json +++ b/schemas/ui-schema.json @@ -1,4745 +1,1786 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", - "$ref": "#/definitions/UiInterface", - "definitions": { - "UiInterface": { - "anyOf": [ - { - "$ref": "#/definitions/MultiStepFormInterface" - }, - { - "$ref": "#/definitions/SingleStepFormInterface" - }, - { - "$ref": "#/definitions/FormElementType" - } - ] + "$ref": "#/definitions/FormType", + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "AllElement": { + "anyOf": [ + { + "$ref": "#/definitions/BaseElement" }, - "MultiStepFormInterface": { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "multi-step-form" - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "properties": { - "title": { - "type": "string" - }, - "id": { - "type": "string" - }, - "if": { - "type": "string" - }, - "form": { - "anyOf": [ - { - "$ref": "#/definitions/MultiStepFormInterface" - }, - { - "$ref": "#/definitions/SingleStepFormInterface" - } - ] - } - }, - "required": [ - "title", - "id", - "form" - ], - "additionalProperties": false - } - } - }, - "required": [ - "type", - "steps" - ], - "additionalProperties": false - }, - "SingleStepFormInterface": { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "single-step-form" - }, + { + "$ref": "#/definitions/DerivedElement" + }, + { + "$ref": "#/definitions/LayoutElement" + } + ] + }, + "Anchor": { + "additionalProperties": false, + "properties": { + "customClass": { + "type": "string" + }, + "description": { + "type": "string" + }, + "disable": { + "type": ["boolean", "string"] + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "schema": { + "type": "string" + }, + "subtitle": { + "type": "string" + }, + "type": { + "const": "anchor", + "type": "string" + }, + "validation": { + "$ref": "#/definitions/Validation" + }, + "watcher": { + "$ref": "#/definitions/Watchers" + } + }, + "required": ["label", "schema", "type"], + "type": "object" + }, + "ArrayItem": { + "additionalProperties": false, + "properties": { + "buttonClass": { + "type": "string" + }, + "customClass": { + "type": "string" + }, + "description": { + "type": "string" + }, + "disable": { + "type": ["boolean", "string"] + }, + "element": { + "additionalProperties": false, + "properties": { + "addNewButton": { + "additionalProperties": false, + "properties": { "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } - }, - "additionalProperties": false + "type": "string" }, - "customClass": { - "type": "string" + "target": { + "type": "string" }, - "schema": { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } + "url": { + "anyOf": [ + { + "type": "string" }, - "required": [ - "$ref" - ], - "additionalProperties": false - }, - "disabled": { - "type": [ - "boolean", - "string" - ] - }, - "required": { - "type": [ - "boolean", - "string" - ] - }, - "if": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - }, - "expression": { - "type": "string" - } - }, - "required": [ - "params", - "expression" - ], - "additionalProperties": false - } - ] - }, - "fetch": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "function": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - } - }, - "additionalProperties": false - } - ] - }, - "computed": { - "type": "string" - }, - "individualItemDisabilityCheck": { - "type": "string" - }, - "onChange": { - "type": "string" - }, - "encoder": { - "type": "string" - }, - "decoder": { - "type": "string" - }, - "keepEmpty": { - "type": "boolean" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "text": { - "type": "string" - } - }, - "required": [ - "text" - ], - "additionalProperties": false + { + "additionalProperties": false, + "properties": { + "function": { + "type": "string" } - ] - }, - "identifier": { - "type": "string" - }, - "show_label": { - "type": "boolean" - }, - "hideForm": { - "type": "boolean" - }, - "accordion": { - "type": "boolean" - }, - "elements": { - "type": "array", - "items": { - "$ref": "#/definitions/FormElementType" - } - }, - "discriminator": { - "type": "object", - "additionalProperties": {} - }, - "style": { - "type": "object", - "additionalProperties": { - "type": "string" + }, + "required": ["function"], + "type": "object" } - }, - "toggleOption": { - "$ref": "#/definitions/ToggleOption" + ] } + }, + "required": ["label", "url"], + "type": "object" }, - "required": [ - "elements", - "type" - ], - "additionalProperties": false - }, - "FormElementType": { - "anyOf": [ - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "label-element" - }, - "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } - }, - "additionalProperties": false - }, - "customClass": { - "type": "string" - }, - "schema": { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - }, - "disabled": { - "type": [ - "boolean", - "string" - ] - }, - "required": { - "type": [ - "boolean", - "string" - ] - }, - "if": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - }, - "expression": { - "type": "string" - } - }, - "required": [ - "params", - "expression" - ], - "additionalProperties": false - } - ] - }, - "fetch": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "function": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - } - }, - "additionalProperties": false - } - ] - }, - "computed": { - "type": "string" - }, - "individualItemDisabilityCheck": { - "type": "string" - }, - "onChange": { - "type": "string" - }, - "encoder": { - "type": "string" - }, - "decoder": { - "type": "string" - }, - "keepEmpty": { - "type": "boolean" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "text": { - "type": "string" - } - }, - "required": [ - "text" - ], - "additionalProperties": false - } - ] - }, - "alertInfo": { - "type": "object", - "properties": { - "show": { - "type": "boolean" - }, - "type": { - "type": "string", - "enum": [ - "success", - "info", - "error", - "neutral" - ] - }, - "hideIcon": { - "type": "boolean" - }, - "actionButton": { - "type": "object", - "properties": { - "show": { - "type": "boolean" - }, - "title": { - "type": "string" - }, - "iconClass": { - "type": "string" - }, - "action": {} - }, - "required": [ - "show", - "title", - "iconClass", - "action" - ], - "additionalProperties": false - } - }, - "required": [ - "type" - ], - "additionalProperties": false - } - }, - "additionalProperties": false, - "required": [ - "type" - ] - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "tabs" - }, - "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } - }, - "additionalProperties": false - }, - "customClass": { - "type": "string" - }, - "schema": { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - }, - "disabled": { - "type": [ - "boolean", - "string" - ] - }, - "required": { - "type": [ - "boolean", - "string" - ] - }, - "if": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - }, - "expression": { - "type": "string" - } - }, - "required": [ - "params", - "expression" - ], - "additionalProperties": false - } - ] - }, - "fetch": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "function": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - } - }, - "additionalProperties": false - } - ] - }, - "computed": { - "type": "string" - }, - "individualItemDisabilityCheck": { - "type": "string" - }, - "onChange": { - "type": "string" - }, - "encoder": { - "type": "string" - }, - "decoder": { - "type": "string" - }, - "keepEmpty": { - "type": "boolean" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "text": { - "type": "string" - } - }, - "required": [ - "text" - ], - "additionalProperties": false - } - ] - }, - "tabs": { - "type": "array", - "items": { - "type": "object", - "properties": { - "value": { - "type": [ - "string", - "number", - "boolean" - ] - }, - "title": { - "type": "string" - } - }, - "required": [ - "value", - "title" - ], - "additionalProperties": false - } - } - }, - "required": [ - "tabs", - "type" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "anchor" - }, - "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } - }, - "additionalProperties": false - }, - "customClass": { - "type": "string" - }, - "schema": { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - }, - "disabled": { - "type": [ - "boolean", - "string" - ] - }, - "required": { - "type": [ - "boolean", - "string" - ] - }, - "if": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - }, - "expression": { - "type": "string" - } - }, - "required": [ - "params", - "expression" - ], - "additionalProperties": false - } - ] - }, - "fetch": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "function": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - } - }, - "additionalProperties": false - } - ] - }, - "computed": { - "type": "string" - }, - "individualItemDisabilityCheck": { - "type": "string" - }, - "onChange": { - "type": "string" - }, - "encoder": { - "type": "string" - }, - "decoder": { - "type": "string" - }, - "keepEmpty": { - "type": "boolean" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "text": { - "type": "string" - } - }, - "required": [ - "text" - ], - "additionalProperties": false - } - ] - }, - "target": { - "type": "string" - }, - "url": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "function": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - } - }, - "additionalProperties": false - } - }, - "required": [ - "type", - "url" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "input" - }, - "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } - }, - "additionalProperties": false - }, - "customClass": { - "type": "string" - }, - "schema": { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - }, - "disabled": { - "type": [ - "boolean", - "string" - ] - }, - "required": { - "type": [ - "boolean", - "string" - ] - }, - "if": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - }, - "expression": { - "type": "string" - } - }, - "required": [ - "params", - "expression" - ], - "additionalProperties": false - } - ] - }, - "fetch": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "function": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - } - }, - "additionalProperties": false - } - ] - }, - "computed": { - "type": "string" - }, - "individualItemDisabilityCheck": { - "type": "string" - }, - "onChange": { - "type": "string" - }, - "encoder": { - "type": "string" - }, - "decoder": { - "type": "string" - }, - "keepEmpty": { - "type": "boolean" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "text": { - "type": "string" - } - }, - "required": [ - "text" - ], - "additionalProperties": false - } - ] - }, - "hideValue": { - "type": "boolean" - }, - "inputType": { - "type": "string" - }, - "showPasswordStrength": { - "type": "boolean" - }, - "minValue": { - "type": "number" - }, - "maxValue": { - "type": "number" - }, - "validationRuleObject": { - "type": "object", - "additionalProperties": {} - } - }, - "additionalProperties": false, - "required": [ - "type" - ] - }, - { - "$ref": "#/definitions/TimeInputInterface" - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "textarea" - }, - "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } - }, - "additionalProperties": false - }, - "customClass": { - "type": "string" - }, - "schema": { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - }, - "disabled": { - "type": [ - "boolean", - "string" - ] - }, - "required": { - "type": [ - "boolean", - "string" - ] - }, - "if": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - }, - "expression": { - "type": "string" - } - }, - "required": [ - "params", - "expression" - ], - "additionalProperties": false - } - ] - }, - "fetch": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "function": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - } - }, - "additionalProperties": false - } - ] - }, - "computed": { - "type": "string" - }, - "individualItemDisabilityCheck": { - "type": "string" - }, - "onChange": { - "type": "string" - }, - "encoder": { - "type": "string" - }, - "decoder": { - "type": "string" - }, - "keepEmpty": { - "type": "boolean" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "text": { - "type": "string" - } - }, - "required": [ - "text" - ], - "additionalProperties": false - } - ] - } - }, - "required": [ - "type" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "editor" - }, - "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } - }, - "additionalProperties": false - }, - "customClass": { - "type": "string" - }, - "schema": { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - }, - "disabled": { - "type": [ - "boolean", - "string" - ] - }, - "required": { - "type": [ - "boolean", - "string" - ] - }, - "if": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - }, - "expression": { - "type": "string" - } - }, - "required": [ - "params", - "expression" - ], - "additionalProperties": false - } - ] - }, - "fetch": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "function": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - } - }, - "additionalProperties": false - } - ] - }, - "computed": { - "type": "string" - }, - "individualItemDisabilityCheck": { - "type": "string" - }, - "onChange": { - "type": "string" - }, - "encoder": { - "type": "string" - }, - "decoder": { - "type": "string" - }, - "keepEmpty": { - "type": "boolean" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "text": { - "type": "string" - } - }, - "required": [ - "text" - ], - "additionalProperties": false - } - ] - }, - "language": { - "type": "string", - "enum": [ - "json", - "yaml" - ] - } - }, - "additionalProperties": false, - "required": [ - "type" - ] - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "select" - }, - "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } - }, - "additionalProperties": false - }, - "customClass": { - "type": "string" - }, - "schema": { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - }, - "disabled": { - "type": [ - "boolean", - "string" - ] - }, - "required": { - "type": [ - "boolean", - "string" - ] - }, - "if": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - }, - "expression": { - "type": "string" - } - }, - "required": [ - "params", - "expression" - ], - "additionalProperties": false - } - ] - }, - "fetch": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "function": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - } - }, - "additionalProperties": false - } - ] - }, - "computed": { - "type": "string" - }, - "individualItemDisabilityCheck": { - "type": "string" - }, - "onChange": { - "type": "string" - }, - "encoder": { - "type": "string" - }, - "decoder": { - "type": "string" - }, - "keepEmpty": { - "type": "boolean" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "text": { - "type": "string" - } - }, - "required": [ - "text" - ], - "additionalProperties": false - } - ] - }, - "add_new_button": { - "type": "object", - "properties": { - "url": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "function": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - } - }, - "additionalProperties": false - }, - "target": { - "type": "string" - }, - "label": { - "type": "string" - } - }, - "required": [ - "url" - ], - "additionalProperties": false - }, - "allowUserDefinedOption": { - "type": "boolean" - }, - "options": { - "type": "array", - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/Option" - }, - { - "$ref": "#/definitions/Project" - } - ] - } - }, - "refresh": { - "type": "boolean" - }, - "sortable": { - "type": "boolean" - }, - "disableUnselect": { - "type": "boolean" - }, - "hasGroup": { - "type": [ - "boolean", - "string" - ] - } - }, - "additionalProperties": false, - "required": [ - "type" - ] - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "multiselect" - }, - "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } - }, - "additionalProperties": false - }, - "customClass": { - "type": "string" - }, - "schema": { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - }, - "disabled": { - "type": [ - "boolean", - "string" - ] - }, - "required": { - "type": [ - "boolean", - "string" - ] - }, - "if": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - }, - "expression": { - "type": "string" - } - }, - "required": [ - "params", - "expression" - ], - "additionalProperties": false - } - ] - }, - "fetch": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "function": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - } - }, - "additionalProperties": false - } - ] - }, - "computed": { - "type": "string" - }, - "individualItemDisabilityCheck": { - "type": "string" - }, - "onChange": { - "type": "string" - }, - "encoder": { - "type": "string" - }, - "decoder": { - "type": "string" - }, - "keepEmpty": { - "type": "boolean" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "text": { - "type": "string" - } - }, - "required": [ - "text" - ], - "additionalProperties": false - } - ] - }, - "add_new_button": { - "type": "object", - "properties": { - "url": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "function": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - } - }, - "additionalProperties": false - }, - "target": { - "type": "string" - }, - "label": { - "type": "string" - } - }, - "required": [ - "url" - ], - "additionalProperties": false - }, - "allowUserDefinedOption": { - "type": "boolean" - }, - "options": { - "type": "array", - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/Option" - }, - { - "$ref": "#/definitions/Project" - } - ] - } - }, - "refresh": { - "type": "boolean" - }, - "sortable": { - "type": "boolean" - }, - "disableUnselect": { - "type": "boolean" - }, - "hasGroup": { - "type": [ - "boolean", - "string" - ] - } - }, - "additionalProperties": false, - "required": [ - "type" - ] - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "checkbox" - }, - "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } - }, - "additionalProperties": false - }, - "customClass": { - "type": "string" - }, - "schema": { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - }, - "disabled": { - "type": [ - "boolean", - "string" - ] - }, - "required": { - "type": [ - "boolean", - "string" - ] - }, - "if": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - }, - "expression": { - "type": "string" - } - }, - "required": [ - "params", - "expression" - ], - "additionalProperties": false - } - ] - }, - "fetch": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "function": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - } - }, - "additionalProperties": false - } - ] - }, - "computed": { - "type": "string" - }, - "individualItemDisabilityCheck": { - "type": "string" - }, - "onChange": { - "type": "string" - }, - "encoder": { - "type": "string" - }, - "decoder": { - "type": "string" - }, - "keepEmpty": { - "type": "boolean" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "text": { - "type": "string" - } - }, - "required": [ - "text" - ], - "additionalProperties": false - } - ] - }, - "options": { - "type": "array", - "items": { - "$ref": "#/definitions/Option" - } - }, - "hasDescription": { - "type": "boolean" - }, - "isHorizontal": { - "type": "boolean" - } - }, - "additionalProperties": false, - "required": [ - "type" - ] - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "radio" - }, - "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } - }, - "additionalProperties": false - }, - "customClass": { - "type": "string" - }, - "schema": { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - }, - "disabled": { - "type": [ - "boolean", - "string" - ] - }, - "required": { - "type": [ - "boolean", - "string" - ] - }, - "if": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - }, - "expression": { - "type": "string" - } - }, - "required": [ - "params", - "expression" - ], - "additionalProperties": false - } - ] - }, - "fetch": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "function": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - } - }, - "additionalProperties": false - } - ] - }, - "computed": { - "type": "string" - }, - "individualItemDisabilityCheck": { - "type": "string" - }, - "onChange": { - "type": "string" - }, - "encoder": { - "type": "string" - }, - "decoder": { - "type": "string" - }, - "keepEmpty": { - "type": "boolean" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "text": { - "type": "string" - } - }, - "required": [ - "text" - ], - "additionalProperties": false - } - ] - }, - "options": { - "type": "array", - "items": { - "$ref": "#/definitions/Option" - } - }, - "hasDescription": { - "type": "boolean" - }, - "isHorizontal": { - "type": "boolean" - } - }, - "additionalProperties": false, - "required": [ - "type" - ] - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "switch" - }, - "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } - }, - "additionalProperties": false - }, - "customClass": { - "type": "string" - }, - "schema": { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - }, - "disabled": { - "type": [ - "boolean", - "string" - ] - }, - "required": { - "type": [ - "boolean", - "string" - ] - }, - "if": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - }, - "expression": { - "type": "string" - } - }, - "required": [ - "params", - "expression" - ], - "additionalProperties": false - } - ] - }, - "fetch": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "function": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - } - }, - "additionalProperties": false - } - ] - }, - "computed": { - "type": "string" - }, - "individualItemDisabilityCheck": { - "type": "string" - }, - "onChange": { - "type": "string" - }, - "encoder": { - "type": "string" - }, - "decoder": { - "type": "string" - }, - "keepEmpty": { - "type": "boolean" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "text": { - "type": "string" - } - }, - "required": [ - "text" - ], - "additionalProperties": false - } - ] - } - }, - "required": [ - "type" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "key-value-input-form" - }, - "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } - }, - "additionalProperties": false - }, - "customClass": { - "type": "string" - }, - "schema": { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - }, - "disabled": { - "type": [ - "boolean", - "string" - ] - }, - "required": { - "type": [ - "boolean", - "string" - ] - }, - "if": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - }, - "expression": { - "type": "string" - } - }, - "required": [ - "params", - "expression" - ], - "additionalProperties": false - } - ] - }, - "fetch": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "function": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - } - }, - "additionalProperties": false - } - ] - }, - "computed": { - "type": "string" - }, - "individualItemDisabilityCheck": { - "type": "string" - }, - "onChange": { - "type": "string" - }, - "encoder": { - "type": "string" - }, - "decoder": { - "type": "string" - }, - "keepEmpty": { - "type": "boolean" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "text": { - "type": "string" - } - }, - "required": [ - "text" - ], - "additionalProperties": false - } - ] - }, - "isArray": { - "type": "boolean" - }, - "newItemValidator": { - "type": "string" - }, - "keys": { - "type": "object", - "properties": { - "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "required": [ - "label" - ], - "additionalProperties": false - }, - "values": { - "$ref": "#/definitions/FormElementType" - } - }, - "required": [ - "keys", - "type", - "values" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "key-text-area-input-form" - }, - "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } - }, - "additionalProperties": false - }, - "customClass": { - "type": "string" - }, - "schema": { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - }, - "disabled": { - "type": [ - "boolean", - "string" - ] - }, - "required": { - "type": [ - "boolean", - "string" - ] - }, - "if": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - }, - "expression": { - "type": "string" - } - }, - "required": [ - "params", - "expression" - ], - "additionalProperties": false - } - ] - }, - "fetch": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "function": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - } - }, - "additionalProperties": false - } - ] - }, - "computed": { - "type": "string" - }, - "individualItemDisabilityCheck": { - "type": "string" - }, - "onChange": { - "type": "string" - }, - "encoder": { - "type": "string" - }, - "decoder": { - "type": "string" - }, - "keepEmpty": { - "type": "boolean" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "text": { - "type": "string" - } - }, - "required": [ - "text" - ], - "additionalProperties": false - } - ] - }, - "isArray": { - "type": "boolean" - }, - "newItemValidator": { - "type": "string" - }, - "keys": { - "type": "object", - "properties": { - "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "required": [ - "label" - ], - "additionalProperties": false - }, - "values": { - "$ref": "#/definitions/FormElementType" - } - }, - "required": [ - "keys", - "type", - "values" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "list-input-form" - }, - "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } - }, - "additionalProperties": false - }, - "customClass": { - "type": "string" - }, - "schema": { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - }, - "disabled": { - "type": [ - "boolean", - "string" - ] - }, - "required": { - "type": [ - "boolean", - "string" - ] - }, - "if": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - }, - "expression": { - "type": "string" - } - }, - "required": [ - "params", - "expression" - ], - "additionalProperties": false - } - ] - }, - "fetch": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "function": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - } - }, - "additionalProperties": false - } - ] - }, - "computed": { - "type": "string" - }, - "individualItemDisabilityCheck": { - "type": "string" - }, - "onChange": { - "type": "string" - }, - "encoder": { - "type": "string" - }, - "decoder": { - "type": "string" - }, - "keepEmpty": { - "type": "boolean" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "text": { - "type": "string" - } - }, - "required": [ - "text" - ], - "additionalProperties": false - } - ] - }, - "element": { - "$ref": "#/definitions/FormElementType" - }, - "validationRuleObject": { - "type": "object", - "additionalProperties": {} - } - }, - "required": [ - "element", - "type" - ], - "additionalProperties": false - }, - { - "$ref": "#/definitions/SingleStepFormArrayInterface" - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "reusable-element" - }, - "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } - }, - "additionalProperties": false - }, - "customClass": { - "type": "string" - }, - "schema": { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - }, - "disabled": { - "type": [ - "boolean", - "string" - ] - }, - "required": { - "type": [ - "boolean", - "string" - ] - }, - "if": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - }, - "expression": { - "type": "string" - } - }, - "required": [ - "params", - "expression" - ], - "additionalProperties": false - } - ] - }, - "fetch": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "function": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - } - }, - "additionalProperties": false - } - ] - }, - "computed": { - "type": "string" - }, - "individualItemDisabilityCheck": { - "type": "string" - }, - "onChange": { - "type": "string" - }, - "encoder": { - "type": "string" - }, - "decoder": { - "type": "string" - }, - "keepEmpty": { - "type": "boolean" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "text": { - "type": "string" - } - }, - "required": [ - "text" - ], - "additionalProperties": false - } - ] - }, - "identifier": { - "type": "string" - }, - "show_label": { - "type": "boolean" - }, - "hideForm": { - "type": "boolean" - }, - "accordion": { - "type": "boolean" - }, - "elements": { - "type": "array", - "items": { - "$ref": "#/definitions/FormElementType" - } - }, - "discriminator": { - "type": "object", - "additionalProperties": {} - }, - "style": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "toggleOption": { - "$ref": "#/definitions/ToggleOption" - }, - "alias": { - "type": "string" - }, - "chart": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "version": { - "type": "string" - } - }, - "required": [ - "name", - "version" - ], - "additionalProperties": false - }, - "moduleResolver": { - "type": "string" - }, - "dataContext": { - "type": "object", - "additionalProperties": { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - }, - "functionCallbacks": { - "type": "object", - "additionalProperties": { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - } - }, - "required": [ - "alias", - "chart", - "moduleResolver", - "type" - ], - "additionalProperties": false - }, - { - "$ref": "#/definitions/SingleStepFormInterface" - }, - { - "$ref": "#/definitions/ConfigureOptionsInterface" - }, + "box": { + "type": "boolean" + }, + "customClass": { + "type": "string" + }, + "data": { + "anyOf": [ { - "$ref": "#/definitions/ArrayInputFormElementInterface" + "type": "string" }, { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "resource-input-form" - }, - "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } - }, - "additionalProperties": false - }, - "customClass": { - "type": "string" - }, - "schema": { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - }, - "disabled": { - "type": [ - "boolean", - "string" - ] - }, - "required": { - "type": [ - "boolean", - "string" - ] - }, - "if": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - }, - "expression": { - "type": "string" - } - }, - "required": [ - "params", - "expression" - ], - "additionalProperties": false - } - ] - }, - "fetch": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "function": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - } - }, - "additionalProperties": false - } - ] - }, - "computed": { - "type": "string" - }, - "individualItemDisabilityCheck": { - "type": "string" - }, - "onChange": { - "type": "string" - }, - "encoder": { - "type": "string" - }, - "decoder": { - "type": "string" - }, - "keepEmpty": { - "type": "boolean" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "text": { - "type": "string" - } - }, - "required": [ - "text" - ], - "additionalProperties": false - } - ] - } - }, - "required": [ - "type" - ], - "additionalProperties": false - } - ] - }, - "TimeInputInterface": { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "time-input" - }, - "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } - }, - "additionalProperties": false - }, - "customClass": { - "type": "string" - }, - "schema": { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - }, - "disabled": { - "type": [ - "boolean", - "string" - ] - }, - "required": { - "type": [ - "boolean", - "string" - ] - }, - "if": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - }, - "expression": { - "type": "string" - } - }, - "required": [ - "params", - "expression" - ], - "additionalProperties": false - } - ] - }, - "fetch": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "function": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - } - }, - "additionalProperties": false - } - ] - }, - "computed": { - "type": "string" - }, - "individualItemDisabilityCheck": { - "type": "string" - }, - "onChange": { - "type": "string" - }, - "encoder": { - "type": "string" - }, - "decoder": { - "type": "string" - }, - "keepEmpty": { - "type": "boolean" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "text": { - "type": "string" - } - }, - "required": [ - "text" - ], - "additionalProperties": false - } - ] + "items": { + "$ref": "#/definitions/MultiFileEditorViewDataType" + }, + "type": "array" } + ] }, - "required": [ - "type" - ], - "additionalProperties": false - }, - "Option": { - "type": "object", - "properties": { - "text": { - "type": "string" - }, - "value": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "boolean" - }, - { - "type": "object", - "additionalProperties": {} - }, - { - "type": "array", - "items": {} - } - ] - }, - "description": { - "type": "string" - } + "description": { + "type": "string" }, - "required": [ - "text", - "value" - ], - "additionalProperties": false - }, - "Project": { - "type": "object", - "properties": { - "project": { - "type": "string" - }, - "namespaces": { - "type": "array", - "items": { - "$ref": "#/definitions/Namespace" - } - } + "disable": { + "type": ["boolean", "string"] }, - "required": [ - "project", - "namespaces" - ], - "additionalProperties": false - }, - "Namespace": { - "type": "object", - "properties": { - "text": { - "type": "string" - }, - "value": { - "type": "string" - } + "disableUnselect": { + "type": "boolean" }, - "required": [ - "text", - "value" - ], - "additionalProperties": false - }, - "SingleStepFormArrayInterface": { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "single-step-form-array" - }, - "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } - }, - "additionalProperties": false - }, - "customClass": { - "type": "string" - }, - "schema": { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - }, - "disabled": { - "type": [ - "boolean", - "string" - ] - }, - "required": { - "type": [ - "boolean", - "string" - ] - }, - "if": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - }, - "expression": { - "type": "string" - } - }, - "required": [ - "params", - "expression" - ], - "additionalProperties": false - } - ] - }, - "fetch": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "function": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - } - }, - "additionalProperties": false - } - ] - }, - "computed": { - "type": "string" - }, - "individualItemDisabilityCheck": { - "type": "string" - }, - "onChange": { - "type": "string" - }, - "encoder": { - "type": "string" - }, - "decoder": { - "type": "string" - }, - "keepEmpty": { - "type": "boolean" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "text": { - "type": "string" - } - }, - "required": [ - "text" - ], - "additionalProperties": false - } - ] - }, - "addFormLabel": { - "type": "string" - }, - "hideForm": { - "type": "boolean" - }, - "isCreateDisabled": { - "type": "boolean" - }, - "element": { - "$ref": "#/definitions/SingleStepFormInterface" - }, - "newItemValidator": { - "type": "string" - }, - "tableContents": { - "type": "array", - "items": { - "$ref": "#/definitions/TableContent" - } - }, - "temporaryPath": { - "type": "string" - }, - "resetOnChange": { - "type": "boolean" - }, - "resetDependencyPath": { - "type": "string" - }, - "hideDetailsButton": { - "type": "boolean" - }, - "validationRuleObject": { - "type": "object", - "additionalProperties": {} - } + "editorHeight": { + "type": "string" + }, + "forceRequired": { + "type": "boolean" + }, + "fullwidth": { + "type": "boolean" + }, + "hasGroup": { + "type": ["boolean", "string"] + }, + "hasIcon": { + "type": "boolean" + }, + "header": { + "type": "string" + }, + "height": { + "type": "string" + }, + "hideCopyButton": { + "type": "boolean" + }, + "hideFormatButton": { + "type": "boolean" + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "isHorizontal": { + "type": "boolean" + }, + "isSecret": { + "type": "boolean" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "maxValue": { + "type": "number" + }, + "minValue": { + "type": "number" + }, + "multiple": { + "type": "boolean" }, - "required": [ - "element", - "tableContents", - "type" - ], - "additionalProperties": false - }, - "TableContent": { + "options": { + "$ref": "#/definitions/Options" + }, + "readonly": { + "type": "boolean" + }, + "refresh": { + "type": "boolean" + }, + "showCodeGroup": { + "type": "boolean" + }, + "sortable": { + "type": "boolean" + }, + "subtitle": { + "type": "string" + }, + "type": { + "enum": [ + "label-element", + "alert", + "info", + "warning", + "error", + "success", + "neutral", + "input", + "date", + "date-time", + "select", + "textarea", + "radio", + "checkbox", + "switch", + "anchor", + "editor", + "multi-file-editor", + "time-picker", + "threshold-input", + "input-compare" + ], + "type": "string" + }, + "validation": { + "$ref": "#/definitions/Validation" + }, + "watcher": { + "$ref": "#/definitions/Watchers" + }, + "width": { + "type": "string" + } + }, + "required": ["type"], + "type": "object" + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "schema": { + "type": "string" + }, + "subtitle": { + "type": "string" + }, + "type": { + "const": "array-item-form", + "type": "string" + }, + "validation": { + "$ref": "#/definitions/Validation" + }, + "watcher": { + "$ref": "#/definitions/Watchers" + } + }, + "required": ["element", "label", "schema", "type"], + "type": "object" + }, + "ArrayObject": { + "additionalProperties": false, + "properties": { + "buttonClass": { + "type": "string" + }, + "customClass": { + "type": "string" + }, + "description": { + "type": "string" + }, + "disable": { + "type": ["boolean", "string"] + }, + "elements": { + "items": { "anyOf": [ - { - "$ref": "#/definitions/TableContentValueInterface" - }, - { - "type": "object", - "properties": { - "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } - }, - "additionalProperties": false - }, - "type": { - "type": "string", - "const": "label" - } - }, - "required": [ - "label", - "type" - ], - "additionalProperties": false - } + { + "$ref": "#/definitions/BaseElement" + }, + { + "$ref": "#/definitions/ArrayObject" + }, + { + "$ref": "#/definitions/ArrayItem" + } ] + }, + "type": "array" }, - "TableContentValueInterface": { - "type": "object", - "properties": { - "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } - }, - "additionalProperties": false - }, - "type": { - "type": "string", - "const": "value" - }, - "computed": { - "type": "string" - }, - "inTableColumn": { - "type": "boolean" - }, - "path": { - "type": "string" - }, - "typeOfValue": { - "type": "string", - "enum": [ - "string", - "array", - "object-array", - "key-operator-values-array", - "key-value", - "code", - "datetime" - ] - }, - "tableContents": { - "type": "array", - "items": { - "$ref": "#/definitions/TableContent" - } - } + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "schema": { + "type": "string" + }, + "subtitle": { + "type": "string" + }, + "type": { + "const": "array-object-form", + "type": "string" + }, + "validation": { + "$ref": "#/definitions/Validation" + }, + "watcher": { + "$ref": "#/definitions/Watchers" + } + }, + "required": ["elements", "label", "schema", "type"], + "type": "object" + }, + "ArrayOfArrayObject": { + "additionalProperties": false, + "properties": { + "butttonClass": { + "type": "string" + }, + "customClass": { + "type": "string" + }, + "description": { + "type": "string" + }, + "disable": { + "type": ["boolean", "string"] + }, + "elements": { + "items": { + "anyOf": [ + { + "$ref": "#/definitions/BaseElement" + }, + { + "$ref": "#/definitions/ArrayObject" + } + ] + }, + "type": "array" + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "schema": { + "type": "string" + }, + "subtitle": { + "type": "string" + }, + "type": { + "const": "array-of-array-object", + "type": "string" + }, + "validation": { + "$ref": "#/definitions/Validation" + }, + "watcher": { + "$ref": "#/definitions/Watchers" + } + }, + "required": ["elements", "label", "schema", "type"], + "type": "object" + }, + "BaseElement": { + "anyOf": [ + { + "$ref": "#/definitions/Label" + }, + { + "$ref": "#/definitions/Input" + }, + { + "$ref": "#/definitions/Select" + }, + { + "$ref": "#/definitions/TheSelect" + }, + { + "$ref": "#/definitions/TextArea" + }, + { + "$ref": "#/definitions/Radio" + }, + { + "$ref": "#/definitions/CheckBox" + }, + { + "$ref": "#/definitions/Switch" + }, + { + "$ref": "#/definitions/Anchor" + }, + { + "$ref": "#/definitions/EditorView" + }, + { + "$ref": "#/definitions/MultiFileEditorView" + }, + { + "$ref": "#/definitions/TimePicker" + }, + { + "$ref": "#/definitions/ThresholdInput" + }, + { + "$ref": "#/definitions/InputCompare" + } + ] + }, + "BlockLayout": { + "additionalProperties": false, + "properties": { + "customClass": { + "type": "string" + }, + "description": { + "type": "string" + }, + "elements": { + "items": { + "$ref": "#/definitions/AllElement" + }, + "type": "array" + }, + "fixedBlock": { + "type": "boolean" + }, + "hasButton": { + "additionalProperties": false, + "properties": { + "action": { + "type": "string" }, - "required": [ - "label", - "path", - "type", - "typeOfValue" - ], - "additionalProperties": false - }, - "ToggleOption": { - "type": "object", - "properties": { - "disabled": { - "type": [ - "boolean", - "string" - ] - }, - "id": { - "type": "string" - }, - "onStatusFalse": { - "type": "string" - }, - "onStatusTrue": { - "type": "string" - }, - "setInitialStatusFalse": { - "type": [ - "boolean", - "string" - ] - }, - "show": { - "type": "boolean" - }, - "ignoreInitialStatusFunction": { - "type": "boolean" - }, - "schema": { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } + "buttonClass": { + "type": "string" + }, + "hasCancel": { + "type": ["boolean", "string"] }, - "required": [ - "id" - ], - "additionalProperties": false + "text": { + "type": "string" + } + }, + "required": ["text", "action"], + "type": "object" }, - "ConfigureOptionsInterface": { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "configure-options" - }, - "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } - }, - "additionalProperties": false - }, - "customClass": { - "type": "string" - }, - "schema": { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - }, - "disabled": { - "type": [ - "boolean", - "string" - ] - }, - "required": { - "type": [ - "boolean", - "string" - ] - }, - "if": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - }, - "expression": { - "type": "string" - } - }, - "required": [ - "params", - "expression" - ], - "additionalProperties": false - } - ] - }, - "fetch": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "function": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - } - }, - "additionalProperties": false - } - ] - }, - "computed": { - "type": "string" - }, - "individualItemDisabilityCheck": { - "type": "string" - }, - "onChange": { - "type": "string" - }, - "encoder": { - "type": "string" - }, - "decoder": { - "type": "string" - }, - "keepEmpty": { - "type": "boolean" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "text": { - "type": "string" - } - }, - "required": [ - "text" - ], - "additionalProperties": false - } - ] - }, - "options": { - "type": "array", - "items": { - "$ref": "#/definitions/ConfigureOption" - } - }, - "hasDescription": { - "type": "boolean" - }, - "isHorizontal": { - "type": "boolean" - }, - "hasDependencies": { - "type": "boolean" - }, - "owner": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - }, - "cluster": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } + "hideBlock": { + "type": "boolean" + }, + "hideBorder": { + "type": "boolean" + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "showLabels": { + "type": "boolean" + }, + "type": { + "const": "block-layout", + "type": "string" + } + }, + "required": ["elements", "type"], + "type": "object" + }, + "CheckBox": { + "additionalProperties": false, + "properties": { + "customClass": { + "type": "string" + }, + "description": { + "type": "string" + }, + "disable": { + "type": ["boolean", "string"] + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "options": { + "$ref": "#/definitions/Options" + }, + "schema": { + "type": "string" + }, + "subtitle": { + "type": "string" + }, + "type": { + "const": "checkbox", + "type": "string" + }, + "validation": { + "$ref": "#/definitions/Validation" + }, + "watcher": { + "$ref": "#/definitions/Watchers" + } + }, + "required": ["label", "schema", "type"], + "type": "object" + }, + "DerivedElement": { + "anyOf": [ + { + "$ref": "#/definitions/ArrayObject" + }, + { + "$ref": "#/definitions/ArrayItem" + }, + { + "$ref": "#/definitions/ArrayOfArrayObject" + }, + { + "$ref": "#/definitions/ObjectItem" + }, + { + "$ref": "#/definitions/ScalingRules" + }, + { + "$ref": "#/definitions/MachineElement" + }, + { + "$ref": "#/definitions/SelectElement" + } + ] + }, + "EditorView": { + "additionalProperties": false, + "properties": { + "customClass": { + "type": "string" + }, + "data": { + "type": "string" + }, + "description": { + "type": "string" + }, + "disable": { + "type": ["boolean", "string"] + }, + "editorHeight": { + "type": "string" + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "readonly": { + "type": "boolean" + }, + "schema": { + "type": "string" + }, + "showCodeGroup": { + "type": "boolean" + }, + "subtitle": { + "type": "string" + }, + "type": { + "const": "editor", + "type": "string" + }, + "validation": { + "$ref": "#/definitions/Validation" + }, + "watcher": { + "$ref": "#/definitions/Watchers" + } + }, + "required": ["label", "schema", "type"], + "type": "object" + }, + "FormType": { + "anyOf": [ + { + "$ref": "#/definitions/SingleStepForm" + }, + { + "$ref": "#/definitions/MultiStepForm" + } + ] + }, + "HorizontalLayout": { + "additionalProperties": false, + "properties": { + "customClass": { + "type": "string" + }, + "description": { + "type": "string" + }, + "elements": { + "items": { + "$ref": "#/definitions/AllElement" + }, + "type": "array" + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "showLabels": { + "type": "boolean" + }, + "type": { + "const": "horizontal-layout", + "type": "string" + } + }, + "required": ["elements", "type"], + "type": "object" + }, + "IfType": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "type": { + "enum": ["function", "computed"], + "type": "string" + } + }, + "required": ["type", "name"], + "type": "object" + }, + "Init": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "type": { + "const": "func", + "type": "string" }, - "required": [ - "cluster", - "options", - "owner", - "type" - ], - "additionalProperties": false - }, - "ConfigureOption": { - "type": "object", - "properties": { - "text": { - "type": "string" - }, - "value": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "boolean" - }, - { - "type": "object", - "additionalProperties": {} - }, - { - "type": "array", - "items": {} - } - ] - }, - "description": { - "type": "string" - }, - "dependencies": { - "type": "array", - "items": { - "type": "object", - "properties": { - "group": { - "type": "string" - }, - "version": { - "type": "string" - }, - "name": { - "type": "string" - }, - "resource": { - "type": "string" - }, - "url": { - "type": "string" - } - }, - "required": [ - "group", - "version", - "name", - "resource", - "url" - ], - "additionalProperties": false - } - }, - "dependingSteps": { - "type": "array", - "items": { - "type": "string" - } - } + "value": { + "type": "string" + } + }, + "required": ["type", "value"], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "type": { + "const": "static", + "type": "string" }, + "value": {} + }, + "required": ["type", "value"], + "type": "object" + } + ] + }, + "Input": { + "additionalProperties": false, + "properties": { + "customClass": { + "type": "string" + }, + "description": { + "type": "string" + }, + "disable": { + "type": ["boolean", "string"] + }, + "forceRequired": { + "type": "boolean" + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "isSecret": { + "type": "boolean" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "schema": { + "type": "string" + }, + "subtitle": { + "type": "string" + }, + "type": { + "enum": ["input", "date", "date-time"], + "type": "string" + }, + "validation": { + "$ref": "#/definitions/Validation" + }, + "watcher": { + "$ref": "#/definitions/Watchers" + } + }, + "required": ["label", "schema", "type"], + "type": "object" + }, + "InputCompare": { + "additionalProperties": false, + "properties": { + "customClass": { + "type": "string" + }, + "description": { + "type": "string" + }, + "disable": { + "type": ["boolean", "string"] + }, + "header": { + "type": "string" + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "schema": { + "type": "string" + }, + "subtitle": { + "type": "string" + }, + "type": { + "const": "input-compare", + "type": "string" + }, + "validation": { + "$ref": "#/definitions/Validation" + }, + "watcher": { + "$ref": "#/definitions/Watchers" + } + }, + "required": ["label", "schema", "type"], + "type": "object" + }, + "Label": { + "additionalProperties": false, + "properties": { + "box": { + "type": "boolean" + }, + "customClass": { + "type": "string" + }, + "description": { + "type": "string" + }, + "disable": { + "type": ["boolean", "string"] + }, + "hasIcon": { + "type": "boolean" + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "schema": { + "type": "string" + }, + "subtitle": { + "type": "string" + }, + "type": { + "enum": ["label-element", "alert", "info", "warning", "error", "success", "neutral"], + "type": "string" + }, + "validation": { + "$ref": "#/definitions/Validation" + }, + "watcher": { + "$ref": "#/definitions/Watchers" + } + }, + "required": ["label", "type"], + "type": "object" + }, + "LayoutElement": { + "anyOf": [ + { + "$ref": "#/definitions/BlockLayout" + }, + { + "$ref": "#/definitions/HorizontalLayout" + }, + { + "$ref": "#/definitions/TabLayout" + } + ] + }, + "LoaderType": { + "anyOf": [ + { + "type": "string" + }, + { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "watchPaths": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": ["name"], + "type": "object" + } + ] + }, + "MachineElement": { + "additionalProperties": false, + "properties": { + "customClass": { + "type": "string" + }, + "description": { + "type": "string" + }, + "disable": { + "type": ["boolean", "string"] + }, + "header": { + "type": "string" + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "schema": { + "type": "string" + }, + "subtitle": { + "type": "string" + }, + "type": { + "const": "machine-compare", + "type": "string" + }, + "validation": { + "$ref": "#/definitions/Validation" + }, + "watcher": { + "$ref": "#/definitions/Watchers" + } + }, + "required": ["label", "schema", "type"], + "type": "object" + }, + "MultiFileEditorView": { + "additionalProperties": false, + "properties": { + "customClass": { + "type": "string" + }, + "data": { + "items": { + "$ref": "#/definitions/MultiFileEditorViewDataType" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "disable": { + "type": ["boolean", "string"] + }, + "editorHeight": { + "type": "string" + }, + "hideCopyButton": { + "type": "boolean" + }, + "hideFormatButton": { + "type": "boolean" + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "readonly": { + "type": "boolean" + }, + "schema": { + "type": "string" + }, + "subtitle": { + "type": "string" + }, + "type": { + "const": "multi-file-editor", + "type": "string" + }, + "validation": { + "$ref": "#/definitions/Validation" + }, + "watcher": { + "$ref": "#/definitions/Watchers" + } + }, + "required": ["schema", "type"], + "type": "object" + }, + "MultiFileEditorViewDataType": { + "additionalProperties": false, + "properties": { + "content": { + "type": "string" + }, + "format": { + "type": "string" + }, + "initContent": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": ["name", "content"], + "type": "object" + }, + "MultiStepForm": { + "additionalProperties": false, + "properties": { + "label": { + "type": "string" + }, + "loader": { + "type": "string" + }, + "step": { + "items": { + "$ref": "#/definitions/SingleStepForm" + }, + "type": "array" + }, + "type": { + "const": "multi-step-form", + "type": "string" + } + }, + "required": ["type", "step"], + "type": "object" + }, + "ObjectItem": { + "additionalProperties": false, + "properties": { + "buttonClass": { + "type": "string" + }, + "customClass": { + "type": "string" + }, + "description": { + "type": "string" + }, + "disable": { + "type": ["boolean", "string"] + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "schema": { + "type": "string" + }, + "subtitle": { + "type": "string" + }, + "type": { + "const": "object-item", + "type": "string" + }, + "validation": { + "$ref": "#/definitions/Validation" + }, + "watcher": { + "$ref": "#/definitions/Watchers" + } + }, + "required": ["label", "schema", "type"], + "type": "object" + }, + "Options": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "items": { "additionalProperties": false, - "required": [ - "text", - "value" - ] + "properties": { + "description": { + "type": "string" + }, + "label": { + "type": "string" + }, + "text": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": ["text", "value"], + "type": "object" + }, + "type": "array" }, - "ArrayInputFormElementInterface": { - "type": "object", + { + "items": { + "additionalProperties": false, "properties": { - "type": { - "type": "string", - "const": "array-input-form" - }, - "label": { - "type": "object", - "properties": { - "isSubsection": { - "type": "boolean" - }, - "text": { - "type": "string" - } + "namespaces": { + "items": { + "additionalProperties": false, + "properties": { + "text": { + "type": "string" }, - "additionalProperties": false - }, - "customClass": { - "type": "string" - }, - "schema": { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - }, - "disabled": { - "type": [ - "boolean", - "string" - ] - }, - "required": { - "type": [ - "boolean", - "string" - ] - }, - "if": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - }, - "expression": { - "type": "string" - } - }, - "required": [ - "params", - "expression" - ], - "additionalProperties": false - } - ] - }, - "fetch": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "function": { - "type": "string" - }, - "params": { - "type": "object", - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "number" - }, - { - "type": "object", - "properties": { - "$ref": { - "type": "string" - } - }, - "required": [ - "$ref" - ], - "additionalProperties": false - } - ] - } - } - }, - "additionalProperties": false - } - ] - }, - "computed": { - "type": "string" - }, - "individualItemDisabilityCheck": { - "type": "string" - }, - "onChange": { - "type": "string" - }, - "encoder": { - "type": "string" - }, - "decoder": { - "type": "string" - }, - "keepEmpty": { - "type": "boolean" - }, - "description": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "text": { - "type": "string" - } - }, - "required": [ - "text" - ], - "additionalProperties": false - } - ] - }, - "identifier": { - "type": "string" - }, - "element": { - "$ref": "#/definitions/FormElementType" - }, - "show_label": { - "type": "boolean" - }, - "hideForm": { - "type": "boolean" - }, - "style": { - "type": "object", - "additionalProperties": { - "type": "string" + "value": { + "type": "string" } + }, + "required": ["text", "value"], + "type": "object" + }, + "type": "array" + }, + "project": { + "type": "string" + } + }, + "required": ["project", "namespaces"], + "type": "object" + }, + "type": "array" + } + ] + }, + "Radio": { + "additionalProperties": false, + "properties": { + "customClass": { + "type": "string" + }, + "description": { + "type": "string" + }, + "disable": { + "type": ["boolean", "string"] + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "isHorizontal": { + "type": "boolean" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "options": { + "$ref": "#/definitions/Options" + }, + "schema": { + "type": "string" + }, + "subtitle": { + "type": "string" + }, + "type": { + "const": "radio", + "type": "string" + }, + "validation": { + "$ref": "#/definitions/Validation" + }, + "watcher": { + "$ref": "#/definitions/Watchers" + } + }, + "required": ["label", "schema", "type"], + "type": "object" + }, + "ScalingRules": { + "additionalProperties": false, + "properties": { + "customClass": { + "type": "string" + }, + "description": { + "type": "string" + }, + "disable": { + "type": ["boolean", "string"] + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "schema": { + "type": "string" + }, + "subtitle": { + "type": "string" + }, + "type": { + "const": "scaling-rules", + "type": "string" + }, + "validation": { + "$ref": "#/definitions/Validation" + }, + "watcher": { + "$ref": "#/definitions/Watchers" + } + }, + "required": ["label", "schema", "type"], + "type": "object" + }, + "Select": { + "additionalProperties": false, + "properties": { + "customClass": { + "type": "string" + }, + "description": { + "type": "string" + }, + "disable": { + "type": ["boolean", "string"] + }, + "disableUnselect": { + "type": "boolean" + }, + "hasGroup": { + "type": ["boolean", "string"] + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "options": { + "$ref": "#/definitions/Options" + }, + "refresh": { + "type": "boolean" + }, + "schema": { + "type": "string" + }, + "subtitle": { + "type": "string" + }, + "type": { + "const": "select", + "type": "string" + }, + "validation": { + "$ref": "#/definitions/Validation" + }, + "watcher": { + "$ref": "#/definitions/Watchers" + } + }, + "required": ["label", "schema", "type"], + "type": "object" + }, + "SelectElement": { + "additionalProperties": false, + "properties": { + "customClass": { + "type": "string" + }, + "description": { + "type": "string" + }, + "disable": { + "type": ["boolean", "string"] + }, + "header": { + "type": "string" + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "schema": { + "type": "string" + }, + "subtitle": { + "type": "string" + }, + "type": { + "const": "select-compare", + "type": "string" + }, + "validation": { + "$ref": "#/definitions/Validation" + }, + "watcher": { + "$ref": "#/definitions/Watchers" + } + }, + "required": ["label", "schema", "type"], + "type": "object" + }, + "SingleStepForm": { + "additionalProperties": false, + "properties": { + "elements": { + "items": { + "$ref": "#/definitions/AllElement" + }, + "type": "array" + }, + "id": { + "type": "string" + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "schema": { + "type": "string" + }, + "subtitle": { + "type": "string" + }, + "type": { + "const": "single-step-form", + "type": "string" + } + }, + "required": ["type", "elements"], + "type": "object" + }, + "Switch": { + "additionalProperties": false, + "properties": { + "customClass": { + "type": "string" + }, + "description": { + "type": "string" + }, + "disable": { + "type": ["boolean", "string"] + }, + "fullwidth": { + "type": "boolean" + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "schema": { + "type": "string" + }, + "subtitle": { + "type": "string" + }, + "type": { + "const": "switch", + "type": "string" + }, + "validation": { + "$ref": "#/definitions/Validation" + }, + "watcher": { + "$ref": "#/definitions/Watchers" + } + }, + "required": ["label", "schema", "type"], + "type": "object" + }, + "TabLayout": { + "additionalProperties": false, + "properties": { + "customClass": { + "type": "string" + }, + "description": { + "type": "string" + }, + "elements": { + "items": { + "$ref": "#/definitions/AllElement" + }, + "type": "array" + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "options": { + "$ref": "#/definitions/Options" + }, + "schema": { + "type": "string" + }, + "showLabels": { + "type": "boolean" + }, + "type": { + "const": "tab-layout", + "type": "string" + }, + "watcher": { + "$ref": "#/definitions/Watchers" + } + }, + "required": ["elements", "schema", "type"], + "type": "object" + }, + "TextArea": { + "additionalProperties": false, + "properties": { + "customClass": { + "type": "string" + }, + "description": { + "type": "string" + }, + "disable": { + "type": ["boolean", "string"] + }, + "height": { + "type": "string" + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "schema": { + "type": "string" + }, + "subtitle": { + "type": "string" + }, + "type": { + "const": "textarea", + "type": "string" + }, + "validation": { + "$ref": "#/definitions/Validation" + }, + "watcher": { + "$ref": "#/definitions/Watchers" + } + }, + "required": ["label", "schema", "type"], + "type": "object" + }, + "TheSelect": { + "additionalProperties": false, + "properties": { + "addNewButton": { + "additionalProperties": false, + "properties": { + "label": { + "type": "string" + }, + "target": { + "type": "string" + }, + "url": { + "anyOf": [ + { + "type": "string" }, - "individualItemVisibilityCheck": { - "type": "string" + { + "additionalProperties": false, + "properties": { + "function": { + "type": "string" + } + }, + "required": ["function"], + "type": "object" } + ] + } + }, + "required": ["label", "url"], + "type": "object" + }, + "customClass": { + "type": "string" + }, + "description": { + "type": "string" + }, + "disable": { + "type": ["boolean", "string"] + }, + "disableUnselect": { + "type": "boolean" + }, + "hasGroup": { + "type": ["boolean", "string"] + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "multiple": { + "type": "boolean" + }, + "options": { + "$ref": "#/definitions/Options" + }, + "refresh": { + "type": "boolean" + }, + "schema": { + "type": "string" + }, + "sortable": { + "type": "boolean" + }, + "subtitle": { + "type": "string" + }, + "type": { + "const": "select", + "type": "string" + }, + "validation": { + "$ref": "#/definitions/Validation" + }, + "watcher": { + "$ref": "#/definitions/Watchers" + } + }, + "required": ["label", "schema", "type"], + "type": "object" + }, + "ThresholdInput": { + "additionalProperties": false, + "properties": { + "customClass": { + "type": "string" + }, + "description": { + "type": "string" + }, + "disable": { + "type": ["boolean", "string"] + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "maxValue": { + "type": "number" + }, + "minValue": { + "type": "number" + }, + "schema": { + "type": "string" + }, + "subtitle": { + "type": "string" + }, + "type": { + "const": "threshold-input", + "type": "string" + }, + "validation": { + "$ref": "#/definitions/Validation" + }, + "watcher": { + "$ref": "#/definitions/Watchers" + }, + "width": { + "type": "string" + } + }, + "required": ["label", "schema", "type"], + "type": "object" + }, + "TimePicker": { + "additionalProperties": false, + "properties": { + "customClass": { + "type": "string" + }, + "description": { + "type": "string" + }, + "disable": { + "type": ["boolean", "string"] + }, + "if": { + "$ref": "#/definitions/IfType" + }, + "init": { + "$ref": "#/definitions/Init" + }, + "label": { + "type": "string" + }, + "loader": { + "$ref": "#/definitions/LoaderType" + }, + "schema": { + "type": "string" + }, + "subtitle": { + "type": "string" + }, + "type": { + "const": "time-picker", + "type": "string" + }, + "validation": { + "$ref": "#/definitions/Validation" + }, + "watcher": { + "$ref": "#/definitions/Watchers" + } + }, + "required": ["label", "schema", "type"], + "type": "object" + }, + "Validation": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "type": { + "const": "required", + "type": "string" + } + }, + "required": ["type"], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" }, - "required": [ - "element", - "type" - ], - "additionalProperties": false + "type": { + "const": "custom", + "type": "string" + } + }, + "required": ["type", "name"], + "type": "object" + } + ] + }, + "Watchers": { + "additionalProperties": false, + "properties": { + "func": { + "type": "string" + }, + "paths": { + "items": { + "type": "string" + }, + "type": "array" } + }, + "required": ["paths", "func"], + "type": "object" } -} \ No newline at end of file + } +}